
タイトルの通り、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];
とすべきなのでしょうか?
初歩的な質問ですが、ご教示お願いします。
No.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))
と定義します。
どちらにカッコを付けても同じですが私はすべてにカッコを付ける派です。
・参考にして下さい。
懇切丁寧な説明、ありがとうございます。
参照している書籍がビギナー向けのものばかりのためか、defineに
関する記述が少なく困っているところでした。
大変参考になりました。
No.2
- 回答日時:
#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 に準拠したコンパイラじゃないと通らないと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
構造体を引数とする、クラス間...
-
main.c:7:43: warning: implici...
-
【#define】 defineで定義した...
-
C++/CLIでネイティブの構造体を...
-
2重定義って??
-
構造体の要素すべてに対する四...
-
C++でboolにintの値を代入する...
-
C++のコンストラクタを宣言する...
-
C#でオセロを作っているのです...
-
64bit → 32bit型へのキャスト
-
DWORDの実際の型は何でしょうか
-
C言語のコンパイルエラー
-
相互参照するクラス、俺こんな...
-
24ビットの変数
-
long型の定数の末尾にLを付ける...
-
最早開始時間と最遅完了時刻を...
-
Aの値からBの値を除するとは??
-
信頼区間の1.96や1.65ってどこ...
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語 エラーの原因がわからな...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
main.c:7:43: warning: implici...
-
long型の定数の末尾にLを付ける...
-
DWORDの実際の型は何でしょうか
-
visualstudio C# テキストボッ...
-
2重定義って??
-
C++のfor文について
-
変数の型を定義しなかった場合...
-
ハンドルされていない例外が発...
-
intとINTの違いは?
-
C++でboolにintの値を代入する...
-
構造体の要素すべてに対する四...
-
プログラムの中で別のmainを呼...
-
エラー「invalid conversion fr...
-
GCCで暗黙の型変換の警告を出し...
-
【#define】 defineで定義した...
-
sshdログの意味
-
DDVによるメッセージの変更
-
typedef enumの使い方を教えて...
-
構造体を生成時にわざわざ初期...
-
DLLでLIBファイルが作成されない
おすすめ情報