Этот метод работает в 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
из-за обычного процесса продвижения типа.