• ベストアンサー

defineで定数が置き換えられない?(C言語)

#defineについて質問です。 #defineは、ソースコード内にこの文字を見つけたら、コンパイルする前にこの文字をこの定数に置き換えて、というプリプロセッサですよね?だから、printfで#defineで定義した定数を出力する場合で、変換指定が必要ない場合は #include <stdio.h> #define DEF 100 void main(){ printf("#defineで定義された定数はDEFです"); } でもいいと思うんです。ですがこのソースコードは間違いで、実行結果は #defineで定義された定数はDEFです(←置き換えられてない) となってしまします。プリプロセッサだけ実行しても、DEFは100に置き換えられずそのままです。printfで#defineで定義した定数を出力させたい場合は書式指定をしなければなりません。なぜ、このような場合は#defineで定義した定数は置き換えられないのでしょうか?回答よろしくお願いします。

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

  • ベストアンサー
  • S117
  • ベストアンサー率40% (18/45)
回答No.5

「なぜ置き換えられないのか」について説明しましょう。 マクロが置き換えるのは、文字の並びではなく、トークンになります。 どういうことかというと、 #define DEF 100 とした場合、 DEFINE は「DEFINE」のままで「100INE」にはなりません。 置き換えできるのは「DEF」という文字の並びが前後と区切られているときだけです。 ここでトークンについて説明しましょう。一言で言うなら、記号や識別子などのプログラムの最小構成要素です。自然言語で言うなら、単語や句読点です。 sum=a+b; という一行のソースコードはトークンに分解すると、以下のようになります。 sum = a + b ; この段階ではそれが変数なのか、関数なのか、演算子なのかは考慮されていません。全部「トークン」です。 printf("#defineで定義された定数はDEFです"); この部分は以下のようなトークンに分解されるでしょう。 printf ( "#defineで定義された定数はDEFです" ) ; 文字列リテラルはそのままトークンになります。DEFというトークンが存在しないことがわかります。これでは置換できないのも当然です。 この辺の挙動は参考URLのWikipedia -コンパイラの3.1フロントエンドも参考にしてください。 なお、文字の並びを置換しない理由ですが、単純な置換よりもトークン単位の方が役に立つからです。冒頭のように「DEF」というマクロで「DEFINE」の一部が置換されるといやですよね。

参考URL:
http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9
noname#113783
質問者

お礼

詳しい・・・! 確かにトークンにしないと不便ですね。 トークンがないとソースももっと正確に書かないといけなくなりますし、便利ですねトークン。

その他の回答 (4)

  • 79562
  • ベストアンサー率0% (0/1)
回答No.4

ダブルクォーテーションの中に書いてある為だと思います。それだとその中にDEFと書いたとしても、ダブルクォーテーションによって文字列に変換されてしまいます。ので #include <stdio.h> #define DEF 100 void main(){ printf("#defineで定義された定数は%dです",DEF); } だと思います。

noname#113783
質問者

お礼

回答ありがとうございました!

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

引用府内は置換されないので 引用符の外に出せば出来ます #include <stdio.h> #define DEF "100" void main(){ printf("#defineで定義された定数は" DEF "です"); }

noname#113783
質問者

お礼

できました!printfに渡す文字列は間にプリプロセッサを挟んで区切ってもいいんですね。回答ありがとうございました。

  • rabbit_cat
  • ベストアンサー率40% (829/2062)
回答No.2

#include <stdio.h> #define DEF 100 void main(){ printf("#defineで定義された定数は" #DEF "です"); } とかやれば一応できるかな。(多分)

noname#113783
質問者

お礼

回答ありがとうございます! 上のソースコードですが、コンパイルしてみたのですができませんでした。"#DEF"の部分がエラーになっているのですが、調べてみたところソースコードに間違いはないはずなのですが・・・。こういう時にもっと知識があればなぁ。

  • Evreux
  • ベストアンサー率29% (225/774)
回答No.1

""で括っているから、そのまま出力されます。 こうしないと逆に、"DEF"という文字をprintfで出力できなくなってしまいます。

noname#113783
質問者

お礼

確かに!何で気付かなかったんでしょう。 回答ありがとうございました!