• ベストアンサー

C言語の#defineについて

初歩的なことですみませんが、 #define命令はソースのどこに記述しても問題ありませんか? 一応、コンパイル時には問題ないようですが。 また、#ifdef,#ifndef,#elseifとうのマクロ全般においてはどうなのですか? どなたか教えていただけませんか?

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

> #define命令はソースのどこに記述しても問題ありませんか? ある程度制限はあります。 まず、1論理行(行末に\があれば連結した上での1行)に記述できる前処理指令はひとつだけです。 次に、論理行において#の前に空白類(コメントを含む)以外があってはなりません。 #ifなども同様です。 > また、#ifdef,#ifndef,#elseifとうのマクロ全般においてはどうなのですか? #if, #ifdef, #ifndef, #else, #elif, #endifは、#ifと#endifが対応していなければならないなどの制約もあります。 いきなり、#elifや#endifを書くことはできません。 なお、#elseifというのは分かりません。

TCD725c
質問者

お礼

回答ありがとうございます。 少し制限があることが分かりました。 ということは、関数内に書いたり命令の直後に書いても動作上は問題ないと言うことですか? ............. #define kazu 200 if(!(.....)) printf("kazu\n"); #define kazu 100 printf("kazu"); .............. (...は省略の意味) このような記述は危険ではないのでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

どこに書いても「本当の(というか狭義の) コンパイラ」には見えない (と思っていい) ので特に問題ないのですが.... でも, #define kazu 100 printf("kazu"); とやったところで「100」と表示されるわけじゃないってのは理解できてますよね?

TCD725c
質問者

お礼

回答ありがとうございました。参考になりました。 >「100」と表示されるわけじゃないってのは理解できてますよね? 確かに表示されないのは分かっていたのですが...勘違いしていました。

全文を見る
すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> このような記述は危険ではないのでしょうか? 問題ありません。

TCD725c
質問者

お礼

