C語言中#define定義的標識符和宏實例代碼

📢1.#define定義標識符

在C語言程序中,有時候會包含#define

#define可以定義標識符

也就是說可以對字符重新定義,實現代替的作用

📢語法

#define  name  stuff 

就比如說:

#define MAX 1000(用MAX代替1000)

#define reg   register (用reg代替register)

📢舉個栗子

#include<stdio.h>
#define MAX 100
int main()
{
	printf("%d", MAX);
	return 0;
}

當代碼運行的時候

在代碼編譯的預處理階段 就會把宏替換為文本程序代碼

代替的結果如下:

#include<stdio.h>
int main()
{
	printf("%d", 100);
	return 0;
}

📢註意:#define定義標識符後面盡量不加上分號,因為如果加上的話,在替換的過程中,分號也會別替換到文本程序中,有時候會導致出現邏輯錯誤。

📢2.#define定義宏

#define規定允許將參數替換到文本中,這樣包含參數叫做#define定義宏

宏在程序中,執行的速度更快,因為相對於函數,宏沒有函數的調用和返回的開銷

語法:
#define SQUARE(x)   x*x

這與#define定義宏一樣,都是完成替換的,不過#define定義宏後面有一個括號,包含參數

📢下面用#define定義宏來實現兩個數求最大值

#include<stdio.h>
#define MAX(x,y) ((x)>(y)?(x):(y))
int main()
{
	int a = 20;
	int b = 10;
	int c = MAX(a,b);
	printf("%d", c);
	return 0;
}

替換後的結果為:

#include<stdio.h>
int main()
{
	int a = 20;
	int b = 10;
	int c = a>b?a:b;
	printf("%d", c);
	return 0;
}

 在#define定義宏的時候,後面的參數盡量帶上括號,使每一個參數相對獨立

這樣可以避免由於操作符的優先級不同,導致最終的邏輯就錯瞭

舉個栗子:

#include<stdio.h>
#define sum(x) x*x
int main()
{
	int ret = sum(3 + 3);
	printf("%d", ret);
}

如果不仔細觀察的話,可能你認為的結果就是36

這個代碼的計算過程為:3+3*3+3,並不是(3+3)*(3+3)

📢#define替換的規則

#define定義標識符和宏時,程序會繼續如下步驟

1.在定義宏時,先對參數進行檢查,如果參數裡包含有#define定義的標識符時,首先完成相應的替換

 

2.替換文本會隨後插入到原來文本文件中,對於宏來說,參數名被他們的值所替換

 

3.最後進行檢查,果然還有#define定義的符號,將重復上述的操作

 註意:

1.#define參數中可以包含其他由#define定義的標識符,但是#define不能遞歸

2.如果#define的參數名存在在字符串中,將不會完成替換

📢#與## #的用法:

在不確定參數的情況下,可以使用 “#n” ,可以實現不同字符串的插入

效果如下:

#include<stdio.h>
#define PRINT(n) printf("the value of "#n" is %d\n",n);
int main()
{
	int a = 10;
	PRINT(a);
	int b = 20;
	PRINT(b);
    int c= 30;
    PRINT(c);
	return 0;
}

📢替換後的效果為:

#include<stdio.h>
int main()
{
	int a = 10;
    printf("the value of" "a" " is %d\n",a);
	PRINT(a);
	int b = 20;
	PRINT(b);
    printf("the value of " "b" " is %d\n",b);
    int c= 30;
    PRINT(c);
    printf("the value of " "c" " is %d\n",c);
	return 0;
} 

##的用法:

#include<stdio.h>
#define CAT(Max,num) Max##nu
int main()
{
	int Maxnum = 100;
	printf("%d", Maxnum);
	return 0;
}

雙##的用法可以拼接兩個字符串

當然這個前提是拼接後的字符串必須產生一個合法的標識符,否則結果就是未定義的

📢宏的缺點

 1.如果使用宏過多,宏定義的代碼插入到程序中,會大幅度增加程序的長度

2.宏是沒法調試的

3.宏與類型無關,導致程序不夠嚴謹

4.宏會帶來優先級的問題,容易導致程序的錯誤

 📢宏和函數的優缺點      

1).在代碼長度角度上,因為宏是直接替換所以若宏較長會增加代碼長度

2).在執行速度上,宏較函數快,因為函數存在調用/返回時的額外開銷

3).在參數求值方面,define定義的宏可能會具有副作用會導致修改變量最後的值,而函數即使調用多次也不會修改變量原來的值

4).在參數類型方面,宏與類型無關,所以宏是可以傳參數的而函數不行在C中函數是不可以傳類型的

 5).在是否可調試方面,宏不可調試,函數可調試宏可以傳類型的檢測,實現malloc(動態開辟內存的函數)

#include<stdio.h>
#include<stdlib.h>
#define MALLOC(COUNT,TYPE)\
    (TYPE *)alloc(COUNT*sizeof(TYPE))
void *alloc(int sz)   //宏可以傳類型,函數不可以傳類型
{
    void *p=malloc(sz);
    if(p == NULL)
    {
        printf("out of memory\n");
        exit(EXIT_FAILURE);
    }
    return p;
}
int main()
{
    int i=0;
    int *p=MALLOC(10,int);
    for(i=0;i<10;i++)
    {
        *(p+i)=i;
    }
    for(i=0;i<10;i++)
    {
        printf("%d ",*(p+i));
    }
    free(p);
    system("pause");
    return 0;
}

總結

到此這篇關於C語言中#define定義的標識符和宏的文章就介紹到這瞭,更多相關C語言#define定義標識符和宏內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: