プロが教えるわが家の防犯対策術!

タイトルの通り、defineで定義した値を配列のサイズ指定に使いたいと考えています。
この場合、次のような使い方をしても問題ないのでしょうか?

/* サンプルここから */
#define SIZE_A 10
#define SIZE_B 20
#define SIZE_ALL (SIZE_A * SIZE_B)

cahr ARR[SIZE_ALL];
/* サンプルここまで */

コンパイル時にワーニング等はありませんが、int型という型を宣言していないSIZE_ALLを要素数として使用するのが不安に感じるのですが問題ないのでしょうか?

int SIZE_int = SIZE_ALL;
とdefineした値を明示的にint型変数に代入した上で、
cahr ARR[SIZE_int];
とすべきなのでしょうか?

初歩的な質問ですが、ご教示お願いします。

A 回答 (3件)

★特に問題ありません。


・普通に define された定数を掛け算などして新しい記号定数を定義します。
 そしてその記号定数を配列などの添え字に使います。
 そもそも define された定数は通常は int 型と同じになります。
 #define SIZE_A 10…int型
 #define SIZE_A 10L…long型
 #define SIZE_A 10LL…long long型
 となります。
 『L』や『LL』のサフィックスを付けないとすべて int 型に解釈されます。
 つまり、プリプロセッサ命令は単純な文字列の置換ですのでサフィックスを
 付けないと int 型になるわけですよ。
・もし char 型にしたいならキャストを指定します。
 例えば
 #define SIZE_A ((char)(10))
 とします。
・もう既に回答がありますが
>int SIZE_int = SIZE_ALL;
>とdefineした値を明示的にint型変数に代入した上で、
>cahr ARR[SIZE_int];
>とすべきなのでしょうか?
 ↑
 この方法は新しい記述方法です。
 1999年の最新のC言語の規格です。
 この C99 にすべてのコンパイラが対応しているわけではないため使わない方が
 良いかもしれません。この記述が利用できれば便利なこともありますが…。
・最後にカッコをつけた方が良いですよ。
 #define SIZE_A (10)
 #define SIZE_B (20)
 #define SIZE_ALL (SIZE_A * SIZE_B)
 という風に SIZE_A、SIZE_B に括弧を付けます。
 これは今後 SIZE_A を『10 + 20』と定義した際に括弧がないと計算式が
 正しくなくなるので付けるように習慣を付けておいた方が良いということです。
 つまり今後
 #define SIZE_A 10 + 20
 #define SIZE_B 20 * 3
 #define SIZE_ALL (SIZE_A * SIZE_B)
 と定義したとします。
 すると SIZE_ALL は (10 + 20 * 20 * 3) と置換されますが計算式が掛け算を先に
 する数学上のルールより意図しない結果になります。正しくは SIZE_ALL=1800 に
 なるべくところが SIZE_ALL=1210 となってしまいます。
・これを防ぐには2つ。
 #define SIZE_A (10 + 20)
 #define SIZE_B (20 * 3)
 #define SIZE_ALL (SIZE_A * SIZE_B)
 もしくは
 #define SIZE_A 10 + 20
 #define SIZE_B 20 * 3
 #define SIZE_ALL ((SIZE_A) * (SIZE_B))
 と定義します。
 どちらにカッコを付けても同じですが私はすべてにカッコを付ける派です。
・参考にして下さい。
    • good
    • 1
この回答へのお礼

懇切丁寧な説明、ありがとうございます。
参照している書籍がビギナー向けのものばかりのためか、defineに
関する記述が少なく困っているところでした。

大変参考になりました。

お礼日時:2008/02/14 01:43

#define で定義された文字列は「コンパイルされる前に」プリプロセッサによって単純に置き換えられます。


なので、char ARR[SIZE_ALL]; なる宣言はコンパイラからは char ARR[10*20]; に見えます。

gcc -E などで実際に確認してみましょう。

>int SIZE_int = SIZE_ALL;
>とdefineした値を明示的にint型変数に代入した上で、
>char ARR[SIZE_int];
>とすべきなのでしょうか?

逆に、上記の宣言はコンパイル時に SIZE_int がいくつかコンパイラにはわからないので、
C99 に準拠したコンパイラじゃないと通らないと思います。
    • good
    • 1
この回答へのお礼

なるほど、置換されchar ARR[10*20]; とみなされるのですね。
ありがとうございました。

お礼日時:2008/02/14 01:41

#Cはほとんど読めない(実はpascal派)のですが・・



defineしている以上、

   cahr ARR[SIZE_ALL];



   cahr ARR[10];

としてコンパイルされるハズです。
    • good
    • 0
この回答へのお礼

ありがとうございました。

お礼日時:2008/02/14 01:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています