<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                本文目錄 - [預處理指令簡介](http://www.cnblogs.com/mjios/archive/2013/03/20/2969817.html#label0) - [一、不帶參數的宏定義](http://www.cnblogs.com/mjios/archive/2013/03/20/2969817.html#label1) - [二、帶參數的宏定義](http://www.cnblogs.com/mjios/archive/2013/03/20/2969817.html#label2) 說明:這個C語言專題,是學習iOS開發的前奏。也為了讓有面向對象語言開發經驗的程序員,能夠快速上手C語言。如果你還沒有編程經驗,或者對C語言、iOS開發不感興趣,請忽略 [回到頂部](http://www.cnblogs.com/mjios/archive/2013/03/20/2969817.html#labelTop) ### 預處理指令簡介 1.C語言在對源程序進行編譯之前,會先對一些特殊的預處理指令作解釋(比如之前使用的#include文件包含指令),產生一個新的源程序(這個過程稱為編譯預處理),之后再進行通常的編譯 2.為了區分預處理指令和一般的C語句,所有預處理指令都以符號"#"開頭,并且結尾不用分號 3.預處理指令可以出現在程序的任何位置,它的作用范圍是從它出現的位置到文件尾。習慣上我們盡可能將預處理指令寫在源程序開頭,這種情況下,它的作用范圍就是整個源程序文件 4.C語言提供的預處理指令主要有:宏定義、文件包含、條件編譯 這一講先介紹一下宏定義,宏定義可以分為2種:不帶參數的宏定義 和 帶參數的宏定義。 [回到頂部](http://www.cnblogs.com/mjios/archive/2013/03/20/2969817.html#labelTop) ### 一、不帶參數的宏定義 ### 1.一般形式 #define?宏名?字符串 比如#define ABC 10 右邊的字符串也可以省略,比如#define ABC ### 2.作用 它的作用是在編譯預處理時,將源程序中所有"宏名"替換成右邊的"字符串",常用來定義常量。 接下來寫個程序根據圓的半徑計算周長 ~~~ 1 #include <stdio.h> 2 3 // 源程序中所有的宏名PI在編譯預處理的時候都會被3.14所代替 4 #define PI 3.14 5 6 // 根據圓的半徑計radius算周長 7 float girth(float radius) { 8 return 2 * PI *radius; 9 } 10 11 int main () 12 { 13 float g = girth(2); 14 15 printf("周長為:%f", g); 16 return 0; 17 } ~~~ 在第4行定義了一個叫PI的宏,在編譯預處理之后,第8行中的2 * PI *radius就會變成2 * 3.14 * radius。 輸出結果:![](https://box.kancloud.cn/2016-05-07_572d7677eda07.png) ### 3.使用習慣與注意 1> 宏名一般用大寫字母,以便與變量名區別開來,但用小寫也沒有語法錯誤 2> 對程序中用雙引號擴起來的字符串內的字符,不進行宏的替換操作。比如: ~~~ 1 #define R 10 2 int main () 3 { 4 char *s = "Radio"; 5 return 0; 6 } ~~~ 在第1行定義了一個叫R的宏,但是第4行中"Radio"里面的'R'并不會被替換成10 3> 在編譯預處理用字符串替換宏名時,不作語法檢查,只是簡單的字符串替換。只有在編譯的時候才對已經展開宏名的源程序進行語法檢查 ~~~ 1 #define I 100 2 int main () 3 { 4 int i[3] = I; 5 return 0; 6 } ~~~ 在做編譯預處理的時候,不管語法對不對,第4行的I都會被替換為100。不過在編譯的時候就會報第4行的錯。 4> 宏名的有效范圍是從定義位置到文件結束。如果需要終止宏定義的作用域,可以用#undef命令 ~~~ 1 #define PI 3.14 2 /* 3 . 4 . 5 . 6 . 7 */ 8 #undef PI ~~~ PI這個宏在第1行到第8行之間是有效的,第8行后就無效了 5> 定義一個宏時可以引用已經定義的宏名 ~~~ #define R 3.0 #define PI 3.14 #define L 2*PI*R #define S PI*R*R ~~~ [回到頂部](http://www.cnblogs.com/mjios/archive/2013/03/20/2969817.html#labelTop) ### 二、帶參數的宏定義 ### 1.一般形式 #define?宏名(參數列表) 字符串 ### 2.作用 在編譯預處理時,將源程序中所有宏名替換成字符串,并且將 字符串中的參數 用 宏名右邊參數列表 中的參數替換 ~~~ 1 #include <stdio.h> 2 3 #define average(a, b) (a+b)/2 4 5 int main () 6 { 7 int a = average(10, 4); 8 9 printf("平均值:%d", a); 10 return 0; 11 } ~~~ 第3行中定義了一個帶有2個參數的宏average,第7行其實會被替換成:int?a = (10 +?4)/2;,輸出結果為:![](https://box.kancloud.cn/2016-05-07_572d76780a992.png) 。是不是感覺這個宏有點像函數呢? ### 3.使用注意 1> 宏名和參數列表之間不能有空格,否則空格后面的所有字符串都作為替換的字符串 ~~~ 1 #define average (a, b) (a+b)/2 2 3 int main () 4 { 5 int a = average(10, 4); 6 return 0; 7 } ~~~ 注意第1行的宏定義,宏名average跟(a, b)之間是有空格的,于是,第5行就變成了這樣: ~~~ int a = (a, b) (a+b)/2(10, 4); ~~~ 這個肯定是編譯不通過的 2>?帶參數的宏在展開時,只作簡單的字符和參數的替換,不進行任何計算操作。所以在定義宏時,一般用一個小括號括住字符串的參數。 下面定義一個宏D(a),作用是返回a的2倍數值: - 如果定義宏的時候不用小括號括住參數 - ~~~ 1 #include <stdio.h> 2 3 #define D(a) 2*a 4 5 int main () 6 { 7 int b = D(3+4); 8 9 printf("%d", b); 10 return 0; 11 } ~~~ 第7行將被替換成int?b = 2*3+4;,輸出結果:![](https://box.kancloud.cn/2016-05-07_572d76781a417.png) - 如果定義宏的時候用小括號括住參數,把上面的第3行改成: ~~~ #define D(a) 2*(a) ~~~ 注意右邊的a是有括號的,第7行將被替換成int?b = 2*(3+4);,輸出結果:![](https://box.kancloud.cn/2016-05-07_572d76782b609.png) 3> 計算結果最好也用括號括起來 下面定義一個宏P(a),作用是返回a的平方: - 如果不用小括號括住計算結果 ~~~ 1 #include <stdio.h> 2 3 #define Pow(a) (a) * (a) 4 5 int main(int argc, const char * argv[]) { 6 int b = Pow(10) / Pow(2); 7 8 printf("%d", b); 9 return 0; 10 } ~~~ 注意第3行,沒有用小括號擴住計算結果,只是括住了參數而已。第6行代碼被替換為: ~~~ int b = (10) * (10) / (2) * (2); ~~~ 簡化之后:int?b = 10 * (10 / 2) * 2;,最后變量b為:![](https://box.kancloud.cn/2016-05-07_572d76783bd9d.png) - 如果用小括號括住計算結果 將上面的第3行代碼改為: ~~~ #define Pow(a) ( (a) * (a) ) ~~~ 那么第6行被替換為: ~~~ int b = ( (10) * (10) ) / ( (2) * (2) ); ~~~ 簡化之后:int?b = (10 * 10) / (2 * 2);,最后輸出結果:![](https://box.kancloud.cn/2016-05-07_572d76784b820.png) 。這個才是我們想要的結果。 也就意味著前面的#define average(a, b) (a+b)/2應該寫成#define average(a, b) (((a)+(b))/2) ### 5.與函數的區別 從整個使用過程可以發現,帶參數的宏定義,在源程序中出現的形式與函數很像。但是兩者是有本質區別的: 1>?宏定義不涉及存儲空間的分配、參數類型匹配、參數傳遞、返回值問題 2>?函數調用在程序運行時執行,而宏替換只在編譯預處理階段進行。所以帶參數的宏比函數具有更高的執行效率
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看