2.7 定数
2.7.1 接尾辞
100 というような数字や二重引用符で囲まれた文字列などを総称して定数と呼びます。実は、定数にも変数と同様に型が存在します。定数を変数に代入する場合、もちろん定数は変数の型に対して互換性がなければなりません。
数字を表す定数は、浮動小数点定数と整数定数に分かれます。数字だけの場合、コンパイラは int 型の整数定数と判断し、少数点が見つかると double 型の定数として処理します。しかしこれでは、float や long double 、long 型などの定数を表現することができません。そこで C 言語では、定数の型を明示するために、数字の末尾に型を示すアルファベットを指定します。これを接尾辞と呼びます。整数定数に指定することができる接尾辞は表1 のいずれかです。
接尾辞 | 型 | 記入例 |
---|---|---|
l 又は L | 定数のサイズに従って long int 又は unsigned long int | 123456789L |
u 又は U | 定数のサイズに従って unsigned int 又は unsigned long int | 123456789U |
l 又は L と u 又は U |
unsigned long int | 123456789UL |
これらの接尾辞を整数定数に指定することで、定数の型を明示することができます。同様に浮動小数点定数も float か double か long double かを指定するための接尾辞が存在します。浮動小数点定数には表2 のいずれかの接尾辞を指定できます。
接尾辞 | 型 | 記入例 |
---|---|---|
f 又は F | float | 3.14F |
l 又は L | long double | 3.14L |
通常は、接尾辞を指定するような場面はありませんが、定数の型をコンパイラに伝えたい場合に接尾辞を用います。例えば、浮動小数点定数はデフォルトで double 型と認識されるため float 型の変数に浮動小数点定数を代入すると、コンパイラによっては警告を発生させます。
#include <stdio.h> int main() { float fVar = 3.14F; printf("%g\n" , fVar); return 0; }
コード1は、float 型変数 fVar に 3.14 という float 型の浮動小数点定数を代入しています。このとき定数の末尾に接尾辞 F を用いていることに注目してください。これを除くと、コンパイラによっては値が切り詰められることを警告します。そこで、プログラマはこの定数が float 型であることを証明し、安全に float 型変数に代入できることを、接尾辞を用いてアピールすることができます。
2.7.2 定数の様々な書き方
浮動小数点数も整数定数も、普通は特に意識することなく直観的な記述でかまいません。0.5 と書けば浮動小数点定数ですし、小数点がない数値であれば整数定数であると認識されるからです。しかし、浮動小数点数も整数定数も、これ以外の表現方法がいくつかあるので紹介したいと思います。
浮動小数点定数は、整数部、小数部、指数部に分かれています。整数部と小数部はそのいずれか一方を省略することが可能ですが、両方を同時に省略することはできません。ただし、指数表記を用いれば省略することができます。指数部は e または E の後に続いて値を指定します。
浮動小数点は 仮数 × 基数指数 で計算されるため指数を指定すれば整数部を指定する必要がないのです。例えば 3.14 という値を浮動小数点定数で表現する場合、いくつかの表現方法があります。
#include <stdio.h> int main() { float fVar1 = .314e1F; float fVar2 = 314e-2F; float fVar3 = 31.4e-1F; printf("fVar1 = %g\nfVar2 = %g\nfVar3 = %g\n" , fVar1 , fVar2 , fVar3); return 0; }
コード2では 3 つの float 型変数を浮動小数点定数で初期化しています。これらの浮動小数点定数は、全てが 3.14 という値です。しかし、ソースを見て確認できるように、表現は全て異なっています。このように、浮動小数点定数は同じ値でも様々な表現ができるので、知っておくとよいでしょう。
整数定数は、10 進数以外に 8 進数と 16 進数を用いることができます。2 進数を意識したような数値データを扱う場合は 10 進数を用いるよりも便利でしょう。特に 16 進数は、実際のプログラミングでも多用することが多いので重要です。例えば ARGB 形式の 32 ビット色データを表す場合、それぞれの 1 バイトの要素を 16 進数で指定するとわかりやすくて便利です。
整数定数を 8 進数で指定する場合は、数値の前に 0 を、16 進数で指定する場合は 0x 又は 0X を指定します。16 進数の場合、A ~ F までの数字は大文字でも小文字でもかまいません。
#include <stdio.h> int main() { printf("0xFF = %d\n0377 = %d\n" , 0xFF , 0377); return 0; }
16 進数 0xFF 及び 8 進数 0377 は、両方とも 10 進数で 255 という値です。予想通りコード3を実行すると、両方とも 10 進数で 255 という値を出力します。特に 2 桁の 16 進数は 8 桁の 2 進数(8 ビット)に等しいため、ビット演算などに使うことができます。
2.7.3 文字定数
ASCII 文字セットは、1つの英数文字を 1 バイトで表現します。ASCII コードは多くのコンピュータがサポートする標準の文字コードです。C 言語の文字定数は、すなわち 1 バイトの ASCII コードということになります。ASCII は American Standard Code for Information Interchange の略で、ANSI が 1962 年に制定した標準コードです。実際には 7 ビットで構成されていて、英文字と記号や数字などを表現することができます。
文字定数は引用符 ' に1文字を指定します。char 型の変数に文字を代入する場合、このように文字定数を指定します。char 型には数値を代入することもできますが、1バイトという性質から1文字を表現するのに適しているのです。文字定数で表すことができるのは常に1文字ですが、エスケープ文字を指定することも可能です。エスケープ文字を指定した場合 '\n' というのは2文字に見えますが、実際に現しているのは1文字のエスケープ文字です。
さて、重要なことですがコンピュータは文字を数値として扱っています。例えば ASCII コード 'A' は 16 進数 0x41 に相当し、 'B' は 0x42、'C' は 0x43 と連番になっています。すなわち、ソースコードで文字定数を指定しても、実際には数値として扱われるのです。これを理解すれば、コンピュータで文字というものがどのように扱われているのか、その原理を学ぶことができるでしょう。
#include <stdio.h> int main() { char chVarA = 'A'; char chVarB = 0x42; printf("chVarA(%%X) = %X\nchVarA(%%c) = %c\n" , chVarA , chVarA); printf("chVarB(%%X) = %X\nchVarB(%%c) = %c\n" , chVarB , chVarB); return 0; }
コード4を実行すると、大変興味深い結果が表示されます。
このプログラムは、char 型変数 chVarA と chVarB が格納している数値と、その文字表現を表示します。chVarA には、初期化子で 'A' という文字定数を代入していますが、先ほど説明したとおり、この値を16進数として出力すると 41 という結果が得られました。chVarB には16進数 42 という整数定数を代入しています。同様にこの変数を出力すると、数値は当然 42 を出力しますが、文字として表示させると B という結果になりました。先ほどの ASCII コードの A に続いていることがわかります。
このように、1文字は文字定数として指定することができますが、実際には数値として扱うことも可能なのです。ここでひとつ注意をしなければならないのですが、リテラル文字列 "" と文字定数 '' は根本的に違う種類だと認識してください。"A" と 'A' は異なります。
2.7.4 エスケープ文字
文字列や文字定数には \ 記号で始まるエスケープ文字を指定できます。エスケープ文字は改行やタブ文字など、通常の文字では表せない、表現が難しい文字コードを表すことができます。エスケープ文字は表3のようなものがあります。
記号 | 意味 |
---|---|
\a | ベル文字(アラート) |
\b | 1文字分戻る |
\f | ページ送り(クリア) |
\n | 改行、復帰 |
\r | 同じ行の先頭に戻る |
\t | 水平タブ |
\v | 垂直タブ |
\\ | \を表示 |
\? | ?を表示 |
\' | 引用符(')を表示 |
\" | 二重引用符(")を表示 |
\0 | ヌル |
\N | 8進定数(Nは8進数の定数) |
\xN | 16進定数(Nは16進数の定数) |
例えば、文字列内で二重引用符を用いたい場合や、文字定数で引用符を表現する場合、または \ 記号やタブ文字などを表現したい場合にこれらのエスケープ文字を使います。ただし、垂直タブなど、一部のエスケープ文字は特定のデバイスでしか意味を成さない場合もあります。