程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C/C++預處理命令

C/C++預處理命令

編輯:關於C++

1.預處理概述和文件包含命令

前面各章中,已經多次使用過#include命令。使用庫函數之前,應該用#include引入對應的頭文件。這種以#號開頭的命令稱為預處理命令。

C語言源文件要經過編譯、鏈接才能生成可執行程序:
1) 編譯(Compile)會將源文件(.c文件)轉換為目標文件。對於VC/VS,目標文件後綴為 .obj;對於GCC,目標文件後綴為 .o。

編譯是針對單個源文件的,一次編譯操作只能編譯一個源文件,如果程序中有多個源文件,就需要多次編譯操作。
2) 鏈接(Link)是針對多個文件的,它會將編譯生成的多個目標文件以及系統中的庫、組件等合並成一個可執行程序。

不過,在編譯之前有時候還需要對源文件進行簡單的處理。例如,我們希望自己的程序在Windows和Linux下都能夠運行,那麼就要在Windows下使用VS編譯一遍,然後在Linux下使用GCC編譯一遍。但是現在有個問題,程序中要實現的某個功能在VS和GCC下使用的函數不同(假設VS下使用 a(),GCC下使用 b()),VS下的函數在GCC下不能編譯通過,GCC下的函數在VS下也不能編譯通過,怎麼辦呢?

這就需要在編譯之前先對源文件進行處理:如果檢測到是VS,那麼就保留 a() 刪除 b();如果檢測到是GCC,那麼就保留 b() 刪除 a()。

這些在編譯之前對源文件進行的簡單處理,就稱為預處理(即預先處理、提前處理)。

預處理主要是處理以#開頭的命令,例如#include 等。預處理命令要放在所有函數之外,而且一般都放在源文件的前面。

預處理是C語言的一個重要功能,由預處理程序完成。當對一個源文件進行編譯時,系統將自動調用預處理程序對源程序中的預處理部分作處理,處理完畢自動進入對源程序的編譯。

編譯器會將預處理的結果保存到和源文件同名的.i文件中,例如 main.c 的預處理結果在 main.i 中。和.c一樣,.i也是文本文件,可以用編輯器打開直接查看內容。

C語言提供了多種預處理功能,如宏定義、文件包含、條件編譯等,合理地使用它們會使編寫的程序便於閱讀、修改、移植和調試,也有利於模塊化程序設計。

#include命令

#include是文件包含命令,主要用來引入對應的頭文件。#include的處理過程很簡單,就是將頭文件的內容插入到該命令所在的位置,從而把頭文件和當前源文件連接成一個源文件,這與復制粘貼的效果相同。

#include有兩種使用方式:
#include 
#include "myHeader.h"
使用尖括號< >和雙引號" "的區別在於頭文件的搜索路徑不同,我們將在《C語言頭文件的路徑》一節中深入探討,請大家先記住:包含標准庫的頭文件一般用尖括號,包含自定義的頭文件一般用雙引號。

