第80回 プログラミングについて『いまさらですがC言語の門を叩こう その3~ 定数 ~』
当たり前のことですが、定数とは固定の値のことです。当然ですが、10 や 3.14 は定数であり、前者は整数型の定数、後者は実数型の定数です。これらの算術上の定数以外に文字定数と、文字列定数があります。
まず整数定数を考えてみましょう。
10
という定数はC言語では10進数の10のことを意味します。これについては誰もが理解して頂けると思います。ところが、
010
はC言語では意味が違うのです。この場合は8進数の10(10進数では8)を意味するのです。どうしてこういう解釈になるのかと問われても私は、こう決まっているから仕方ないんだとしか言えません。010 と書いても10進数の10と解釈する言語もありますが、C言語では8進数と解釈するという約束事があるのです。8進数ですので、
090
と書くとコンパイラに叱られてしまいます。C言語に慣れるまでよくバグの原因になるので注意して下さい。例えば、
i=10;
j=100;
としたいところを、プログラムの見た目をよくするために、
i=010;
j=100;
としてしまうことがときどきあるのです。当然希望する結果は出ません。10進数と8進数があるのならば2進数はというと残念ですけれどもありませんが、16進数はあります。
0x10
と記述すると、16進数の10で、10進数では16になります。
実数定数は、小数がある定数です。
1.0
は実数の定数です。詳しい話しはここではしませんが整数の 1 と値は同じなのですが、C言語では解釈に大きな違いがあります。このような見慣れた実数値の表現方法以外に指数形式で表現する方法もあります。
1.0e0
と表現すると、1.0 に 10の0乗を掛けた値になり、結果として 1.0 と同じ値になります。ですので、1.5e3 は 1500.0 ということになります。
実数定数で忘れてはいけないことに、コンピュータは実数値を近似値でしか持てないということです。運がいいときにはぴったりの値になりますが、殆どの場合は近似値です。
0.3
という実数値は実はコンピュータの中では、0.29999999999999999.... という値になっているのです。当然近似値ですので実数の計算時には誤差が発生しますので、
#include <stdio.h>
main()
{
if(0.1*3.0==0.3)printf("Same\n");
}
というプログラムを実行しても Same という文字は表示されないのです。
算術上の定数以外に文字に関する定数があります。文字の定数はアポストロフィで囲みます。
'a'
は文字 a を意味します。人間は a という文字として考えていてもコンピュータ内ではASCII文字コードの場合は、16進数で表現すると 0x61 という整数値で表現されているのです。ここがちょっと分かりづらいところなのですが、とりあえずはあまり気にしないでもいいと思います。
C言語の文字定数には特殊なものも含まれていて、改行文字、タブ文字など通常は文字として印字されない文字も表現することができます。
'\0' ヌル
'\n' 改行
'\r' 復帰
'\a' アラート(ベル)
'\t' 水平タブ
などです。詳しくは書籍を参考にして下さい。
次に文字列定数。文字列定数はダブルクォーテーションで囲んで表現します。
"Pen"
は文字列定数になります。当然 Pen という文字列です。C言語で文字列を扱うにはもう少し詳しく説明しなければなりません。C言語の文字列というのは、文字列の終わりを表すために、文字列の後にヌルが追加されます。ですので "Pen" は、
'P' 'e' 'n' '\0'
というようになっているのです。ですので3文字の文字列には1文字余分にヌル文字がありますので、実際には4文字分のメモリーが使われているのです。
更に問題なのが、文字の場合は値そのものなのですが、C言語では文字列の場合は文字列のアドレスが値になっているのです。
プログラムを勉強し始めた方にはアドレスという言葉はピンとこないと思います。コンピュータの世界でもアドレスとは日常生活で使う住所と意味合いとしては変わりはありません。コンピュータにはメモリーという記憶装置があって、プログラムの実行時にはその中に文字列定数が存在しています。当然コンピュータはメモリーのどこにその文字列があるのかを知っていなければなりません。その場所を示すのが住所、即ちアドレスなのです。コンピュータの世界では~県~市~町というような住所ではなく、基本的には1つの数値で表されます。メモリーを家が一列に並んだものと考えると、住所には県も市も町もなくても構いません。何番めの家かが分かればいいことになります。コンピュータはこのような考えでアドレスを決めています。(DOSやWindowsが16ビットの頃は、~町の~番地という表現でしたが、Windows95になってからは~町がなくなりました)。
いまメモリー上に文字列 "Pen" が次のように記憶されているとします。
□ □ □ □ □ □ 'P' 'e' 'n' '\0' □ □ □ □ □ □
|
500番地
このとき、"Pen" の値は 500 になるのです。ここがC言語を理解する上で最も難しいところで、メモリーの500番地には 'P' が、501番地には 'e' が、502番地には'n' が、そして503番地には '\0' があるのです。C言語ではこのような文字列のアドレスを文字列へのポインタという言い方をします。
最後にもう1つ、真と偽を示す値があります。特に型という訳ではないのですが、これもC言語でプログラムを書くには大切な要素です。C言語では0を偽とし、それ以外はすべて真になります。整数であっても、実数であっても、ポインタであっても0は偽で、それ以外は真です。FORTRANなどでは整数でなければならないのですが、C言語では自由度が大きくなっています。ですので、
0
0.0
は偽で、
1
-1
0.5
-0.5
"abc"
は真になります。
今回は短いのですがまた次回。