Я прохожу некоторые проблемы практики, и я видел этот код:
#include <stdio.h>
#include <string.h>
int main(void) {
char* s = "357";
int sum = 0;
int i = 0;
for (i = 0; i < strlen(s); i++) {
sum += s[i] - 48;
}
printf("Sum is %d", sum);
return 0;
}
Кто-то может объяснить, что код делает, особенно вычитание с 48 частями?
Код в основном суммирует цифры числа, представленного в виде строки. Для правильной работы он делает два важных предположения:
'0'...'9'
В ASCII, '0' == 48
, '1' == 49
, и так далее. Таким образом, '0' - 48 == 0
, '1' - 48 == 1
, и так далее. То есть, вычитание на 48 переводит значения char
'0'...9'
в значения int
0...9
.
Таким образом, именно потому, что '0' == 48
, код будет работать и с:
sum += s[i] - '0';
Возможно, в этой версии замысел немного более ясен.
Конечно, вы можете сделать "обратное" отображение путем сложения, например, 5 + '0' == '5'
. Аналогично, если у вас есть char
, содержащий букву в диапазоне 'A'...'Z'
, вы можете "вычесть" из него 'A'
, чтобы получить индекс этой буквы в диапазоне 0...25
.
'0'
, так и с 48
! Как уже упоминалось, оригинальный код - 48
предполагает, что используемая кодировка символов - ASCII. - '0'
не только улучшает читаемость, но и отменяет предположение об ASCII, и будет работать с любой кодировкой, как указано в языке C, который предусматривает, что символы цифр должны быть закодированы последовательно в непрерывном блоке.
С другой стороны, в отношении букв такого условия нет. Таким образом, в редкой ситуации, когда вы используете кодировку EBCDIC, например, отображение 'A'...Z'
на 0...25
уже не так просто, как вычитание 'A'
, из-за того, что буквы НЕ кодируются последовательно в непрерывном блоке в EBCDIC.
Некоторые языки программирования упрощают ситуацию, предписывая использовать одну конкретную кодировку для представления исходного кода (например, Java использует Unicode: JLS §3.1)
он складывает 3 + 5 + 7, а затем печатает
Сумма равна 15
Часть -48
заключается в том, что он вычитает символ 0, то есть значение ascii для 0.
Так что он делает следующее
'3' - '0' > 51 - 48
'5' - '0' > 53 - 48
'7' - '0' > 55 - 48
Как вы видите, в языке C '0' (символ ноль) отличается от 0 (число 0). Они имеют разные значения (среди прочего)
Нахождение суммы чисел в строке s.
Программа sum += s[i] - 48;
преобразует символы ASCII в их числовые значения.
Я предлагаю написать тестовую программу, чтобы посмотреть, что отображают значения s[]. Вы также можете распечатать все значения для каждой записи в "0123456789".
Я думаю, вы быстро поймете, что это делает, хотя этот код полагается на кодировку ASCII.
Веселитесь!