C/C++學習總結積累(超詳細)——C提高:預處理(include、define、可變宏參)、編譯、匯編、鏈接
預處理
1)預處理的基本概念
C語言對源程序處理的四個步驟:預處理、編譯、匯編、鏈接。
預處理是在程序源代碼被編譯之前,由預處理器(Preprocessor)對程序源代碼進行的處理。這個過程並不對程序的源代碼語法進行解析,但它會把源代碼分割或處理成為特定的符號為下一步的編譯做准備工作。
2)預編譯命令
C編譯器提供的預處理功能主要有以下四種:
1)文件包含 #include
2)宏定義 #define
3)條件編譯 #if #endif ..
4)一些特殊作用的預定義宏
a、文件包含處理
1)文件包含處理
文件包含處理”是指一個源文件可以將另外一個文件的全部內容包含進來。C語言提供了#include命令用來實現“文件包含”的操作。
2)#include< > 與 #include ""的區別
" "表示系統先在file1.c所在的當前目錄找file1.h,如果找不到,再按系統指定的目錄檢索。
< >表示系統直接按系統指定的目錄檢索。
注意:
1. #include <>常用於包含庫函數的頭文件
2. #include " "常用於包含自定義的頭文件 (自定義的頭文件常用“ ”,因為使用< >時需要在系統目錄檢索中加入自定義頭文件的絕對地址/相對地址否則無法檢索到該自定義的頭文件,編譯時會報錯)
3. 理論上#include可以包含任意格式的文件(.c .h等) ,但我們一般用於頭文件的包含。
b、宏定義
1)基本概念
在源程序中,允許一個標識符(宏名)來表示一個語言符號字符串用指定的符號代替指定的信息。
在C語言中,“宏”分為:無參數的宏和有參數的宏。
2)無參數的宏定義
#define 宏名 字符串
例: #define PI 3.141926
在編譯預處理時,將程序中在該語句以后出現的所有的PI都用3.1415926代替。
這種方法使用戶能以一個簡單的名字代替一個長的字符串,在預編譯時將宏名替換成字符串的過程稱為“宏展開”。宏定義,只在宏定義的文件中起作用。
1 #include <stdio.h>
2
3 #define PI 3.1415f
4
5 int main(void) 6 { 7 float L,S,R,V; 8 printf("Input Radius:"); 9 scanf("%f",&R); 10
11 L=2.0f*PI*R; 12 S=PI*R*R; 13 V=4.0f/3*PI*R*R*R; 14
15 printf("L=%.4f,S=%.4f,V=%.4f\n",L,S,V); 16
17 return 0; 18 }
說明:
- 1) 宏名一般用大寫,以便於與變量區別
- 2) 字符串可以是常數、表達式等
- 3) 宏定義不作語法檢查,只有在編譯被宏展開后的源程序才會報錯
- 4) 宏定義不是C語言,不在行末加分號
- 5) 宏名有效范圍為從定義到本源文件結束
- 6) 可以用#undef命令終止宏定義的作用域
- 7) 在宏定義中,可以引用已定義的宏名
3)帶參數的宏定義
1) 格式:#define 宏名(形參表) 字符串
2) 調用:宏名(形參表)
3) 宏展開:進行宏替換
#define S(a,b) a*b
……
Area = S(3,2);
1 #include <stdio.h>
2
3 #define SQ_1(y) (y)*(y)
4 #define SQ_2(y) y*y
5
6 int main(void) 7 { 8 int a = 0,num_1 = 0,num_2 = 0; 9 scanf("%d",&a); 10 num_1 = SQ_1(a+1); //num_1 = (a+1)*(a+1);
11 num_2 = SQ_2(a+1); //num_2 = a+1*a+1;
12
13 printf("num_1 = %d\n",num_1); 14 printf("num_2 = %d\n",num_2); 15
16 return 0; 17 }
c、條件編譯
1)基本概念
一般情況下,源程序中所有的行都參加編譯。但有時希望對部分源程序行只在滿足一定條件時才編譯,即對這部分源程序行指定編譯條件。
2)條件編譯的作用
1)防止頭文件被重復包含引用
1 #ifndef _SOMEFILE_H 2 #define _SOMEFILE_H
3
4 //需要聲明的變量、函數 5 //宏定義 6 //結構體
7
8 #endif
2) 軟件裁剪
同樣的C源代碼,條件選項不同可以編譯出不同的可執行程序。
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define BIG 1
5 int main(void) 6 { 7 char str[20] = "C Language"; 8 char C; 9 int i = 0; 10 while ((C = str[i++]) != '\0') 11 { 12 #if BIG
13 if (C >= 'a' && C <= 'z') 14 C = C - 32; 15 #else
16 if (C >= 'A'&& C <= 'Z') 17 C = C + 32; 18 #endif
19 printf("%c", C); 20 } 21
22 system("pause"); 23
24 return 0; 25 }
d、一些特殊的預定宏
C編譯器,提供了幾個特殊形式的預定義宏,在實際編程中可以直接使用,很方便。
1 // __FILE__ 宏所在文件的源文件名 2 // __LINE__ 宏所在行的行號 3 // __DATE__ 代碼編譯的日期 4 // __TIME__ 代碼編譯的時間
5
6 #include <stdio.h>
7 #include <stdlib.h>
8
9 int main(void) 10 { 11
12 printf("%s\n", __FILE__); 13 printf("%d\n", __LINE__); 14 printf("%s\n", __DATE__); 15 printf("%s\n", __TIME__); 16
17 system("pause"); 18
19 return 0; 20 }