t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

Cの学習とVBAとの比較 その4 ~変数宣言とスコープ

本日も独習C。

独習C

独習C

この本の学習で一番驚いたのは、変数宣言はすべてブロックの先頭でしなければならないという記述である。
書籍によると、次のようなコードはコンパイルできないとある。

#include <stdio.h>

int main(void)
{
    printf("hogehoge");
    int i;
    i = 10;
    printf("%d", i);
    return 0;
}

int i;はprintf("hogehoge");よりも前に書かないといけないというのだ。

そんなばかなと思ってコンパイルしてみたところ、すんなりコンパイルできる。

???


で、調べてみたところ、たしかについ最近までCでは変数宣言を先頭で行う必要があったようだ。この制限が撤廃されたのはC99という規格からである。C99というのは、C言語のバージョンだと思ってよい。1999年に制定されたからC99。

今回使用しているMicrosoft製のC/C++兼用コンパイラVisual C++がC99規格に対応したのが、Visual C++ 2013からというから、つい2年前の話である。
私が持っている独習Cの第3版は2002年の発行なので、当時は確かにコンパイルできなかったわけだ。

お金があるなら最新の第4版を

独習C 第4版

独習C 第4版

…と思ったけどこっちも発行は2007年なので、たぶん「コンパイルできない」の記述のままだと思う。(読んでないけど)

VBAがMicrosoft1社によって実装されているのとは対照に、C言語は様々なベンダーやコミュニティーが独自のコンパイラを実装している。
プログラミング言語の仕様は著作権で保護されず、公開された仕様に基づいてだれでもコンパイラインタープリターを作成して良い。
だからコンパイラによってC89まで対応していたり、C90まで対応していたり、あるいは最新のC11に対応していたりとまちまちである。


私も専門学校では、変数宣言は最初に行うと習ったが、なるほど、あれは仕様上の制限だったのか。

ちなみに、VBAにそんな制限はないが、ネット上のサンプルでは最初に変数宣言がかたまっているものが多い。
これもCの仕様を引きずった癖が広まったものと思われるが、個人的には真似しないほうが良いと思う。

VBAでは変数宣言の位置に制限はないので、スコープを絞るという観点から、変数は使用する直前の宣言が望ましいと考える。
過去記事でその考えを示しているので興味があれば見てほしい。
thom.hateblo.jp

ではVBAの方が変数の扱いが優れているかというとそんなことはなく、Cでは{}を使うことで任意にスコープを絞ることができる。
たとえば、以下のコードは同じint型の変数iが2箇所で宣言されているが、ブロックが異なるため問題なくコンパイルできる。

#include <stdio.h>

int main(void)
{
    {
        int i = 10;
        printf("%d",i);
    }
    {
        int i = 20;
        printf("%d",i);
    }
}

また、最近のCで次のように書けるのは、for文が暗黙のブロックを作るからだとのこと。

#include <stdio.h>

int main(void)
{
    for(int i=1;i<=10;i++) printf("%d\n", i);
    int i = 20;
    printf("%d\n",i);
}

上記のfor文は1行で完結しているが、forの初期化部で宣言したiはforの中のみのスコープを持つ。
つまりforの右側のprintfではiを参照できるが、次の行ではiは見えなくなるので、新たに宣言できる。
VBAで似たようなことをすると(そもそもできないけど)、たぶんコンパイラに怒られる。
f:id:t-hom:20151015233456p:plain

もうひとつ、Cがスマートだと感じるのは、次のようなコード。

#include <stdio.h>

int main(void)
{
    for(int i=1;i<=10;printf("%d\n",i++));
}

これは1~10までの整数を出力するプログラムであるが、なんと、forの( ; ; )の中にすべて収まっている。
分かりやすいかどうかはこのさい置いておいて、すごく機能的だと思う。

CはVBAに比べると自由度が高く、冗長さを廃した極めてコンパクトなプログラムが書ける。
その反面、トリッキーで分かりづらいコードが書けてしまうので諸刃の剣といったところか。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。