Перевод char в int. Зачем " -'0' "?

Решаю задачи на acmp. Суть этой была в том чтобы складывать цифры числа, а затем если полученное числа больше 9, то есть не однозначное, складывать снова до тех пор пока не получится однозначное. Но не суть. Час убил на это, понаписал кучу всего, но потом нашел этот код. Собственно он вполне рабочий, но некоторый моменты мне непонятны.

  1. Всегда ли можно так спокойно переводить char в int? Компилятор ничего не сказал по этому поводу, а я раньше считал, что это можно делать только при помощи atoi и itoa, но они переводят сразу всю строку.
  2. Что делает «-'0'»? Зачем оно там стоит и что вообще значит? Без него программа выдает совсем другой результат.
  3. И по поводу условия продолжения счетчика for «str[i]». Как это работает? Мне просто непривычно видеть там что-то без условия равенства или неравенства.

Буду благодарен, если кто-то поможет разобраться.
Вот код:

#include <iostream> 
using namespace std; 
int main(){ 
char str[1001]; // Входных максимум 1000
cin>>str; 
int sum=0, c=0, i; 
for(i=0;str[i];++i)sum+=str[i]-'0';  // Вот эта строка
if(i>1) c=1; 
while(sum>9){ 
sum=sum%10+sum/10%10+sum/100%10+sum/1000; 
++c; 
} 
cout<<sum<<" "<<c; 
return 0; 
}

MG000, по порядку:

1). char можно всегда неявно преобразовывать в int, поскольку оба этих типа представляют целое число со знаком, но диапазон значений int не меньше диапазона значений char. Это во-первых.

Во-вторых, char может интерпретироваться [программистом] либо как число со знаком (аналогично int, long int, etc.), либо как символ (буква, цифра и т.п.), представленный семи- или восьмибитным кодом (например по таблице ASCII), т.е. в этом случае переменная типа char содержит код символа.

В-третьих, функция atoi принимает не char, а const char *, т.е. константный указатель на массив значений типа char, проще говоря, константный указатель на С-строку (не путать с std::string из STL!).

2). Это перевод цифры в число. Учитывая то, что в массиве char str[1001] содержатся ASCII-коды символов и то, что коды для цифр (символов) 0, 1, ..., 9 в таблице ASCII идут непрерывным блоком в том же порядке, можно делать преобразование из кода символа в число вычитая из кода цифры код цифры 0. Например, '5' - '0' для компилятора будет значить 0x35 - 0x30 (код цифры 5 минус код цифры 0), что даст число 5. Результат будет также типа char, как и исходные операнды.

3). С-строка заканчивается нулевым символом ('\0'). В условном выражении 0 соответствует false, все остальные значения — true. Поэтому оператор можно переписать в форме for (i = 0; str[i] != '\0'; ++i). Т.е. цикл будет продолжаться пока не будет достигнут конец строки.

Cranium, большое спасибо за помощь! Теперь все понятно.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.