目次
1.コンパイルプロセス:
.cファイルをバイナリファイルに変換します。
C言語では、各.cファイルは「コンパイルユニット」と見なされます。各コンパイルユニットについて、コンパイラは最初に.cと含まれる.hを.oに変換します(.oは「オブジェクトファイル」です。これも「オブジェクトファイル」です。バイナリファイルですが、まだ実行できません)
2リンクプロセス:
最後に、.oファイルをマージします。
実際の開発では、関数の定義と呼び出しは2つの異なる.cに分散していることが多く、それらは異なる.oにコンパイルされるため、これらの.oファイルは最後にマージする必要があります。
リンクプロセスでは、ユーザーが作成したファイルでコンパイルされた.oをリンクするだけでなく、一部のライブラリファイル(標準ライブラリ、サードパーティライブラリ)をリンクする必要があります。ここのライブラリは動的ライブラリとして提供できます。または静的ライブラリ。提供する方法。
3.コンパイルリンクには4つの部分が含まれています
①前処理:
実行される操作:マクロの置換、ヘッダーファイルの展開、条件付きコンパイル、コメントの削除、プリコンパイルされた命令の処理。
ただし、#で始まるものはすべて、次のように前処理段階で実行されます。#define #include #pragma
条件付きコンパイル:(たとえば、一部のコードが削除されるなど、選択的にコンパイルするのは便利ですが、それを邪魔するのは残念です。条件付きコンパイルは複数行のコメントとしても使用できます)
#if:マクロに定義があるかどうかだけでなく、マクロの値がtrueかどうかにも注意してください
#endif
#そうしないと
#ifdef:次のマクロが定義されているかどうかにのみ注意してください
#ifndef:#ifdefを論理的に否定するのと同じです
上記の操作は「コンパイル」を制御するために使用され、プログラムの実行とは関係ありません。
事前定義された記号:
__FILE __ //コンパイル用のソースファイル
__LINE __ //ファイルの現在の行番号
__DATE __ //ファイルがコンパイルされた日付
__TIME __ //ファイルがコンパイルされた時刻
__STDC __ //コンパイラがANSICに従う場合、その値は1です。それ以外の場合、未定義です。
これらの事前定義された記号は、次のように言語に組み込まれています。
printf("file:%s line:%d\n", __FILE__, __LINE__);
②コンパイル
狭義のコンパイルとは、具体的には.cソースコードファイルをアセンブリ命令に変換することを指します
③コンパイル
ターンアセンブリ命令をにバイナリマシン命令
④リンク
4.マクロについて
①マクロの本質
前処理段階でテキスト置換を実行します。
②マクロの利用
1.マクロを使用して定数を定義します
#define SIZE 10
2.マクロを使用して演算子の名前を変更します
#define and && #define or ||
3.マクロを使用して、タイプのエイリアスを再定義します
// typedef unsigned int uint; #define uint unsigned int //给unsigned int类型取一个别名 unit //上面两种方式的区别在于使用typedef定义后面需要加封号
4.マクロを使用してキーワードのエイリアスを定義することもできます
// register 表示 "寄存器" // 这个关键字已经废弃了. #define reg register
5.マクロを使用してコードスニペットを定義することもできます
#define CHECK(ret) if (ret == 0) { \ printf("执行失败\n"); \ return 1; \ }
6.マクロは「コンパイラスイッチ」としても使用できます
// 可以根据条件让一些代码能编译或者不编译. // 结合条件编译来使用 // _CRT_SECURE_NO_WARNINGS 就是一个编译开关 // 没有这个宏的定义的时候, VS 就会多编译一些对于 scanf 等函数安全检查的逻辑 // 有这个宏定义, 相关的检查代码就不被编译了. // 这段检查的代码在 stdio.h 里头. 所以必须把这个宏定义到 stdio.h 的上方
③マクロの長所と短所(関数と比較して)
短所:
Ⅰ。正しく書くのは少し難しいです。展開中は、演算子の優先順位により、式の演算結果が期待と一致しない場合があります。
Ⅱ。マクロにはパラメータの型チェックがありません。関数には型チェックがあります。実際のパラメータは、使用する前に仮パラメータの型と一致する必要がありますが、マクロは一致しません。マクロは「テキスト置換」を実行するだけです。
Ⅲ。マクロのデバッグが難しい
Ⅳ。関数ほど読みにくい
利点:
Ⅰ。一部の機能ではできない、または難しいことを実現できます。
#define CHECK(ret) if(ret==0){\ printf("执行失败\n");\ return 1;\ } int main() { //如果程序执行成功, 就继续往下走 // 如果程序执行失败, 就结束程序 int ret = 0; ret = login(); CHECK(ret); ret = enterRoom(); CHECK(ret); ret = startMatch(); CHECK(ret); ret = acceptGame(); CHECK(ret); }
Ⅱ。マクロの実行効率は関数の実行効率よりわずかに高く、関数呼び出しはパラメータを渡す必要があります(実際のパラメータをコピーします)
Ⅲ。マクロはある程度「ジェネリックプログラミング」を実現できます。
たとえば、次のコードは整数と浮動小数点数の加算をサポートできます。
#define ADD(x,y) ((x)+(y))
④#と##:「高度なマクロ使用法」に属する
#:マクロパラメータを対応する文字列に変換します
#define PRINT(FORMAT,VALUE)\
printf("the value of "#VALUE" is "FORMAT" \n",VALUE);
int main()
{
PRINT("%d",(i+2));
return 0;
}
//运行结果: the value of (i+2) is 12
//此处#VALUE相当于把(i+2)转成了字符串,变成结果的一部分了.
##:両側のシンボルを1つのシンボルに組み合わせることができます。これにより、マクロ定義で個別のテキストフラグメントから識別子を作成できます。
#define ADD_TO_SUM(num,value)\
sum##num +=value;
int main()
{
int sum1=0;
int sum2=0;
ADD_TO_SUM(1,10);
ADD_TO_SUM(2,20);
}
//上面1和2这个参数被拼接成了变量名,成了sum1,sum2的一个部分