說明:
    一個#include命令只能包含一個頭文件,多個頭文件需要多個#include命令。文件包含允許嵌套,也就是說在一個被包含的文件中又可以包含另一個文件。
    2.C語言宏定義 宏定義是預處理命令的一種,它允許用一個標識符來表示一個字符串。先看一個例子:
    1. #include
    2. #define N 100
    3. int main(){
    4. int sum = 20 + N;
    5. printf("%d\n", sum);
    6. return 0;
    7. }
    運行結果:
    120

    該示例中的語句int sum = 20 + N;N100代替了。

    #define N 100就是宏定義,N為宏名,100是宏的內容。在編譯預處理時,對程序中所有出現的“宏名”,都用宏定義中的字符串去代換,這稱為“宏代換”或“宏展開”。

    宏定義是由源程序中的宏定義命令#define完成的,宏代換是由預處理程序完成的。

    宏定義的一般形式為:

    #define 宏名 字符串

    #表示這是一條預處理命令,所有的預處理命令都以#開頭。define是預處理命令。宏名是標識符的一種,命名規則和標識符相同。字符串可以是常數、表達式等。
    這裡所說的字符串是一般意義上的字符序列,不要和C語言中的字符串等同,它不需要雙引號。
    程序中反復使用的表達式就可以使用宏定義,例如:
    #define M (n*n+3*n)
    它的作用是指定標識符M來代替表達式(y*y+3*y)。在編寫源程序時,所有的(y*y+3*y)都可由M代替,而對源程序編譯時,將先由預處理程序進行宏代換,即用(y*y+3*y)表達式去替換所有的宏名M,然後再進行編譯。

    將上面的例子補充完整:
    1. #include
    2. #define M (n*n+3*n)
    3. int main(){
    4. int sum, n;
    5. printf("Input a number: ");
    6. scanf("%d", &n);
    7. sum = 3*M+4*M+5*M;
    8. printf("sum=%d\n", n);
    9. return 0;
    10. }
    運行結果:
    Input a number: 10↙
    sum=1560

    上面的程序中首先進行宏定義,定義M來替代表達式(n*n+3*n),在sum=3*M+4*M+5*M中作了宏調用。在預處理時經宏展開後該語句變為:
    sum=3*(n*n+3*n)+4*(n*n+3*n)+5*(n*n+3*n);
    需要注意的是,在宏定義中表達式(n*n+3*n)兩邊的括號不能少,否則會發生錯誤。如當作以下定義後:
    #difine M n*n+3*n
    在宏展開時將得到下述語句:
    s=3*n*n+3*n+4*n*n+3*n+5*n*n+3*n;
    這相當於: 3n2+3n+4n2+3n+5n2+3n 這顯然是不正確的。所以進行宏定義時要注意,應該保證在宏代換之後不發生錯誤。

    對宏定義的幾點說明

    1) 宏定義是用宏名來表示一個字符串,在宏展開時又以該字符串取代宏名,這只是一種簡單的替換。字符串中可以含任何字符,可以是常數,也可以是表達式,預處理程序對它不作任何檢查,如有錯誤,只能在編譯已被宏展開後的源程序時發現。

    2) 宏定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起替換。

    3) 宏定義必須寫在函數之外,其作用域為宏定義命令起到源程序結束。如要終止其作用域可使用#undef命令。例如:
    1. #define PI 3.14159
    2. int main(){
    3. // Code
    4. return 0;
    5. }
    6. #undef PI
    7. void func(){
    8. // Code
    9. }
    表示PI只在main函數中有效,在func中無效。

    4) 宏名在源程序中若用引號括起來,則預處理程序不對其作宏代換,例如:
    1. #include
    2. #define OK 100
    3. int main(){
    4. printf("OK\n");
    5. return 0;
    6. }
    運行結果:
    OK

    該例中定義宏名OK表示100,但在 printf 語句中 OK 被引號括起來,因此不作宏代換,而作為字符串處理。

    5) 宏定義允許嵌套,在宏定義的字符串中可以使用已經定義的宏名,在宏展開時由預處理程序層層代換。例如:
    #define PI 3.1415926
    #define S PI*y*y    /* PI是已定義的宏名*/
    對語句:
    printf("%f", S);
    在宏代換後變為:
    printf("%f", 3.1415926*y*y);

    6) 習慣上宏名用大寫字母表示,以便於與變量區別。但也允許用小寫字母。

    7) 可用宏定義表示數據類型,使書寫方便。例如:
    #define UINT unsigned int
    在程序中可用UINT作變量說明:
    UINT a, b;
    應注意用宏定義表示數據類型和用typedef定義數據說明符的區別。宏定義只是簡單的字符串代換,是在預處理完成的,而typedef是在編譯時處理的,它不是作簡單的代換,而是對類型說明符重新命名。被命名的標識符具有類型定義說明的功能。

    請看下面的例子:
    #define PIN1 int *
    typedef (int *) PIN2;
    從形式上看這兩者相似, 但在實際使用中卻不相同。

    下面用PIN1,PIN2說明變量時就可以看出它們的區別:
    PIN1 a,b;
    在宏代換後變成:
    int *a,b;
    表示a是指向整型的指針變量,而b是整型變量。然而:
    PIN2 a,b;
    表示a、b都是指向整型的指針變量。因為PIN2是一個類型說明符。由這個例子可見,宏定義雖然也可表示數據類型, 但畢竟是作字符代換。在使用時要分外小心,以避出錯。

    3.C語言帶參數宏定義 C語言允許宏帶有參數。在宏定義中的參數稱為形式參數,在宏調用中的參數稱為實際參數。

    對帶參數的宏,在調用中,不僅要宏展開,而且要用實參去代換形參。

    帶參宏定義的一般形式為: #define 宏名(形參列表) 字符串 在字符串中含有各個形參。

    帶參宏調用的一般形式為: 宏名(實參列表); 例如:
    #define M(y) y*y+3*y  //宏定義
    // Code
    k=M(5);  //宏調用
    在宏調用時,用實參5去代替形參y,經預處理宏展開後的語句為k=5*5+3*5

    【示例】輸出兩個數中較大的數。
    1. #include
    2. #define MAX(a,b) (a>b) ? a : b
    3. int main(){
    4. int x , y, max;
    5. printf("input two numbers: ");
    6. scanf("%d %d", &x, &y);
    7. max = MAX(x, y);
    8. printf("max=%d\n", max);
    9. return 0;
    10. }
    運行結果:
    input two numbers: 10 20
    max=20

    程序第2行進行了帶參宏定義,用宏名MAX表示條件表達式(a>b) ? a : b,形參a、b均出現在條件表達式中。程序第7行max=MAX(x, y)為宏調用,實參x、y,將代換形參a、b。宏展開後該語句為:
    max=(x>y) ? x : y;
    用於計算x、y中的大數。

    對帶參宏定義的說明

    1) 帶參宏定義中,形參之間可以出現空格,但是宏名和形參列表之間不能有空格出現。例如把:
    #define MAX(a,b) (a>b)?a:b
    寫為:
    #define MAX  (a,b)  (a>b)?a:b
    將被認為是無參宏定義,宏名MAX代表字符串(a,b) (a>b)?a:b。宏展開時,宏調用語句:
    max=MAX(x,y);
    將變為:
    max=(a,b)(a>b)?a:b(x,y);
    這顯然是錯誤的。

    2) 在帶參宏定義中,形式參數不分配內存單元,因此不必作類型說明。而宏調用中的實參有具體的值,要用它們去代換形參,因此必須作類型說明。這是與函數中的情況不同的。在函數中,形參和實參是兩個不同的量,各有自己的作用域,調用時要把實參值賦予形參,進行“值傳遞”。而在帶參宏中,只是符號代換,不存在值傳遞的問題。

    3) 在宏定義中的形參是標識符,而宏調用中的實參可以是表達式。

    【示例】輸入 n,輸出 (n+1)^2 的值。
    1. #include
    2. #define SQ(y) (y)*(y)
    3. int main(){
    4. int a, sq;
    5. printf("input a number: ");
    6. scanf("%d", &a);
    7. sq = SQ(a+1);
    8. printf("sq=%d\n", sq);
    9. return 0;
    10. }
    運行結果:
    input a number: 9
    sq=100

    第2行為宏定義,形參為y。程序第7行宏調用中實參為a+1,是一個表達式,在宏展開時,用a+1代換y,再用(y)*(y) 代換SQ,得到如下語句:
    sq=(a+1)*(a+1);
    這與函數的調用是不同的,函數調用時要把實參表達式的值求出來再賦予形參,而宏代換中對實參表達式不作計算直接地照原樣代換。

    4) 在宏定義中,字符串內的形參通常要用括號括起來以避免出錯。在上例中的宏定義中(y)*(y)表達式的y都用括號括起來,因此結果是正確的。如果去掉括號,把程序改為以下形式:
    1. #include
    2. #define SQ(y) y*y
    3. int main(){
    4. int a, sq;
    5. printf("input a number: ");
    6. scanf("%d", &a);
    7. sq = SQ(a+1);
    8. printf("sq=%d\n", sq);
    9. return 0;
    10. }
    運行結果為:
    input a number: 9
    sq=19
    同樣輸入9,但結果卻是不一樣的。問題在哪裡呢?這是由於替換只作符號替換而不作其它處理而造成的。宏替換後將得到以下語句:
    sq=a+1*a+1;
    由於a為9故sq的值為19。這顯然與題意相違,因此參數兩邊的括號是不能少的。即使在參數兩邊加括號還是不夠的,請看下面程序:
    1. #include
    2. #define SQ(y) (y)*(y)
    3. int main(){
    4. int a,sq;
    5. printf("input a number: ");
    6. scanf("%d", &a);
    7. sq = 200 / SQ(a+1);
    8. printf("sq=%d\n", sq);
    9. return 0;
    10. }
    本程序與前例相比,只把宏調用語句改為:
    sq=160/SQ(a+1);
    運行本程序如輸入值仍為9時,希望結果為2。但實際運行的結果如下:
    input a number: 9
    sq=200

    為什麼會得這樣的結果呢?分析宏調用語句,在宏代換之後變為:
    sq=200/(a+1)*(a+1);
    a為9時,由於“/”和“*”運算符優先級和結合性相同,則先作200/(9+1)得20,再作20*(9+1)最後得200。為了得到正確答案應在宏定義中的整個字符串外加括號,程序修改如下:
    1. #include
    2. #define SQ(y) ((y)*(y))
    3. int main(){
    4. int a,sq;
    5. printf("input a number: ");
    6. scanf("%d", &a);
    7. sq = 200 / SQ(a+1);
    8. printf("sq=%d\n", sq);
    9. return 0;
    10. }
    由此可見:對於宏定義不僅應在參數兩側加括號,也應在整個字符串外加括號。

    4.C語言帶參宏定義和函數的區別 帶參的宏和帶參函數很相似,但有本質上的不同,把同一表達式用函數處理與用宏處理的結果有可能是不同的。

    【示例①】用函數計算平方值。
    1. #include
    2. int SQ(int y){
    3. return ((y)*(y));
    4. }
    5. int main(){
    6. int i=1;
    7. while(i<=5){
    8. printf("%d^2 = %d\n", (i-1), SQ(i++));
    9. }
    10. return 0;
    11. }
    運行結果:
    1^2 = 1
    2^2 = 4
    3^2 = 9
    4^2 = 16
    5^2 = 25

    【示例②】用宏計算平方值。
    1. #include
    2. #define SQ(y) ((y)*(y))
    3. int main(){
    4. int i=1;
    5. while(i<=5){
    6. printf("%d^2 = %d\n", i, SQ(i++));
    7. }
    8. return 0;
    9. }
    VC 6.0下運行結果:
    1^2 = 1
    3^2 = 9
    5^2 = 25

    C-Free(MinGW)下運行結果:
    3^2 = 1
    5^2 = 9
    7^2 = 25
    之所以出現不同的結果,與 printf() 參數列表中表達式的計算順序和優先級有關,這裡不再深究。
    分析如下:在示例①中,函數調用是把實參 i 值傳給形參 y 後自增 1,然後輸出函數值,所以要循環5次,輸出1~5的平方值。而在示例②中宏調用時只作代換,SQ(i++) 被代換為 ((i++)*(i++))。第一次循環,i 的值為1,(i++)*(i++)=1;第二次循環 i 的值為 3,(i++)*(i++)=9;第三次循環 i 的值為 5,(i++)*(i++)=25;第四次循環,i 的值為7,終止循環。

    從以上分析可以看出函數調用和宏調用二者在形式上相似,在本質上是完全不同的。

    宏定義也可用來定義多個語句,在宏調用時,把這些語句又代換到源程序內。看下面的例子。
    1. #include
    2. #define SSSV(s1, s2, s3, v) s1=l*w; s2=l*h; s3=w*h; v=w*l*h;
    3. int main(){
    4. int l=3, w=4, h=5, sa, sb, sc, vv;
    5. SSSV(sa, sb, sc, vv);
    6. printf("sa=%d\nsb=%d\nsc=%d\nvv=%d\n", sa, sb, sc, vv);
    7. return 0;
    8. }
    運行結果:
    sa=12
    sb=15
    sc=20
    vv=60

    5.C語言宏參數的字符串化和宏參數的連接 在宏定義中,有時還會用到###兩個符號,它們能夠對宏參數進行操作。

    # 的用法

    #用來將宏參數轉換為字符串,也就是在宏參數的開頭和末尾添加引號。例如有如下宏定義:
    #define STR(s)
    那麼:
    printf("%s", STR(c.biancheng.net));
    printf("%s", STR("c.biancheng.net"));
    分別被展開為:
    printf("%s", "c.biancheng.net");
    printf("%s", "\"c.biancheng.net\"");
    可以發現,即使給宏參數“傳遞”的數據中包含引號,使用#仍然會在兩頭添加新的引號,而原來的引號會被轉義。

    將上面的例子補充完整:
    1. #include
    2. #define STR(s) #s
    3. int main() {
    4. printf("%s\n", STR(c.biancheng.net));
    5. printf("%s\n", STR("c.biancheng.net"));
    6. return 0;
    7. }
    運行結果:
    c.biancheng.net
    "c.biancheng.net"

    ##的用法

    ##稱為連接符,用來將宏參數或其他的串連接起來。例如有如下的宏定義:
    #define CON1(a, b) a##e##b
    #define CON2(a, b) a##b##00
    那麼:
    printf("%f\n", CON1(8.5, 2));
    printf("%d\n", CON2(12, 34));
    將被展開為:
    printf("%f\n", 8.5e2);
    printf("%d\n", 123400);
    將上面的例子補充完整:
    1. #include
    2. #define CON1(a, b) a##e##b
    3. #define CON2(a, b) a##b##00
    4. int main() {
    5. printf("%f\n", CON1(8.5, 2));
    6. printf("%d\n", CON2(12, 34));
    7. return 0;
    8. }
    運行結果:
    850.000000
    123400

    6.C語言中幾個預定義宏 顧名思義,預定義宏就是已經預先定義好的宏,我們可以直接使用,無需再重新定義。

    ANSI C 規定了以下幾個預定義宏,它們在各個編譯器下都可以使用:
      __LINE__:表示當前源代碼的行號;__FILE__:表示當前源文件的名稱;__DATE__:表示當前的編譯日期;__TIME__:表示當前的編譯時間;__STDC__:當要求程序嚴格遵循ANSI C標准時該標識被賦值為1;__cplusplus:當編寫C++程序時該標識符被定義。
      預定義宏演示:
      1. #include
      2. #include
      3. int main() {
      4. printf("Date : %s\n", __DATE__);
      5. printf("Time : %s\n", __TIME__);
      6. printf("File : %s\n", __FILE__);
      7. printf("Line : %d\n", __LINE__);
      8. system("pause");
      9. return 0;
      10. }
      VS下的輸出結果:
      Date : Mar 6 2016
      Time : 11:47:15
      File : main.c
      Line : 8

      C-Free 5.0 下的輸出結果:
      Date : Mar 6 2016
      Time : 12:12:59
      File : C:\Users\mozhiyan\Desktop\demo.c
      Line : 8

      7.C語言條件編譯 預處理程序提供了條件編譯的功能,可以按不同的條件去編譯不同的程序部分,因而產生不同的目標代碼文件。這對於程序的移植和調試是很有用的。條件編譯有三種形式,下面分別介紹。

      第一種形式

      第一種形式的格式為:
      #ifdef 標識符
      程序段1
      #else
      程序段2
      #endif

      它的功能是,如果標識符已被 #define 命令定義過則對程序段1進行編譯;否則對程序段2進行編譯。如果沒有程序段2(它為空),本格式中的#else可以沒有,即可以寫為:
      #ifdef 標識符
      程序段
      #endif

      請看下面的例子:
      1. #include
      2. #define WIN16 true
      3. int main(void){
      4. #ifdef WIN16
      5. printf("The value of sizeof(int) is 2.\n");
      6. #else
      7. printf("The value of sizeof(int) is 4.\n");
      8. #endif
      9. return 0;
      10. }
      運行結果:
      The value of sizeof(int) is 2.

      第4行插入了條件編譯預處理命令,要根據 WIN16 是否被定義過來決定編譯哪一個 printf 語句。而在程序的第2行已對 WIN16 作過宏定義,所以應對第一個 printf 語句進行編譯。

      程序第2行宏定義中,定義 WIN16 表示字符串 true,其實也可以為任何字符串,甚至不給出任何字符串,寫為:
      #define WIN16
      也具有同樣的意義。只有取消程序的第2行才會去編譯第二個 printf 語句。

      第二種形式

      第二種形式的格式為:
      #ifndef 標識符
      程序段1
      #else
      程序段2
      #endif

      與第一種形式的區別是將ifdef改為ifndef。它的功能是,如果標識符未被#define命令定義過則對程序段1進行編譯,否則對程序段2進行編譯。這與第一種形式的功能正相反。

      第三種形式

      第三種形式的格式為:
      #if 常量表達式
      程序段1
      #else
      程序段2
      #endif

      它的功能是,如常量表達式的值為真(非0),則對程序段1 進行編譯,否則對程序段2進行編譯。因此可以使程序在不同條件下,完成不同的功能。

      請看下面的例子:
      1. #include
      2. #define R 1
      3. int main(){
      4. float len, area_round, area_square;
      5. printf ("input a number: ");
      6. scanf("%f", &len);
      7. #if R
      8. area_round = 3.14159*len*len;
      9. printf("Area of round is: %f\n", area_round);
      10. #else
      11. area_square = len*len;
      12. printf("Area of square is: %f\n", area_square);
      13. #endif
      14. return 0;
      15. }
      運行結果:
      input a number: 4
      Area of round is: 50.265442

      第2行宏定義中,定義R為1,因此在條件編譯時,常量表達式的值為真,所以計算並輸出圓面積。

      上面介紹的條件編譯當然也可以用條件語句 if-else 來實現。 但是用條件語句將會對整個源程序進行編譯,生成的目標代碼程序較長,而采用條件編譯,則根據條件只編譯其中的程序段1或程序段2,生成的目標程序較短。如果條件選擇的程序段很長,采用條件編譯的方法是十分必要的。

      8.C語言#error命令,阻止程序編譯 #error 指令用於在編譯期間產生錯誤信息,並阻止程序的編譯,其形式如下:
      #error error_message
      例如,我們的程序針對Linux編寫,不保證兼容Windows,那麼可以這樣做:
      1. #ifdef WIN32
      2. #error This programme cannot compile at Windows Platform
      3. #endif
      WIN32 是Windows下的預定義宏。當用戶在Windows下編譯該程序時,由於定義了WIN32這個宏,所以會執行#error命令,提示用戶發生了編譯錯誤,錯誤信息是:

      This programme cannot compile at Windows Platform

      這和發生語法錯誤的效果是一樣的,程序編譯失敗。請看下面的截圖: \
      VS2010 下的錯誤信息

      \
      C-Free 5.0 下的錯誤信息
      需要注意的是:報錯信息不需要加引號" ",如果加上,引號會被一起輸出。例如將上面的#error命令改為:
      #error "This programme cannot compile at Windows Platform"
      那麼錯誤信息如下:
      \

      再如,當我們希望以C++的方式來編譯程序時,可以這樣做:
      復制純文本新窗口
      1. #ifndef __cplusplus
      2. #error 當前程序必須以C++方式編譯
      3. #endif

      9.C語言預處理指令總結 預處理指令是以#號開頭的代碼行,#號必須是該行除了任何空白字符外的第一個字符。#後是指令關鍵字,在關鍵字和#號之間允許存在任意個數的空白字符,整行語句構成了一條預處理指令,該指令將在編譯器進行編譯之前對源代碼做某些轉換。

      下面是本章涉及到的部分預處理指令:
      指令 說明 # 空指令,無任何效果 #include 包含一個源代碼文件 #define 定義宏 #undef 取消已定義的宏 #if 如果給定條件為真,則編譯下面代碼 #ifdef 如果宏已經定義,則編譯下面代碼 #ifndef 如果宏沒有定義,則編譯下面代碼 #elif 如果前面的#if給定條件不為真,當前條件為真,則編譯下面代碼 #endif 結束一個#if……#else條件編譯塊
      預處理功能是C語言特有的功能,它是在對源程序正式編譯前由預處理程序完成的,程序員在程序中用預處理命令來調用這些功能。

      宏定義可以帶有參數,宏調用時是以實參代換形參,而不是“值傳送”。

      為了避免宏代換時發生錯誤,宏定義中的字符串應加括號,字符串中出現的形式參數兩邊也應加括號。

      文件包含是預處理的一個重要功能,它可用來把多個源文件連接成一個源文件進行編譯,結果將生成一個目標文件。

      條件編譯允許只編譯源程序中滿足條件的程序段,使生成的目標程序較短,從而減少了內存的開銷並提高了程序的效率。

      使用預處理功能便於程序的修改、閱讀、移植和調試,也便於實現模塊化程序設計。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved