Как вычитание символа " 0 " из символа изменяет его на int?

этот метод работает на C, C++ и Java. Я хотел бы знать, что за наука стоит за этим.

4 ответов


значение a char может быть 0-255, где разные персонажи сопоставляются с одним из этих значений. Числовые цифры также хранятся в порядке '0' через '9', но они также обычно не хранятся как первые десять char значения. Символ '0' не имеет значения ASCII 0. Значение char 0 почти всегда нуль-символ.

не зная ничего больше о ASCII, это довольно просто как вычитание '0' символ из любого другого числового символа приведет к значению char исходного символа.

Итак, это простая математика:

'0' - '0' = 0  // Char value of character 0 minus char value of character 0
// In ASCII, that is equivalent to this:
48  -  48 = 0 // '0' has a value of 48 on ASCII chart

таким образом, аналогично, я могу сделать целочисленную математику с любым из char numberics...

(('3' - '0') + ('5' - '0') - ('2' - '0')) + '0') = '6'

разницу между 3, 5 или 2 и 0 на диаграмме ASCII точно равно номиналу, о котором мы обычно думаем, когда видим эту числовую цифру. Вычитая char '0' от каждого, добавив их вместе, а затем добавив '0' back в конце даст нам значение char, которое представляет char, который будет результатом выполнения этой простой математики.

фрагмент кода выше эмулирует 3 + 5 - 2, но в ASCII, это на самом деле делает это:

((51 - 48) + (53 - 48) - (50 - 48)) + 48) = 54

потому что на диаграмме ASCII:

0 = 48
2 = 50
3 = 51
5 = 53
6 = 54

в C + и - операторы применяют целочисленное продвижение*1 к их аргументам, таким образом, результат вычитания (или добавления) двух charС int*2.

из стандарта C:

5.1.2.3 выполнение программы

[...]

10 Пример 2 при выполнении фрагмента

char c1, c2;
/* ... */
c1 = c1 + c2;

"целочисленные акции" требуют, чтобы абстрактная машина повышает значение каждой переменной до int размер, а затем добавить два тега ints [...]

применяя это к неявно заданному варианту использования OP

char c = 42;
... = c - `0`;

это приведет к тому, что выше будет то же самое, что:

... = (int) c - (int) `0`; /* The second cast is redundant, as per Jens' comment. */              
      ^                ^
      +------ int -----+

*1: Если аргументы операторы имеют более низкий ранг, чем int они повышаются до int.
*2: char имеет более низкий ранг, чем int.


здесь никаких изменений. '0' является int в C. Это причудливый способ писать 48 (предполагая ASCII).

вы можете убедить себя в этом факте, вычисляя размер '0':

  printf ("sizeof '0'   is %zu\n", sizeof '0');
  printf ("sizeof(char) is %zu\n", sizeof(char));

который в первой строке, скорее всего, печатает 4 (или 2), но, вероятно, не 1, как во второй строке (опять же: в C; это отличается для C++).


числовая константа 0, без каких-либо квалификаций, типа int. Результат бинарной операции вычитания на char и int также имеет тип int из-за обычного процесса продвижения типа.