6

マクロのような関数の考え方を理解しようとしていますが、困惑する点がいくつかあります。たとえば、次のようになります。

#define Max(a,b)  ((a)>(b)) ? (a):(b))

そして私はそれをそのように呼びます

int i = Max(4,5);

a>bこれにより、 ?と同等の条件式が評価されます。はいの場合はa、そうでない場合はb。しかし、Max関数が引数をどう処理するかをどのように知っているかについて私は混乱しています。実際の関数とは異なり、実装は呼び出し側プログラムのコードで記述されていません。定義ステートメントの右側のステートメントは私のためにこれを行っていますか?それは私にとっては新しいことであり、ここで何が起こっているのかを確実に理解したいと思います。

マクロのような関数のこの特定の部分は私を混乱させます。これらのタイプのマクロは、スタックのメモリを節約するJSR RTSプロセッサ命令を除外しているため、オーバーヘッドコストを削減するのに役立つことを私は知っています。

4

4 に答える 4

13
#define Max(a,b)  ((a)>(b)) ? (a):(b))

はマクロであり、コード内で単純なテキスト置換を行うだけです。つまり、前処理中に次の行を実行します。

int i = Max(4,5);

に変更されます:

int i = ((4)>(5)) ? (4):(5));

このようなマクロを操作している間は型の安全性がなく、コードのデバッグ中にも非常に苦労することに注意してください。経験則として、関数で同じことができる場合はマクロを使用しないでください

int max(int a, int b) {
    return (a > b) ? a : b;
}
于 2013-03-22T16:45:49.207 に答える
5

前処理後にコンパイラーが実際に認識するのは、次のとおりです。

int i = ((4)>(5)) ? (4):(5));

マクロに渡されたパラメーターは、マクロの本体に置き換えられます。

于 2013-03-22T16:38:24.873 に答える
5

コンパイル可能なコードのようなマクロについて考えるのをやめてください。マクロは、実際にはコンパイル段階ではなく、プリプロセッサによって「解決」されます。したがって、マクロ定義によって、テキストファイル内の特定の文字列を処理する方法を定義するだけです。プリプロセッサの出力のみがコンパイラに渡されます。gcc -Eプリプロセッサの後でソースを表示するために使用できます。この段階ではまだCコードですが、プリプロセッサディレクティブはありません。

これがお役に立てば幸いです。

于 2013-03-22T16:56:01.927 に答える
3

を使用してコードをビルドし、gcc -Eコンパイルする前にコードがどのように表示されるかを確認してください

実際、ビルドプロセスでは、コンパイラーが実際のコードをプリプロセッサーコードに変換します。プリプロセッサフ​​ェーズでは、コンパイラはcコード内のすべてのマクロをそのコンテンツに置き換え、プリプロセッサコードと呼ばれる別のコードを生成してから、プリプロセッサコードからオブジェクトコードを生成します。

gcc -Eプリプロセッサコードを表示できるようにします

于 2013-03-22T16:38:17.503 に答える