yohhoyの日記

技術的メモをしていきたい日記

数字から数値への変換: ch - '0'

プログラミング言語C/C++における、1文字の数字から1桁の整数値へ変換するイディオム ch - '0' について。

C/C++言語仕様では、数字の文字コード'0''9'がその並び順で連続かつ隣接すると保証する。このため変換元文字chから数字0の文字コード'0'を減算する下記処理は、処理系やソースコード文字集合によらず正常動作する。*1

int ch = /*...*/;
assert(isdigit(ch));  // chは任意の数字

int n = ch - '0';  // 数字から数値へ変換

C99 5.2.1/p3より一部引用(下線部は強調)。

3 Both the basic source and basic execution character sets shall have the following members:
(snip)
the 10 decimal digits

0 1 2 3 4 5 6 7 8 9

(snip) The representation of each member of the source and execution basic character sets shall fit in a byte. 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. (snip)

C++03 2.2/p1,3より一部引用(下線部は強調)。

1 The basic source character set consists of 96 characters: the space character, the control characters representing horizontal tab, vertical tab, form feed, and new-line, plus the following 91 graphical characters:

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '

3 (snip) For each basic execution character set, the values of the members shall be non-negative and distinct from one another. 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. (snip)

関連URL

*1:C/C++言語仕様が保証するのは、10進数字(decimal digits)文字コードの連続性のみ。一部の文字集合(例:wikipedia:en:EBCDIC)ではラテンアルファベット 'a'〜'z', 'A'〜'Z' 文字コードの連続性は保証されない。