回答ありがとうございます。解決しました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Cの最初の行に

    #ifndef PQFORMAT_H #define PQFORMAT_H のようなものがあったりしますが #define PQFORMAT_Hで変数PQFORMAT_Hに何も割り当てていません このようなマクロはどういう時に使うのでしょうか? PQFORMAT_Hは一例で一般の変数と考えてください 何も割り当てない#defineの使い道を教えてください よろしくお願いします

  • マクロ初級 #define

    #include <iostream.h> #define mkr(a) {cout << a;\cout << b;\} void main(void){ cout << "2数を表示するマクロ" << endl; mkr(1,9); } ↑これをコンパイルするとエラーになりました。 エラー 5行目 マクロ 'mkr' の呼び出しにおける引数の個数が 誤っている(関数 main() ) ネット上で見つけたものなんですが、このプログラムを 正しく修正するとどうなるんですか? マクロのソースを見たのは初めてだったので分かりませんでした。

  • 【#define】 defineで定義した値を配列のサイズに使う事は可能?

    タイトルの通り、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]; とすべきなのでしょうか? 初歩的な質問ですが、ご教示お願いします。

  • C言語で直角三角形の斜辺を求めるプログラムについて

    「二辺の長さが与えられているとき、斜辺の長さを求めよ」という問題です。 #include <stdio.h> #include <math.h> #define a 3 #define b 4 int main (void) { double c=0; c=sqrt(a*a+b*b); printf("%f",c); return 0; } visual2010c++で作ったんですが、sqrtに下線がついて、コンパイルエラーしちゃいます。 すんごい初歩的なことなんだと思いますが、どこなのか気づけません。 どなたかよろしくお願いします。

  • コンパイル時のスイッチについて

    C言語初心者なので申し訳ありませんが,コンパイル時のスイッチについて困っております. 現在, #define tmp ... #ifdef tmp  関数1 #else  関数2 #endif とtmpを定義して切り替えようとしております. 現在コンパイルの切替は,毎回 //#define tmp とコメントアウトして切り替えているのですが, gcc等のコンパイラのコマンドラインから 切り替える方法はあるのでしょうか. 色々調べたら, cc -D tmp みたいな?感じにするのかと思ったのですがうまくいきません. 初歩の質問ですがご教授よろしくお願いします.

  • C言語における定数の使用方法

    こんにちは。 今日質問したいのは、タイトルにありますように、C言語における「定数」の使い方についてです。 私は現在、Visual C++を用いてC言語のプログラミングを勉強しているのですが、条件文(if文)に定数を用いてコーディングを行おうとしても、どうしてもエラー表示が出て、うまくコンパイルすることができません。 具体的には、 if(No>=1 && No<=10){ //具体的な処理部分 } というif文を、予めヘッダファイル内にて定義した定数 #define start 1; #define stop 10; を用いて次のように、 if(No>=start && No<=stop){ //具体的な処理部分 } コーディングしたいと考えています。 しかし、これをコンパイルするとエラーが発生してしまいどうにもうまくいきません。 また、定数ではなく数字で記述するとうまく回ります。 別のところで定数を、 wk = start; のように代入で使用しているのですが、そこではなにも問題がありません。 いったい何が間違っているのか、どのようにすればうまくいくのかを教えていただきたいと考え、書き込ませていただきました。 皆様、どうぞよろしくお願いします。

  • 構造体サイズをコンパイル時に出力させられるか(gcc)?

    gccでソースの改造でメモリ節約のため構造体サイズの圧縮を行っているのですが、 構造体定義が#defineマクロの塊になってしまっているのでサイズの見当がつかなくて 困っています。 sizeofの値をコンパイル時のエラーメッセージ出力などを使って出力できれば、 実装してターゲットでprintf()を動かさなくてもいいので助かるのですが、プリ プロセス命令の組み合わせとかでどうにかならないでしょうか?

  • ソースとヘッダについて

    VC++2008を使っています。これは他でもいえるのではないかと思いますが、一応プロジェクトの種類はWindowsFormアプリケーションです。 字数削減や書きなおしを楽にするために、ある程度のマクロを織り交ぜたコーディングをしたいのですが ソースに#defineしたものの効果範囲は、#undefの場所まで あるいはそれがなければそのソースの終了地点まで でしょうか? もしそうなら、ソースに書く分なら「別のソースに同じマクロを、全く違う定義をして使っても問題ない」という事でしょうか? ヘッダに書いた場合は、なんか#undef文を下の方に書いてもまるで上に書いたかのように「駄目」という判定になってしまったのですが、かといって#undefを書かないとそのヘッダをインクルードする他のヘッダにも影響を与えてしまうようで… これをどうにかできる方法はありませんか? また、ソースでは #pragma once などをしなくてもいいのですか? (あるいは書いてもソースはオブジェクトファイルに変換され、実質的にはコンパイル後に影響が出るため、プリプロセッサはコンパイル前に完了するので、ソースにこれを書いたところで無意味ということでしょうか?)

  • libecc

    楕円曲線暗号のソースコードをダウンロードしました。 libecc の中のファイルに #define LibEccDebug(STATEMENT...) LibcwDebug(libecc::debug::channels, STATEMENT) との記述があります。 たぶん、gccをつかえば コンパイルできると思うのですが、 CV++2005でコンパイルしたいのです。 ...が問題なので #define LibEccDebug(STATEMENT) LibcwDebug(libecc::debug::channels, STATEMENT) と変えてしまって差し支えないでしょうか? また、 #define LibEccDebug(STATEMENT...) の...は、 他にも引数があるよ という意味に理解してかまわないのでしょうか? よろしくお願いします。

  • C++の組込みマクロのassert()が使えない

    こんにちは。 CygwinでC++開発を行っているのですが、C++の関数型マクロであるassert()が使えなくて困っています。 main関数を含むソースファイルに、 #include assert.h を記述しておけば使えるはずなのですが、そのソースファイルから実行ファイルを、 g++コマンドでビルドしようとすると、以下のようなエラーが出ます。 ------------------------------------------------------------ $ g++ test03-STLの使用.cpp /cygdrive/c/Users/Kei/AppData/Local/Temp/cckwDP4e.o:test03-STLの使用.cpp:(.text+0x904): undefined reference to `___assert_func' collect2: ld はステータス 1 で終了しました ------------------------------------------------------------ test03-STLの使用.cpp のmain関数は、以下の通りです。 ------------------------------------------------------------ int main() { string s="ABC DEF\nGH\tIJ"; reverse(s.begin(), s.end() ); assert(s=="JI\tHG\nFED CBA"); cout<<s return 0; } ------------------------------------------------------------ ちなみに、実際にインクルードされる /usr/include/assert.h の内容は以下のようになっていました。 ------------------------------------------------------------ /* assert.h */ #ifdef __cplusplus extern "C" { #endif #include "_ansi.h" #undef assert #ifdef NDEBUG /* required by ANSI standard */ # define assert(__e) ((void)0) #else # define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ __ASSERT_FUNC, #__e)) # ifndef __ASSERT_FUNC /* Use g++'s demangled names in C++. */ # if defined __cplusplus && defined __GNUC__ # define __ASSERT_FUNC __PRETTY_FUNCTION__ /* C99 requires the use of __func__. */ # elif __STDC_VERSION__ >= 199901L # define __ASSERT_FUNC __func__ /* Older versions of gcc don't have __func__ but can use __FUNCTION__. */ # elif __GNUC__ >= 2 # define __ASSERT_FUNC __FUNCTION__ /* failed to detect __func__ support. */ # else # define __ASSERT_FUNC ((char *) 0) # endif # endif /* !__ASSERT_FUNC */ #endif /* !NDEBUG */ void _EXFUN(__assert, (const char *, int, const char *) _ATTRIBUTE ((__noreturn__))); void _EXFUN(__assert_func, (const char *, int, const char *, const char *) _ATTRIBUTE ((__noreturn__))); #ifdef __cplusplus } #endif ------------------------------------------------------------ Borland C++ Compilerのbcc32コマンドでは、先ほどのソースファイルから実行ファイルをビルドすることができたので、何が問題なのかが分かりません。 以上の件について何かご存知の方がいらっしゃれば、是非教えて頂きたいと思います。 では、よろしくお願い致します。