第56章 身長いくら?

 変数にはサイズがあります。これをプログラム上ではかれると便利ですね。今回は、そういうことをやっていきます。


 今回の要点です。


 では、いってみましょう。


 前回まで、ファイルの操作について話してきました。そのとき、読み込むサイズを数値で表していましたね。第29章で言ったように、こういうことはあまりやらない方がいいことです。

 では、これをどうしたらいいでしょうか? やはり第29章で言ったように、マクロを使うという手があります。配列のサイズをマクロで置き換え、それを使えばいいわけです。

 しかし、もう1つ便利な方法があります。それは、配列のサイズを取得するという方法です。実に単純な発想です。が、どうするのでしょうか?

 ということで、以下のプログラムを見て下さい。

プログラム実行結果
// File4c.cpp
#include <stdio.h>

int main()
{
    FILE* pFile;
    int   nLength;
    char  buffer[512];

    pFile = fopen("fwrite.txt", "rb");
    if(pFile == NULL)
      return 0;

    fread(&nLength, sizeof nLength, 1, pFile);
    fread(buffer, 1, sizeof buffer, pFile);
    buffer[sizeof buffer - 1] = 0;

    printf("文字列の長さは %d バイトです。\n%s\n", nLength, buffer);

    fclose(pFile);

    return 0;
}
文字列の長さは 10 バイトです。
1234567890

 赤くなっている部分が、第55章と違っている部分です。

 ここには、共通して出てくるものがありますね。そうです。sizeof です。

 この sizeof が、変数のサイズを取得する演算子です。サイズの単位はバイトです。

sizeof [変数]

とすると、その変数のサイズが分かります。

 こうすると、マクロを使わないでも数値を直接書くことなしに、サイズが指定できました。さらに、配列でない nLength についても、数値を使わずにサイズを指定することができました。ついでに、バッファの最後の位置も怪しい数値を使わずに指定することができました。これは便利ですね。


 さて、「sizeof は変数のサイズを取得する」と言いましたが、これは厳密には正しくありません。型のサイズを取得することもできるからです。

 では、次のプログラムを見て下さい。

プログラム実行結果
// Sizeof1.cpp
#include <iostream.h>

int main()
{
    cout << "int     : " << sizeof (int)     << endl;
    cout << "char    : " << sizeof (char)    << endl;
    cout << "double  : " << sizeof (double)  << endl;
    cout << "int*    : " << sizeof (int*)    << endl;
    cout << "char*   : " << sizeof (char*)   << endl;
    cout << "double* : " << sizeof (double*) << endl;

    return 0;
}
int     : 4
char    : 1
double  : 8
int*    : 4
char*   : 4
double* : 4

 今まで言ってきたとおりのサイズになっていますね。ポインタのサイズは常に int のサイズと同じになっていますね。

 このように、型のサイズを取得するときは、キャスト演算子に sizeof を付けます。キャスト演算子は、型キャスト(第21章参照)の時の、カッコ付きの型のことです。実は、カッコなしでも int とかは問題ないようですが、double だと問題があるようです。何でなのか分かりませんが、とりあえず型のサイズを取得するときはカッコは必ず付けておきましょう


 ここで、文法的な補足をしておきます。

 sizeof は演算子です。第43章で説明した区分では、単項演算子に入ります。インクリメント演算子 ++ や、マイナス符号 - などと同じですね。

 ところで、sizeof を使うときに

sizeof(a)

のように、対象をカッコで囲み、sizeof と (a) の間を詰めて、あたかも関数のように書く人がいます。というか、かなりの人がそうしています。もちろん、型のサイズを取得するときは当然のことです。配列の要素のサイズを取得するときも、気になるなら付けても構わないでしょう(必要はありませんが)。ですが、a のように単一の変数に付けるのは無駄です。優先順位(+より×の方が優先、というような暗黙の計算順序)が気になるときは

(sizeof a)

と、全体を囲むのが筋というものです。sizeof(a) では、優先順位には何も影響を与えていませんよね。(-x)2 としたいのに、-(x)2 としているようなものです。関数みたいに見えることで、全体がひとかたまりになっている気分がして逆に紛らわしいです。

 しかし、sizeof の優先順位は、普通気にすることはありません。気にならないようになっています。カッコを付けようが、付けまいが、どっちでも問題になることはないでしょう。しかし、一応「優先順位がある」ということは覚えておいた方がいいかもしれません。

 あと、関数のサイズは取得できません。あしからず。


 今回はこれでお終いです。では、今回の要点です。


 次回も sizeof について掘り下げてみましょう。それでは、また。


第55章 ファイルのススメ4 | 第57章 身長いくら?2

Last update was done on 2002.2.28

この講座の著作権はロベールが保有しています