как работает индексирование этого массива? - PullRequest
1 голос
/ 01 ноября 2009

Я пытаюсь понять, как это работает (я знаю, что это делает, я просто не понимаю, как). Насколько я знаю, это читает символ, пока не будет достигнут EOF, и если это цифра, поместите его в массив:

while ((c = getchar()) != EOF)
  if (c >= '0' && c <= '9')
    ++ndigit[c-'0'];

Я понимаю, что могу индексировать массив следующим образом:

some_array[1] = 12;

, который поместит 12 во второй элемент.

Что делает c-'0'?

(я получил это из книги «Язык программирования C, второе издание от K & R»)

Ответы [ 4 ]

5 голосов
/ 01 ноября 2009

'0' - это char, который имеет десятичное значение 48, когда приводится к целому числу. Это работает, потому что char - встроенный порядковый тип.

Если вы посмотрите на разборку, вы увидите это в действии:

      if (c >= '0' && c <= '9')
004135E3  movsx       eax,byte ptr [ebp-9] 
004135E7  cmp         eax,30h 
004135EA  jl          wmain+6Eh (41360Eh) 
004135EC  movsx       eax,byte ptr [ebp-9] 
004135F0  cmp         eax,39h 
004135F3  jg          wmain+6Eh (41360Eh) 

Обратите внимание, что мы сравниваем с 30 гексами и 39 гексами, а не с '0' и '9'.

3 голосов
/ 01 ноября 2009

На самом деле то, что он делает, считает, сколько раз вы считаете каждую цифру. Итак, у вас есть массив вроде:

int ndigit[10] = { 0 }; // Start with all zeros

Если задана цифра ASCII от '0' до '9', c-'0' преобразует ее из цифры ASCII в простое число от 0 до 9. То есть символ '0', равный 48 в ASCII, вычитается из каждый символ, поэтому они идут от 48 до 57 до 0 до 9.

Затем это число от 0 до 9 используется как индекс в массиве, и этот индекс увеличивается на единицу. Таким образом, ndigit подсчитывает, сколько раз набирается каждая цифра.

1 голос
/ 01 ноября 2009

Согласно таблице ASCII , символ 0 является представлением ASCII значения 48. Поскольку символы от 0 до 9 являются представлениями чисел от 48 до 57, вы можете преобразовать каждый символ до действительной цифры путем вычитания 48.

Таким образом, вместо написания ndigit[c-48] обычной практикой является запись его как ndigit[c-'0'], чтобы указать, что вы преобразовываете значение ASCII вашего персонажа в цифру.

Вы можете легко проверить это:

 char c = '0';
 printf("%d", c); // prints 48
 printf("%d", c - `0`); // prints 0 -- that's what we are looking for
0 голосов
/ 01 ноября 2009

c - это символ, который может быть преобразован в int с помощью расширяющегося преобразования (8 бит на любое количество битов, которые int имеет на вашей платформе).

c - «0» вычитает целочисленное значение «0» из целочисленного значения «c».

Значения ASCII для символов от «0» до «9» являются последовательными, поэтому для символов в диапазоне от «0» до «9» вычитание значения «0» из значения «c» дает целое число в диапазон 0 - 9.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...