首页
/
每日頭條
/
生活
/
c語言中ifdef的作用
c語言中ifdef的作用
更新时间:2025-12-07 10:45:43
1. 明示常量#define

#define為C語言的一個預處理指令,通常用于進行宏定義。每行#define(邏輯行)一般由以下三部分組成,第一部分是#define指令本身,第二部分為宏,第三部分為稱為替換列表或替換體

c語言中ifdef的作用(詳解C語言中的define)1

預處理器在發現程序中的宏後,會用宏等價的替換體進行替換,如在上圖中,LENGTH 将被替換為100。但值得注意的是雙引号中的宏将不會進行替換。來看下面的一個例子:

c語言中ifdef的作用(詳解C語言中的define)2

輸出的結果将是:

c語言中ifdef的作用(詳解C語言中的define)3

2. 在define中使用參數

在#define中還可以使用參數創建作用與函數類似的類函數宏。帶有參數的宏看上去很像函數,因為這樣的宏也使用圓括号。類函數宏定義的圓括号中可以有一個或多個參數,随後這些參數出現在替換體中,如下圖所示:

c語言中ifdef的作用(詳解C語言中的define)4

首先預處理器将所有出現MEAN(X,Y)的地方都替換為(((X) (Y))/2),然後根據X,Y的值進行計算(注意預處理器不做計算,不求值,隻替換字符序列)。下面我們來看一個例子:

c語言中ifdef的作用(詳解C語言中的define)5

輸出結果為:

c語言中ifdef的作用(詳解C語言中的define)6

前面兩行的結果大家應該都能想到,後面兩行有部分讀者可能會不太明白。還記得我們在上面談到的嘛,“首先預處理器将所有出現square(X)的地方都替換為X*X”。對SQUARE(x 2),将其替換為x 2*x 2,x值為5,由于乘号優先級高于 号,所以結果為17,而非49,要得到正确結果我們應将宏定義寫為:

c語言中ifdef的作用(詳解C語言中的define)7

對100/SQUARE(2),首先将其替換為100/2*2,根據優先級規則,從左往右對表達式求值,結果為100,而非25,要得到宏定義結果我們應将宏定義寫為:

c語言中ifdef的作用(詳解C語言中的define)8

要處理前面的兩種情況,應這樣定義:

c語言中ifdef的作用(詳解C語言中的define)9

盡管如此,仍無法 避免類似SQUARE( x)的情況,這裡不再深入讨論

