C語言進階【宏定義】編譯預處理#define

C語言學習筆記

之  編譯預處理與宏定義 ide

  宏是編譯預處理的重要定義,宏定義就像基本數據類型定義同樣,能夠看做是一種類型,與基本類型不一樣的是,宏與函數有着密切的類似之處,可是宏是編譯時發生做用。 函數

一:不帶參數的宏定義

1. 通常格式: 學習

       #define  標識符  字符串  標識符即爲這個字符串的宏名 spa


2. 宏調用:程序中用宏名代替字符串。 blog

 宏展開:預編譯時將字符串代替宏名的過程。 圖片

 好比:#define  PI 3.14 內存

  這裏的PI就是宏名,他表明的是字符串3.14,預編譯時將源程序中的全部宏名PI出現的位置都用字符串3.14來替換。好比: 程序中出現PI*5,它的結果其實是 3.14*5 作用域


(1)宏名用大寫,用來區分普通變量 字符串


(2)宏定義不能以分號結束,不然分號將做爲字符串的一部分參加宏展開。好比:       get

#define PI 3.1415; //結尾加了分號

a=PI*r*r;

在編譯預處理時,將宏展開: a=3.1415;*r*r   分號將做爲字符串參加運算,很明顯是錯誤的


(3)宏定義只是用來替換字符串的。 無論字符串是什麼數據類型,總之就是一句話,宏名替換字符串,宏名替換的必定是字符串,即便上述中的3.1415寫成了3.1W15。替換後的結果依然是a=3.1W15*r*r


(4)#define命令定義的宏名範圍是從定義命令開始直到源程序文件結束,並且#define定義在文件開頭與函數之間。 若是要想提早結束宏定義的做用域,能夠經過#undef終止宏名的做用域


(5)宏定義中能夠出現已經定義的宏名,能夠層層置換。

    若宏名中 出現一個被雙引號括起來的字符串中時,將不會產生宏替換

   好比:


#include <stdio.h>
/*宏定義在文件頭和函數之間*/
#define R 3.0
#define PI 3.1415926
#define L 2*PI*R  //出現了前面已經定義的PI和R
#define S PI*R*R   //出現了前面已經定義的PI和
main()
{
   /*
   當L和S在「」以內時將不會與宏定義產生聯繫,即不會發生替換
   當L和S不在「」以內時,L將被替換成 2*PI*R,S將被替換成 PI*R*R
*/
printf("L=%7.2f\nS=%7.2f\n",L,S);
}


  最後須要注意的是: 宏定義是專用於預處理的一個名詞,它的做用就是替換,不分配空間

二:帶參數的宏定義

 通常格式:

       #define  宏名(參數表)   字符串

  帶參數的宏定義並不單單是宏名代換字符串,還要進行參數的替換,相似於函數的調用

 好比:

#define S(a,b) a*b

area=S(3,2);

 S爲宏名,ab爲形參,程序中調用S32),把實參32分別替換形參ab,因此宏展開是area=3*2;

 好比:


#include <stdio.h>
/*宏定義在文件頭和函數之間*/
#define S(a,b) a*b   //須要注意的是S和()之間不能有空格
main()
{
int area;
area=S(2,3);//傳遞給宏S(a,b),而後替換爲a*b
printf("area=%d\n",area);
}


1上述程序中的參數傳遞應該很好理解,可是若是把程序改動一下,讓實參的值變成S(2+3,3+4), 你們確定會認爲是35,可是真的是35嗎? 咱們看一下:


#include <stdio.h>
/*宏定義在文件頭和函數之間*/
#define S(a,b) a*b   //須要注意的是S和()之間不能有空格
main()
{
int area;
area=S(2+3,3+4);
printf("area=%d\n",area);
}


 居然是15,並非咱們想象中的35,怎麼回事呢?  實際上S(2+3,3+4)傳遞過去後,它的紅替換是 area=2+3*3+4,這下你們明白了吧。仍是一句話,宏定義只是用來替換的,完徹底全的原樣的替換。那要怎麼解決這個問題呢?很簡單,在宏定義的時候加上一個括號就能夠了,看程序:


#include <stdio.h>
/*宏定義在文件頭和函數之間*/
#define S(a,b) (a)*(b)   //須要注意的是S和()之間不能有空格
main()
{
int area;
area=S(2+3,3+4);//傳遞給宏S(a,b),而後替換爲a*b
printf("area=%d\n",area);
}


(2)宏定義的宏調用與函數調用的區別

  在學習了帶參數的宏定義後,是否是以爲這個調用與函數的調用很類似,可是它們徹底是不通的兩個概念:

  函數調用時,先求出實參表達式的值,再將該值傳遞個形參,而帶參數的宏調用只是進行替換,簡單的字符替換

  函數調用是在程序運行時處理,分配給形參臨時內存單元,而宏展開則在編譯時進行的,展開的時並不給形參分配內存單元,不進行值傳遞,也沒有返回值

相關文章
相關標籤/搜索