2016/08/31

[c/c++]私のC言語 (9) - ローカル変数を宣言する位置

C99からだと思うが、変数の宣言位置がどこでもよくなった。
ローカル変数の話なのだが、あれ、用語としては宣言と定義のどっちだ?

・・・K&Rでは「変数の宣言」になっているから、宣言としておこう。
と書いたものの、externの説明では「外部変数の定義」と書いているな。
付録の「宣言」のところには「メモリを確保する宣言は定義と呼ばれる」と書かれている。
つまり、"宣言"の特殊形が"定義"ということか。

もう1冊持っていた「C言語 重要用語解説」では、以下の"宣言"を"定義"と呼ぶそうだ。

  • オブジェクトに対しては、そのオブジェクトの記憶域を確保する宣言
  • 関数に対しては、関数本体を含む宣言
  • 列挙定数またはtypedef名に対しては、その識別子の宣言

んで、その下に「"int i;"のようなオブジェクトの定義は一般的には宣言と呼ぶ傾向にある」と記載してあった。
なんだよ、傾向って。。。

確かに私の中でも、static変数は「定義」って感じがするけど、ローカル変数は「宣言」で済ませたい気持ちがある。
スタックポインタをずらすだけだからだろうか?

というわけで、ここでは「宣言」にしておくので、各自の用語定義で読み直してほしい。


宣言位置はC++がそうだったからあまり気にしていなかったのだが、ANSI-Cなどはブロックの先頭で行う言語仕様だったからそうしていた。
今は「C99で書いてます」と言っておけば、使う時になって宣言すればよいので、気持ちとしては楽だ。

私は、ローカル変数の宣言時に強制的に初期化するのが嫌でねぇ。。。
後で書き換えられない可能性があるならよいけど、書き換えられるのがわかっているなら省きたい。
それだったら、使用する直前に宣言して、同時に代入してしまった方が無難だ。

ただ、変数の戻り値ret、みたいな変数はあちこちで使うので、これはブロックの先頭に書くね。

 

switch文の中でしか使わない変数の場合は、ちょっと揺れる。
ブロックを作るか、switch文の外に宣言しておくか。。。
caseの中にブロックを書くと、インデントをどうするか悩むのだ。
私は、caseをインデントしない派なので、こんな感じになってしまう。

switch (calc_val) {
case 1:
    {
        int a = calc_val * rand();
        ...
    }
    break;

別によいのだけど、せっかくcaseをインデントさせなくて浅めにしたいのに、ブロックで深くなるともったいない、とも思ってしまうのだ。

じゃあ外に書けばいいやん、となるけど、その変数ってここでしか使わないのに・・・と、こっちはこっちで気持ちが微妙になる。


forのループ変数をその場で定義するのは、よくやる。

for (int loop = 0; loop < 10; loop++) {
   ...
}

ただ、途中でbreakしたかどうかを知りたいときは、抜けた後で変数の数を見たいから、外で宣言することになる。

それだったら、最初から外で宣言すればいいやん、と思われそうだけど、うーん、あまりそれは好きじゃないのだよなぁ。
理由が説明できないのだが、forを終わったらスタックポインタが戻るから、とかか?
でもレジスタに割り当てられることもしばしばだから。。。

うん、さっきのswitchと同じで、単に好みの問題だな。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。