externとか配列とか(C入門中)
(追記: Enterキー押したら投稿されてもうた。ちょっと修正。はてなェ・・・)
何やってるの?
観念して望洋本の入門編を入手したので、読んだり書いたりしています。あぁ、ごく基本的な文法事項の説明がちゃんと載っている・・・ 恥ずかしがらずに最初から入門編を読めばよかった・・・。
他の言語でプログラミングをしたことがあるなら、この本は4章まで斜め読みして、5章(配列)、6章(関数)あたりから読めばよいと思います。
覚えたこと
配列宣言
配列宣言の要素数は、定数でなければならない。関数ローカルな変数は使えない。オブジェクト形式マクロは使える。
配列の初期化
- 配列の初期化子が足りない場合は0で初期化される。
- 「足りない場合」というのは、初期化子を1つ以上与えた場合に限られる。
- 初期化子を1つも与えない場合は、次のように、何らかの(おそらく処理系に依存する)値で初期化される。
#include <stdio.h> int main(void){ int vc[3] = {0}; int vd[3]; int i; for(i = 0; i < 3; i++){ printf("vc[%d]: %d\t", i, vc[i]); printf("vd[%d]: %d\n", i, vd[i]); } return 0; }
実行結果。
vc[0]: 0 vd[0]: -858993460 vc[1]: 0 vd[1]: -858993460 vc[2]: 0 vd[2]: -858993460
配列の受渡し
extern
関数外のどこかで定義された変数を使うときは、externで変数を宣言する。
- 参考: テキストエディターを作ろう Step4 「定義と宣言(extern 宣言)」の項
externで変数を宣言すると、宣言のみを行い、定義を行わない。int hoge; と extern int hoge; は違う。
- extern宣言をすると、その変数なり関数なりの定義がどこかにあることを、コンパイラが知ることができる。
- しかし、変数や関数がスコープ内に存在する場合は、extern宣言をしなくても、もちろん使える。
- それでも書く場合があるのは、可読性のためだろうか?
- グローバル変数を別ファイルから参照するときに使う。
Javaのstatic importのようなもの、という理解をしている。
- 参考: POINTER 「補足:externについて」の項
Cでグローバル変数を使用する場合、単純にヘッダファイルで、
POINTER
int global_variable;
のように宣言し、それを使用する(複数の) .c ファイルで #include している例は多い。
しかし、本来は、グローバル変数は、プログラム全体のどこか一箇所で 定義し、残りの個所では extern すべきである。
興味深い。まさにグローバル変数はincludeしまくって使うものだと思っていた(実際そういうコードを見かけるし・・・)。誤解だったみたい。
よく分からないこと
オブジェクト形式マクロと変数の使い分け
作法がよく分かっていない。同じファイル内の別の関数から呼ぶときに、マクロにすればよいのか? つまり、判断基準はスコープ次第ということでよいのか?
関数プロトタイプ宣言の使いどころ
Cのコードは、include文、関数プロトタイプ宣言、main関数、その他の関数、の順に並んでいた方が、個人的には読みやすい。しかし、main関数を最後に書くべし、という考え方もあるようだ(望洋本はこちらを推奨している)。それは、関数の仕様を変更したらプロトタイプ宣言と関数定義の両方を修正しなければならないからだ。そういわれると納得できる。
望洋先生がいうように書くのが正しいのかな?