在上面我們可以看到類函數宏雖然和函數調用看上去相似,但行為卻并不相同,函數調用在程序運行時把參數的值傳遞給函數,宏調用在編譯之前把參數記号傳遞給程序,這兩個不同的過程發生在不同的時期。(務必記得預處理器不做計算,不求值,隻替換字符序列

2.2 用宏參數創建字符串:#運算符

我們在前面提到雙引号字符串中的宏不會被替換,那麼如果我們想要在字符串中包含宏參數該如何做呢?在類函數宏的替換體中,#号作為一個預處理運算符,可以把記号轉換為字符串,如#X将被轉換為”X"。來看一個例子:

c語言中ifdef的作用(詳解C語言中的define)10

輸出結果為:

c語言中ifdef的作用(詳解C語言中的define)11

為什麼呢?調用第一個宏時,X在雙引号中不會被替換,僅替換((X)*(X));調用第二個宏時,#X将被替換為"X",然後由于字符串的串聯特性,"X"将與"The square of "和“is %d\n"組合成"The square of X is %d\n"

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

##運算符把兩個記号組合成一個記号,如:

c語言中ifdef的作用(詳解C語言中的define)12

調用XNAME(n)将轉換為xn,例:

c語言中ifdef的作用(詳解C語言中的define)13

結果為:

c語言中ifdef的作用(詳解C語言中的define)14

2.4 變參宏:...和__VA_ARGS__

通過把宏參數列表中最後的參數寫成省略号(...)來實現宏參數可變,而__VA_ARGS__則出現在替換部分中,表明省略号代表什麼,如:

c語言中ifdef的作用(詳解C語言中的define)15

結果為:

c語言中ifdef的作用(詳解C語言中的define)16

注意:省略号隻能代替最後的宏參數,像下面這樣就是不行的

c語言中ifdef的作用(詳解C語言中的define)17

3. undef指令

#undef指令用于”取消“已定義的#define指令。

假如有如下定義:

c語言中ifdef的作用(詳解C語言中的define)18

通過

c語言中ifdef的作用(詳解C語言中的define)19

将移除上面的定義,然後即可将LENGTH定義為一個新值。即使原來沒有定義LENGTH,取消LENGTH的定義仍然有效。如果想使用一個名稱,又不确定之前是否已經用過,可以用#undef指令取消該名字的定義

4. 條件編譯 4.1 #ifdef、#else和#endif指令

c語言中ifdef的作用(詳解C語言中的define)20

#ifdef指令表示如果預處理器已定義了後面的标識符LENGTH_H,則執行#else(如果有)、#endif指令之前的所有指令并編譯C代碼,如果預處理器未定義标識符LENGTH_H,且有#else指令,則執行#else和#endif指令之間的所有代碼

注意:#else可以沒有,但#endif必須存在

4.2 #ifndef指令

#ifndef指令和#ifdef指令的邏輯相反,#ifndef指令判斷後面的标識符是否是未定義的,常用于定義之前未定義的常量,如:

c語言中ifdef的作用(詳解C語言中的define)21

#ifndef指令也可以和#else、#endif一起使用

通常,包含多個頭文件時,其他的文件可能包含相同的宏定義,#ifndef指令可以防止相同的宏被重複定義。在首次定義一個宏的頭文件中用#ifndef指令激活定義,随後在其他頭文件中的定義都被忽略

#ifndef指令還有一個非常重要的用法,防止多次包含一個文件,讀者也許見過這樣的寫法:

c語言中ifdef的作用(詳解C語言中的define)22

這樣寫是為什麼呢?

首先STACK_H是一個空宏,假如該文件被包含多次,當預處理器首次發現該文件被包含時,STACK_H是未定義的,所以定義STACK_H,并處理該文件的 其他部分,當預處理器第二次發現該文件被包含時,STACK_H是已定義的,預處理器跳過該文件的其他部分

為什麼會多次包含一個文件呢,因為在大型程序中,許多被包含的文件中都包含着其他文件,所以顯示包含的文件中可能包含着已經包含的其他文件。因為在被包含的文件中有某些項(如一些結構類型的聲明)隻能在一個文件中出現一次,這樣就會出錯

通過#ifndef就可以避免重複,因為#ifndef和#endif之間的其他部分在第二次時不會再處理

如何保證像STACK_H這樣待測試的标識符沒有在别處定義呢?通常可以用用大寫的文件名及下劃線和大寫的H做标識符,如STACK就是文件名stack的大寫

(感興趣的讀者可以去看一下我在這篇文章中提的一個關于#ifndef的問題:

關于全局變量被定義在一個被多個.c文件包含的頭文件時出現錯誤)

#if和#elif指令

#if指令和if很像,#if後面跟整型常量表達式,如果表達式非零,則表達式為真,此外可以按照if else的形式使用#elif

如:

c語言中ifdef的作用(詳解C語言中的define)23

#if還有一種用法可以代替#ifdef,即#if defined (VAR)代替#ifdef VAR

#defined是一個預處理運算符(注意不要和#define搞混),如果它的參數是用#define定義過的,返回1,否則返回0,這種方法還可以和#elif一起使用

c語言中ifdef的作用(詳解C語言中的define)24

最後覺得這篇文章對你有幫助的讀者給個點贊加關注吧!

,
Comments
Welcome to tft每日頭條 comments! Please keep conversations courteous and on-topic. To fosterproductive and respectful conversations, you may see comments from our Community Managers.
Sign up to post
Sort by
Show More Comments
推荐阅读
簡曆制作一般用什麼背景的證件照(簡曆上面的證件照怎麼制作)
簡曆制作一般用什麼背景的證件照(簡曆上面的證件照怎麼制作)
  簡曆上面的證件照該怎麼制作呢?很多小夥伴在大學畢業後,就需要找一份工作,而找工作的時候必然需要使用簡曆,簡曆上面是需要放我們的證件照的,而一份合适的證件照會讓HR對我們更好的第一印象,從而也就增加面試成功的幾率。很多小夥伴擔心自己的的證件照尺寸、服飾是否合乎要求,不用擔心,今天給大家分享一個能夠輕松制作證件照的方法,有需要的小夥伴一起來學習吧。     ...
2025-12-07
成都最正宗的四川擔擔面(成都這家老牌面館)
成都最正宗的四川擔擔面(成都這家老牌面館)
  相信隻要是去過成都和重慶的朋友肯定都知道,盡管川渝地區的人民普遍都相當好客,而且各種美食也是看得人眼花缭亂,但是唯獨一句話絕對不能相信,那就是“這個菜一點都不辣”。對于大部分不太能吃辣的人而言,川渝人民眼中的微微辣絕對能夠讓大家懷疑人生,畢竟這兩個地方可是以辣出名的川菜的發源地,随便什麼美食或者是小吃都是辣的人夠嗆,想要找一家味道比較清淡的店鋪吃個飯,那...
2025-12-07
雨中花慢翻譯(雨中花慢)
雨中花慢翻譯(雨中花慢)
  雨中花慢   筱汐   夏送和風,斜陽夕照,柳蔭綠遍天涯。   簇簇荼靡落,花骨成堆。   碧葉青荷猶在,殷勤雙蝶翩飛。   經年舊院,畫梁已斷,燕影無歸。   滿懷愁緒,心事重重,如今看慣榮衰。   多少憶、浮生恨短,鬥轉星移。   夢醒後千載過,南窗倚盼佳期。   相逢那日,琴棋書畫,共賦新詞。      ,
2025-12-07
怎麼分辨春夏秋冬茶的品質(春夏秋)
怎麼分辨春夏秋冬茶的品質(春夏秋)
  #頭條創作挑戰賽#一年四季春夏秋冬采摘制作的茶葉都有哪些區别呢?有人說春茶肥,秋茶瘦,夏茶飽,冬茶透,不同的季節生産的茶真的都會有這些區别嗎?首先我們來說春天,春天茶葉的内含物質是最豐富的,經過一整個冬天的休養生息,茶葉裡面儲存了很多的養分和芳香物質,喝起來的滋味是比較鮮爽的,香氣也是比較高雅綿長的,所以像綠茶和岩茶都是追逐春茶的。      第二夏天,...
2025-12-07
遇見王瀝川兩人初遇(師姐搭檔王瀝川)
遇見王瀝川兩人初遇(師姐搭檔王瀝川)
  《彩虹的重力》即将溫情上線,以現代都市愛情中對“靈魂伴侶”的渴望為主旋律,講訴的一個溫暖治愈的故事。它由《遇見王瀝川》幕後制作團隊打造,原著作者施定柔任編劇,高以翔、宣璐擔綱主演,張亮特邀出演,還有錦榮、嶽以恩等青年演員加盟,有望成為口碑之作《遇見王瀝川》的升級版本。宣璐在今年的大爆劇《陳情令》中出演世界上最好的“師姐”,圈粉無數也虐粉無數。說到高以翔的...
2025-12-07
Copyright 2023-2025 - www.tftnews.com All Rights Reserved