文章目錄
- 前言
- 一、預定義符号
- 二、#define詳解
-
- 1.#define定義辨別符
- 2.#define宏定義
-
- 小結
- 3.define 替換規則
前言
提示:本文将介紹一些預定義符号和#define宏定義,宏與函數的優缺點對比等。
一、預定義符号
__FILE__ //進行編譯的源檔案
__LINE__ //檔案目前的行号
__DATE__ //檔案被編譯的日期
__TIME__ //檔案被編譯的時間
__STDC__ //如果編譯器遵循ANSI C,其值為1,否則未定義
這些預定義符号都是語言内置的。
舉個栗子:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
printf("file:%s line:%d\n", __FILE__, __LINE__);
return 0;
}
列印結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLxImYjJjZ4cTY1UGZlZWO5IjN2QTOyADZlZmY0Y2NwE2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
二、#define詳解
1.#define定義辨別符
舉個栗子:
#define MAX 1000 //将1000指派給MAX
#define reg register //為register這個關鍵字,建立一個更簡短的名字
#define do_forever for(;;) //用更形象的符号來替換一種實作
#define CASE break; case //在寫case自動把break打上
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
data:%s\ttime:%s\n",\
_FILE_,LINE_, \
_DATA_,_TIME_)
//如果定義的stuff過長,可以分成幾行寫,除了最後一行,每行的後面都加上一個反斜杠(續航符)
2.#define宏定義
#define機制包括一個規定,允許把參數替換到文本中,這種實作通常稱為宏或者定義和宏
注意:參數清單的左括号必須與name緊鄰;如果兩者之間有任何空白,參數清單就會被解釋為stuff的一部分。
舉個例子:
#define SQUARE(x) x*x
int main()
{
printf("%d\n", SQUARE(5));
return 0;
}
運作結果:
修改一下代碼:
#define SQUARE(x) x*x
int main()
{
printf("%d\n", SQUARE(5+1));
return 0;
}
列印結果:
觀察這段代碼,乍一看你可能覺得這個代碼将列印36這個值,但是列印出來的卻是11,為什麼呢?
替換文本時,參數x被替換成x+1,所有這條語句實際上變成了: printf (“%d\n”,a + 1 * a + 1 );
如何解決呢?
隻需在宏定義上加上兩個括号,即:#define SQUARE(x) (x) * (x)等價于printf (“%d\n”,(a + 1) * (a + 1) );
我們再看另外一個宏定義栗子:
#define DOUBLE(x) (x)+(x)
int main()
{
int x = 5;
printf("%d\n", 10 * DOUBLE(x));
return 0;
}
這将列印什麼值呢?
看上去好像列印100,實際上列印的是55。
我們發現替換之後:
printf (“%d\n”,10 * (5) + (5));乘法運算優先于定義的加法,是以得出55.
解決辦法就是在宏定義表達式兩邊加上一對括号就可以了:
#define DOUBLE( x) ( ( x ) + ( x ) )
小結
是以用于對數值表達式進行求值的宏定義都應該用這種方式加上括号,避免在使用宏時由于參數中的操作符或鄰近操作符之間不可預料的互相作用。
3.define 替換規則
在程式中擴充#define定義符号和宏時,需要涉及幾個步驟:
- 在調用宏時,首先對參數進行檢查,看看是否包含任何由#define定義的符号。如果是,它們首先被替換。
- 替換文本随後被插入到程式中原來文本的位置。對于宏,參數名被他們的值所替換。
- 最後,再次對結果檔案進行掃描,看看它是否包含任何由#define定義的符号。如果是,就重複上述處理過程。
1.宏參數和#define 定義中可以出現其他#define定義的符号。但是對于宏,不能出現遞歸。
2. 當預處理器搜尋#define定義的符号的時候,字元串常量的内容并不被搜尋。