こんにちは､ そしてお帰りなさい｡ この講義では､ 定数文字列についてお話したいと思います｡
文字列リテラルや文字列定数は､ 二重引用符の中にあることが分かっています｡
しかし､ 変数そのものはどうでしょう｡ その変数が決してその値を変更できないようにするにはどうすればよいのでしょうか｡
これは定数と呼ばれるものです｡ そのため､ 変数の値が変化しないようなプログラムでは､
定数文字列が必要な場合があります｡
ですから､ 例えば何かの計算で円周を作る場合は､ 3ということになります｡
直径14159倍
3. 14159は定数です｡ それは決して変わりません｡
円周率を表しています｡
だから､ マジックナンバーを使う代わりに､ 変数を使い､ その変数が決して変化しないようにできれば､
本当にいいんです｡
ですから､ 毎回数値を入力するのではなく､
記号定数を使うにはそれなりの理由があるのです｡
まず､ 名前は数字よりも多くのことを教えてくれます｡
オワードは0に等しい｡ 015倍の住宅価格は､
オウンゴールイコール税率×価格よりもはるかに意味がない｡
そこで､ 決して変化しない数値を表す変数名を用意したい｡
長いプログラムを読み通すと､ セカンドビジョン版の意味はもっと平易なものになっています｡
そのコードを見て､ 0と理解するのは､ とても簡単です｡ 015は税率を表します｡
ある定数を複数の場所で使っていて､ その値を変更する必要が生じた場合､ その定数を定義した一箇所だけでなく､
プログラム中のあらゆる場所でその値を変更しなければならないのです｡
先ほど､ マジックナンバーという言葉を使ったときに､ この話をしました｡
これが参考になる｡
プログラムの中で使われている数値が変数に格納されていない場合は､
通常､ その数値を作成して定数に格納するのがベストです｡
そうすれば､ 何度も使ってその変数が変わっても､
1回だけ変えれば済むからです｡
使う場所によって変える必要はありません｡
だから､ マジックナンバーは避けて､ 定数を使う｡
cで定数を定義する方法として､ プリプロセッサーディレクティブを定義する方法があります｡
このプリプロセッサーディレクティブは定数を定義するもので､
実際にいくつかのプログラムで使ってみました｡ 今､ その説明のお手伝いをさせていただいています｡
ですから､ 税率を定数にしたい場合は､ その前にポンド記号を付けて定義と言えばいいのです｡
ポンド記号があるのでプリプロセッサーディレクティブであることはわかりますが､
次に名前と値を言います｡
プログラムがコンパイルされると､ 値0になります｡ 015は､ 税率を使ったところでは､
変数のように代用されますが､ 実は変数ではありません｡
そこに他の値を割り当てることはできません｡
変数だったらデータを代入できるけど､
今回はプリプロセッサーだからダメなんだ｡
つまり､ プリプロセッサーディレクティブではデータを代入できないので､
defineでそれを指定するわけです｡
そこで､ この構文に注目してください｡ ポンド記号の後に､ 定義されたキーワードがあります｡
そして､ その後に名前があるんですね｡
代入演算子は使っていません｡
名前と､ スペースと､ 値だけです｡
つまり､ その定義に値を割り当てるには､ スペースがあればいいわけです｡
最後にセミコロンがない｡ 発言ではありません｡ とても具体的ですね｡
つまり､ これらのプリプロセッサでは､ コンパイル時に置換が行われているのです｡
プリプロセッサーは､ コンパイラーが記憶する前に実行されます｡
プリプロセッサーが実行され､ これらの定義されたキャリー・ルーツを見ることになります｡ そして､ 税率が表示されているところには､
0を入れるだけです｡ 015 コンパイラ用
定義文は､ プログラムのどこにでも出現させることができます｡
ローカル・ディフィニションなんてものはないんだよ｡ 一度定義してしまえば､ 誰でも使えるようになります｡
ベストプラクティスや慣例では､ 複数のソースファイルを共有する場合､
プログラムの先頭やインクルードファイルの中に定義文を置くのが一般的ですが､ その必要はありません｡
プリプロセッサで動作しているため､ スコープを持たず､
ローカルもグローバルもないのです｡
どこにでも置けばいいんです｡ そして､ プログラムのどこでも見ることができ､ たとえ定義される前に使用されているとしても､
それを見ることができます｡
また､ 定義文は､ プログラムの移植性を高めるという点でも非常に優れています｡
定義済みのステートメントを使って､ プログラムが実行されているときに､ 実行中の特定のコンピュータに関連付けると､
まさにその値が得られることがあります｡
defined文は数字だけでなく､ 文字や文字列定数にも使えますので｡
このようなことをやりたいのであれば､ 完全に有効です｡
一文字をシングルクオートで囲むだけです｡
また､ 実際に文字列リテラルを丸ごと入れたい場合は､
二重引用符で囲むだけです｡ そして､ このおっかけがそうなのです｡
定数を作って見るという方法もありますが､ もっと最近の仕組みです｡
C90では､
基本的に別の方法として､ 定数モディファイアが追加されました｡
定数キーワードを使用すると､ 変数の宣言を定数の宣言に変換することができます｡
そして､ これによって､ その変数を決して変えられないようにすることができるのです｡ つまり､ constと言いながら､
データ型と変数名を指定するのです｡
そして､ この例では､ monthを12の記号定数としています｡
変数が変化することがあるから､ 変数と呼んでいるわけではありません｡
定数と変数がありますが､ 月の定数は変数ではなく､
変化しないものです｡
定数は､ 月を読み取り専用の値にします｡
月を表示したり､ 計算で使ったりすることができます｡ 月の値を変更することはできません｡
ですから､ 定数はデータを変化させたくない場合に重要であり､ またマジックナンバーの代わりにもなるのです｡
Constは新しいアプローチで､ defineを使うよりも柔軟性があります｡
型を宣言することができます｡
また､ プログラムのどの部分で定数を使用できるかをよりよく制御することができます｡
ですから､ できる限り定数を使うべきですが､ 多くのプログラムでは､ 最初のメカニズムであるため､
definedを使うことが多いようです｡
また､ 定数を作るには3つ目の方法があり､ それはenumを使用することです｡
列挙型の話をしたのを覚えていますか？
列挙型は､ 独自のタイプの変数を作成し､
特定のデータのみを関連付ける方法です｡ enumの値を変更することはできません｡
enumを定義したら､ その値を持たなければならない｡
異なる値を持つこともできますが､ それでも､
完全な方法ではなく､ ある種の方法でシンボル定数を作成することができます｡
また､ constを使えば､ 文字配列を初期化して定数として宣言することができるので､ 標準的なメッセージを扱うには良い方法だと思います｡
つまり､ const char message equals the end of the world is nighと言えば､
メッセージを定数として宣言し､ プログラム内で明示的に変更されることがないように保護されているのです｡
strコピーでメッセージを変更しようとすると､
コンパイラからエラーメッセージが表示されます｡
そして今度は､ プログラムのさまざまな部分で出力として表示される可能性のある標準的なメッセージにこれを使用することができます｡
標準的なメッセージを定義する手法は､ 先ほどのように多くの場所で使われる場合に特に有効です｡
マジックナンバーのように､ プログラムの他の部分でそのような定数が誤って変更されるのを防ぎます｡
定数には､ defineとconstantという2つの方法があります｡
ぜひご注目ください｡
これからの例で見ることができるかもしれません｡
ありがとうございます｡