亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

C語言

C語言#define的用法

時間:2024-08-19 19:01:20 C語言 我要投稿
  • 相關(guān)推薦

C語言#define的用法

  引導語:預處理器是在真正的編譯開始之前由編譯器調(diào)用的獨立程序。以下是百分網(wǎng)小編分享給大家的C語言#define的用法,歡迎閱讀!

  #define的用法

  #define 是一個預處理指令,這個預處理執(zhí)行可以定義宏。與所有預處理指令一樣,預處理指令#define用#符號作為行的開頭。預處理指令從#開始,到其后第一個換行符為止。也就是說,指令的長度限于一行代碼。如果想把指令擴展到幾個物理行,可使用反斜線后緊跟換行符的方法實現(xiàn),該出的換行符代表按下回車鍵在源代碼文件中新起一行所產(chǎn)生的字符,而不是符號 \n 代表的字符。在預處理開始錢,系統(tǒng)會刪除反斜線和換行符的組合,從而達到把指令擴展到幾個物理行的效果。可以使用標準C注釋方法在#define行中進行注釋。

  //使用反斜線+回車

  #define OW "hello\

  world!" /*注意第二行要左對齊*/

  每一個#define行由三部分組成:

  第一部分,指令#deine自身。

  第二部分,所選擇的縮略語,這些縮略語稱為宏(分為對象宏和函數(shù)宏)。宏的名字中不允許有空格,而且必須遵循C變量命名規(guī)則:只能使用字母、數(shù)字和下劃線(_),第一個字符不能為數(shù)字。習慣上宏名用大寫字母表示,以便于與變量區(qū)別。但也允許用小寫字母。

  第三部分,(#define行的其余部分)稱為替換列表或主體。

  注意,結(jié)尾沒有分號

  下面來看一個例子:

  #include

  #define OW 2 * 2

  #define OW 2 * 2

  //#undef OW 需要先取消宏定義

  #define OW 2*2

  int main (void)

  {

  printf ("%d\n", OW);

  return 0;

  }

  輸出結(jié)果:

  define.c:5:0: 警告: “OW”重定義 [默認啟用]

  define.c:4:0: 附注: 這是先前定義的位置

  相同定義意味著主體具有相同順序的語言符號。因此,下面兩個定義相同:

  #define OW 2 * 2

  #define OW 2 * 2

  兩者都有三個相同的語言符號,而且額外的空格不是主體的一部分。下面的定義則被認為是不同的:

  #define OW 2*2

  上式只有一個(而非三個)語言符號,因此與前面兩個定義不同。可以使用#undef指令重新定義宏。

  宏所代表的數(shù)字可以在編譯命令中指定(使用-D選項)

  /*

  宏演示

  */

  #include

  int main()

  {

  int num=0;

  int arr[SIZE]={}; //使用gcc -D可以宏定義這個數(shù)字

  for(num = 0;num <= SIZE - 1;num++)

  {

  arr[num]=num;

  printf("%d ",arr[num]);

  }

  printf("\n");

  return 0;

  }

  gcc -DSIZE=4 define.c

  輸出結(jié)果:

  0 1 2 3

  函數(shù)宏:

  通過使用參數(shù),可以創(chuàng)建外形和作用都與函數(shù)相似的類函數(shù)宏。宏的參數(shù)也用圓括號括起來。類函數(shù)宏的定義中,用圓括號括起來一個或多個參數(shù),隨后這些參數(shù)出現(xiàn)在替換部分。

  #include

  #define SQUARE(X) X*X

  #define PR(X) printf ("The result is %d\n", X)

  int main (void)

  {

  int x = 4;

  int z;

  printf ("x = %d\n", x);

  z = SQUARE(x);

  printf ("Evaluating SQUARE(x): ");

  PR(z);

  z = SQUARE(2);

  printf ("Evaluating SQUARE(2): ");

  PR(z);

  printf ("Evaluating 100/SQUARE(2): ");

  PR(100/SQUARE(2));

  z = SQUARE(x+2);

  printf ("Evaluating SQUARE(x+2): ");

  PR(z);

  printf ("x is %d\n", x);

  z = SQUARE(++x);

  printf ("Eavluating SQUARE(++x): ");

  PR(SQUARE (++x));

  printf ("After incrementing, x is %x\n", x);

  return 0;

  }

  輸出結(jié)果:

  x = 4

  Evaluating SQUARE(x): The result is 16

  Evaluating SQUARE(2): The result is 4

  Evaluating 100/SQUARE(2): The result is 100

  Evaluating SQUARE(x+2): The result is 14

  x is 4

  Eavluating SQUARE(++x): The result is 36

  After incrementing, x is 6

  SQUARE(x+2) 輸出結(jié)果是14,而不是想要的6*6 = 36。這是因為預處理器不進行計算,而只進行字符串替換。在出現(xiàn)x的地方,預處理都用字符串 x+2進行替換。x*x 變?yōu)?x+2*x+2 根據(jù)運算符優(yōu)先級,則結(jié)果為 14

  100/SQUARE(2)輸出結(jié)果是 100,而不是想要的 25。因為,根據(jù)優(yōu)先級規(guī)則,表達式是從左到右求值的。

  100/2*2 = 100

  要處理前面兩個示例中的情況,需要如下定義:

  #define SQUARE(x) ((x) * (x))

  從中得到的經(jīng)驗是使用必須的足夠多的圓括號來保證以正確的順序進行運行和結(jié)合。

  SQUARE(++x) 根據(jù)編譯器的不同會出現(xiàn)兩種不同的結(jié)果。解決這個問題的最簡單的方法是避免在宏的參數(shù)中使用++x。一般來說,在宏中不要使用增量或減量運算符。

  參看:C 語言再學習 -- 運算符與表達式

  利用宏參數(shù)創(chuàng)建字符串:#運算符

  在類函數(shù)宏的替換部分中,#符號用作一個預處理運算符,它可以把語言符號轉(zhuǎn)化為字符串。

  例如:如果x是一個宏參量,那么#x可以把參數(shù)名轉(zhuǎn)化為相應的字符串。該過程稱為字符串化。

  #include

  #define PSQR(x) printf ("The square of " #x" is %d\n", ((x)*(x)))

  int main (void)

  {

  int y = 2;

  PSQR (y);

  PSQR (2 + 4);

  return 0;

  }

  輸出結(jié)果:

  The square of y is 4

  The square of 2 + 4 is 36

  #include

  #include

  #define VEG(n) #n

  int main()

  {

  char str[20];

  strcpy(str,VEG(num));//num

  printf("%s\n",str);//拷貝

  return 0;

  }

  輸出結(jié)果:

  num

  預處理器的粘合劑:##運算符

  和#運算符一樣,##運算符可以用于類函數(shù)宏的替換部分。另外,##還可用于類對象宏的替換部分。這個運算符把兩個語言符號組合成單個語言符號。

  #include

  #define XNAME(n) x##n

  #define PRINT_XN(n) printf ("x"#n" = %d\n", x##n)

  int main (void)

  {

  int XNAME (1) = 14; //變?yōu)?int x1 = 14;

  int XNAME (2) = 20; //變?yōu)?int x2 = 20;

  PRINT_XN (1); //變?yōu)?printf ("x1 = %d\n", x1);

  PRINT_XN (2); //變?yōu)?printf ("x2 = %d\n", x2);

  return 0;

  }

  輸出結(jié)果:

  x1 = 14

  x2 = 20

  宏用于簡單函數(shù):

  #include

  #define MAX(x,y) ((x)>(y) ? (x) : (y)) /*比較大小*/

  #define ABS(x) ((x) < 0 ? -(x) : (x)) /*絕對值*/

  #define ISSIGN(x) ((x) == '+' || (x) == '-' ? 1 : 0) /*正負號*/

  int main()

  {

  printf ("較大的為: %d\n", MAX(5,3));

  printf ("絕對值為: %d\n", ABS (-2));

  printf ("正負號為: %d\n", ISSIGN ('+'));

  return 0;

  }

  輸出結(jié)果:

  較大的為: 5

  絕對值為: 2

  正負號為: 1

  下面是需要注意的幾點:

  1、宏的名字中不能有空格,但是在替代字符串中可以使用空格。ANSI C 允許在參數(shù)列表中使用空格。

  2、用圓括號括住每個參數(shù),并括住宏的整體定義。

  3、用大寫字母表示宏函數(shù)名,便于與變量區(qū)分。

  4、有些編譯器限制宏只能定義一行。即使你的編譯器沒有這個限制,也應遵守這個限制。

  5、宏的一個優(yōu)點是它不檢查其中的變量類型,這是因為宏處理字符型字符串,而不是實際值。

  面試:用預處理指令#define 聲明一個常數(shù),用以表明1年中有多少秒(忽略閏年問題)

  #define SEC (60*60*24*365)UL

  考察內(nèi)容:

  1、懂得預處理器將為你計算常量表達式的值,因此,可直接寫出你是如何計算一年中有多少秒而不是計算出實際的值,這樣更清晰而沒有代價。

  2、意識到這個表達式將使一個16 位機的整形數(shù)溢出,因此要用到長整形符號 L ,告訴編譯器這個常數(shù)是長整形數(shù)。

  3、如果你在你的表達式中用到UL(表示無符號長整型),那么你有了一個好的起點。

  面試:寫一個“標準”宏MIN ,這個宏輸入兩個參數(shù)并返回較小的一個

  #define MIN(A,B) ((A) <= (B) ? (A) : (B))

  考察內(nèi)容:

  1、三目表達式的使用

  2、使用必須的足夠多的圓括號來保證以正確的順序進行運行和結(jié)合

  3、進一步討論,在宏中不要使用增量或減量運算符

  參看:宏名必須用大寫字母嗎?

  研究:C語言中用宏定義(define)表示數(shù)據(jù)類型和用typedef定義數(shù)據(jù)類型有什么區(qū)別?

  宏定義只是簡單的字符串代換,是在預處理完成的,而typedef是在編譯時處理的,它不是作簡單的代換,而是對類型說明符重新命名。被命名的標識符具有類型定義說明的功能。

  請看下面的例子:

  #define P1 int *

  typedef (int *) P2

  從形式上看這兩者相似,但在實際使用中卻不相同。

  下面用P1、P2說明變量時就可以看出它們的區(qū)別:

  P1 a, b; 在宏代換后變成: int *a, b; 表示 a 是指向整型的指針變量,而 b 是整型變量。

  P2 a, b; 表示a,b都是指向整型的指針變量。因為PIN2是一個類型說明符。

  由這個例子可見,宏定義雖然也可表示數(shù)據(jù)類型, 但畢竟是作字符代換。在使用時要分外小心,以避出錯。

  總結(jié),typedef和#define的不同之處:

  1、與#define不同,typedef 給出的符號名稱僅限于對類型,而不是對值。

  2、typedef 的解釋由編譯器,而不是是處理器執(zhí)行。

  3、雖然它的范圍有限,但在其受限范圍內(nèi),typedef 比 #define 更靈活。

  用于定義字符串,尤其是路徑

  A),#define ENG_PATH_1 E:\English\listen_to_this\listen_to_this_3

  B),#define ENG_PATH_2 “ E:\English\listen_to_this\listen_to_this_3”

  A 為 定義路徑, B 為定義字符串

  C), #define ENG_PATH_3 E:\English\listen_to_this\listen\

  _to_this_3

  還沒發(fā)現(xiàn)問題?這里用了 4 個反斜杠,到底哪個是接續(xù)符?回去看看接續(xù)符反斜杠。反斜杠作為接續(xù)符時,

  在本行其后面不能再有任何字符,空格都不行。所以,只有最后一那給 ENG_PATH_1 加上雙引號不就成了:“ENG_PATH_1”。但是請注意:有的系統(tǒng)里規(guī)定路徑的要用雙反斜杠“ \\” ,比如:

  #define ENG_PATH_4 E:\\English\\listen_to_this\\listen_to_this_3

【C語言#define的用法】相關(guān)文章:

C語言for語句用法詳解11-19

c語言問號冒號的用法01-08

c語言大括號的用法11-28

c語言中time函數(shù)的用法03-20

C語言預定義宏用法03-30

C語言中strpbr()函數(shù)的用法03-19

C語言assert的用法有哪些04-02

c語言位運算符的用法指導12-04

C語言學習中的指針用法教程04-01