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

Этот метод работает в C, С++ и Java. Я хотел бы знать науку, стоящую за ней.

Ответ 1

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

Не зная ничего о 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 номик...

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

Разница между 3, 5 или 2 и 0 на диаграмме ASCII в точности равна номинальному значению, которое мы обычно думаем, когда видим эту цифровую цифру. Вычитая char '0' из каждого, добавив их вместе, а затем добавив '0' обратно в конец, мы получим значение 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

Ответ 2

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

Из C-стандарта:

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

[...]

10 ПРИМЕР 2 Выполнение фрагмента

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

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

Применяя это к 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.

Ответ 3

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

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

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

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

Ответ 4

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