t-hom’s diary

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

独習C 第4章(データ型、変数、式の詳細)まで完了

直近では小学生のドリルを解きつつも、気分転換にCの学習も進める。

先日から何度も紹介しているこちらの書籍である。

独習C

独習C

そういえば先日注文したC++の学習書も今日届いた。
当初、柴田さんの書籍(以下)にしようかと思っていたのだが、、

新版 明解C++ 入門編 (明解シリーズ)

新版 明解C++ 入門編 (明解シリーズ)

独習シリーズの続き、独習C++の中古品がAmazonでなんと49円。

独習C++

独習C++

(ただし初版である。)

これは仕方がない。即決。

冒頭で、Cが分からん奴は出直して来いという意味のことが書かれていて、いきなりオブジェクト指向の説明から入る。
独習Cを終えた後なら、無駄がなくて良いかもしれない。
(また変数とは~とかやってられないし。)


さて、独習Cの方はちょうど4章のデータ型、変数、式の詳細まで完了した。
4章最後の問題でちょっと意図しない動作があったので紹介しておく。

以下のようなコードで、ループが終了するかどうかという問題だ。

#include <stdio.h>

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

たぶん、「終了しない、なぜならばintの上限値を越えて符号が変わるから」と答えてほしいのだろうと思って一応試してみたら、、

あれ?普通に終わるし。

それじゃあ、問題にならなくないか?と思って解答を見ると、やはり「終わらない」との記載が。
ああ、時代が進んでintの上限値が変わったのか。

現在ではintが32ビットになっている様子。
1ビットは符号(プラスorマイナス)なので、数値としては31ビットである。
つまり2の31乗マイナス1=2147483647までの数値が扱える。
数が大きすぎるのと、人間からみてハンパすぎるので、ちょっと意味が分からないかもしれない。
まあとにかく、33000は余裕で扱えるということ。

では、問題文の意図どおり、これを終わらないプログラムにしてみる。

#include <stdio.h>

int main(void)
{
    short i;
    for(i=0; i<33000; i++) printf("%d\n",i);
    return 0;
}

変数宣言をshortに変えるだけ。
※shortというのは、short intの省略記法である。もちろん、short intと書いても良い。
short int型にすると16ビットになる。
1ビットは符号なので、扱える数の上限は2の15乗マイナス1=32767
上限値の32767に1を足すと、符号がひっくり返って-32768になる。

なんでマイナスは32768まで扱えるかというと、以下のような仕組み。

まず符号ビット(先頭の赤い数字)が0のときをプラスとする。
数値0は2進数でこうなる。
0000000000000000

プラスの最大値32767は、こうだ。
0111111111111111

これに1を足すと繰り上がってこうなる。
1000000000000000

さて、これは何?
マイナスのゼロ?
いやいや、ゼロはゼロだ。プラスもマイナスも無い。
先頭を符号ではなく数値ビットと考えると32768となる。
つまり、先頭ビットは符号ビットと数値ビットを兼ねているのだ。だからこの値は-32768である。

これがマイナスの場合に1つ上限が多い原理。

そして数値をさらに足していくと、マイナス1までくる。

1111111111111111

これに1を足すと、繰り上がってはみ出たビットが消え、0に戻る。

0000000000000000

…という原理で、先ほどのループは無限に回り続ける。

ところでVBAではどうなるか。
やってみた。

Sub test()
    Dim i As Integer
    For i = 1 To 33000
        If i Mod 1000 = 0 Then Debug.Print i
    Next i
End Sub

f:id:t-hom:20151019001254p:plain


いままでの渾身の説明はいったい何だったのか。
まぁ、親切なのはVBAの方である。「無理なものは無理。」
それに比べるとCは「自己責任でどうぞ。」といった感じの仕様である。
あくまでプログラミングそのものに関してはCの方が学びは多い感じがする。

以上、本日はここまで。

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