4

Довольно часто в коде можно увидеть строки типа

char cdigit = '8';
int idigit = cdigit - '0';

Реже, но также встречается

char letter = 'd';
int letter_number = letter - 'a';

Открываем Страуструпа "Язык прогрммирования С++" специальное издание, "Бином-Пресс", 2008. Цитата (стр 110):

Небезопасно считать, ... что символы алфавита непрерывны (в стандарте EBCDIC между i и j имеется разрыв)

У Кернигана и Ритчи вышеприведенный код (по крайней мере по цифрам) встречается регулярно.

Собственно вопрос по цифрам: обязательно ли корректен код idigit = cdigit - '0'?

VladD
  • 206,799
andy.37
  • 7,461
  • Собственно нашел http://stackoverflow.com/questions/868496/how-to-convert-char-to-integer-in-c. Там утверждается, что текущий стандарт С гарантирует корректность. Ответ от 09 года. – andy.37 Nov 30 '15 at 19:37
  • Огромное спасибо за цитаты из стандартов. Есть одна проблема - я в замешательстве, кому ставить галочку) Ну почему нельзя две поставить? – andy.37 Nov 30 '15 at 19:57
  • Причём один ответ по C, а второй по C++ :) – VladD Nov 30 '15 at 20:01
  • @VladD, причем цитаты совпадают досимвольно)) – andy.37 Nov 30 '15 at 20:03
  • Кто-нибудь может кинуть ссылку на реализацию atoi. Интересно, как там написано. Я нашел только хедеры. – andy.37 Nov 30 '15 at 20:05
  • Нашел (itoa, но неважно) : https://en.wikibooks.org/wiki/C_Programming/C_Reference/stdlib.h/itoa – andy.37 Nov 30 '15 at 20:09
  • Ну, там имплементация K&R, они вполне могли писать под их текущее hardware. Язык тогда только начинался, и о кроссплатформенности никто не думал особенно. – VladD Nov 30 '15 at 20:32
  • И кстати "символы алфавита" и "цифры" немного разные вещи. Я еще не видел кодировок, где цифры не шли бы подряд. А EBCDIC, да, прикольный такой шрифт, особенно русские локализации, где одинаковые по начертанию буквы всегда латинские :) – Mike Dec 01 '15 at 00:02

2 Answers2

8

В стандарте C++ §2.3/4 гласит:

In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.

то есть

В обоих наборе символов исходного текста и времени выполнения, значение каждого символа после 0 в приведённом выше списку десятичных цифр должно быть на единицу больше предыдущего.

(перевод мой). Приведённый в §2.3/1 набор цифр таков:

0 1 2 3 4 5 6 7 8 9

Это гарантирует последовательность значений кодов цифр.

VladD
  • 206,799
  • Ну, и я так понимаю, что за letter -'a' нужно бить по рукам? – andy.37 Nov 30 '15 at 19:58
  • @andy.37: Насчёт letter ничего в стандарте не нашёл, так что по идее да, надо бить по рукам. – VladD Nov 30 '15 at 20:02
  • 1
    @andy.37: Плюс EBCDIC является явным контрпримером. – VladD Nov 30 '15 at 20:05
4

Нашел всё-таки такую фразу в сишном Стандарте (C99):

In both the source and execution basic character sets, the value of each character after0in the above list of decimal digits shall be one greater than the value of the previous.

αλεχολυτ
  • 28,987
  • 13
  • 60
  • 119