Этот метод работает в C, С++ и Java. Я хотел бы знать науку, стоящую за ней.
Как вычитание символа "0" из char меняет его на int?
Ответ 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 из-за обычного процесса продвижения типа.