溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C中#if 0 和#if 1 詳解

發(fā)布時間:2020-08-08 09:02:44 來源:網(wǎng)絡(luò) 閱讀:536 作者:Joe科技 欄目:開發(fā)技術(shù)

1我們知道,C標(biāo)準(zhǔn)不提供C++里的“//”這樣的單行風(fēng)格注釋而只提供“/* */”這樣的塊注釋功能,我們通常使用它寫代碼中說明性的注釋文字(注釋作用)以及在調(diào)試時關(guān)閉某段代碼對編譯器的可見性(屏蔽作用),當(dāng)然,這里所謂的“注釋作用”和“屏蔽作用”是我們從功能上下的主觀定義,對預(yù)處理器而言,兩者并無任何區(qū)別。對于前者,因?yàn)椤白⑨尅敝胁粫俪霈F(xiàn)“注釋”和“需要屏蔽的代碼段”,所以不會有嵌套的需求,所以通常不會有問題;而對于后者,當(dāng)我們在調(diào)試程序時需要“屏蔽”某段代碼時,該段代碼中可能包含著前述的“注釋”和/或“已被屏蔽的代碼段”,這時就產(chǎn)生了“/* */”嵌套使用的需求,但SB的C標(biāo)準(zhǔn)恰恰不允許我們這么干。當(dāng)你試圖使用嵌套的塊注釋功能時,會發(fā)現(xiàn)預(yù)處理器把最外層注釋的開始和最內(nèi)層注釋的結(jié)尾這兩者之間的內(nèi)容處理成了注釋,而其后一直到最外層注釋結(jié)尾的內(nèi)容被當(dāng)作了“有效代碼”——這顯然會引起若干語法錯誤而導(dǎo)致編譯中止。高手們開動腦筋想到了“#if 0 ... #endif”,它同樣由預(yù)處理器進(jìn)行處理,同樣可以“屏蔽”一段代碼,你想把說明文字寫在里面也可以,這些和“/* */”都一樣,但不一樣的是:第一它允許嵌套(層數(shù)上限由預(yù)處理器決定)、第二你隨時可以把“#if 0”改成“#if 1”來取消對某段代碼的“屏蔽”——很卓越的特性,快拋棄笨拙的“/* */”吧!它唯一的缺點(diǎn)就是在編輯器中沒有“注釋”該有的文本顯示樣式。

2、現(xiàn)在再來說說2樓提到的自動變量局部化的問題:
------------------------------------------------
通過google,得知:

#if 0 code #endif




(1)code中定義的是一些調(diào)試版本的代碼,此時code完全被編譯器忽略。如果想讓code生效,只需把#if 0改成#if 1 
(2)#if 0還有一個重要的用途就是用來當(dāng)成注釋,如果你想要注釋的程序很長,這個時候#if 0是最好的,保證不會犯錯誤。(但是林銳的書上說千萬不要把#if 0 來當(dāng)作塊注釋使用) 
#if 1可以讓其間的變量成為局部變量。 
(3)這個結(jié)構(gòu)表示你先前寫好的code,現(xiàn)在用不上了,又不想刪除,就用這個方法,比注釋方便。 
------------------------------------------------

通過我上面說的第一點(diǎn),我們可以知道,對“#if/#endif”的處理是預(yù)處理器完成的,而預(yù)處理器的唯一工作就是作“文字替換”的“預(yù)處理”工作,它并不負(fù)責(zé)常數(shù)符號表的生成、變量存儲空間的分配、代碼的重定位等工作,那么完全是給預(yù)處理器看的“#if/#endif”怎么能控制變量的生存期、怎么能決定變量可以在哪里定義??
打開編輯器,寫下如下代碼:

C中#if 0 和#if 1 詳解

=========================== volatile unsigned char a;
unsigned int main(void)
{
        a = 0; #if 1 unsigned char *p = &a; *p = 255; #endif return 0;
} ===========================

C中#if 0 和#if 1 詳解



存成.c文件后用任何C編譯器(不包括C++編譯器)編譯,都會在紅字那一行報錯——為什么呢?因?yàn)轭A(yù)處理器進(jìn)行“預(yù)處理”的時候發(fā)現(xiàn)if的條件表達(dá)式為“真”,所以它把那段代碼塊留下了,而只把代碼塊前后的“預(yù)處理指示符號(或者叫做預(yù)處理命令)”給清除掉了,這樣,預(yù)處理后的結(jié)果交給編譯器“翻譯”的時候,它發(fā)現(xiàn)在一個函數(shù)(在這里為main函數(shù))內(nèi)部的表達(dá)式語句(在這里是a = 0;)之后發(fā)現(xiàn)了變量聲明/定義語句(在這里是聲明并定義指針變量p的語句)——按照編譯器的規(guī)則,這是一個錯誤,所以它拒絕接受這樣的輸入、罷工并開始抱怨(中止編譯、給出錯誤信息)。

 

 

當(dāng)注釋掉大塊代碼時,使用"#if 0"比使用"/**/"要好,因?yàn)橛?/**/"做大段的注釋要防止被注釋掉的代碼中有嵌套的"/**/",這會導(dǎo)致注釋掉的代碼區(qū)域不是你想要的范圍, 當(dāng)被注釋掉的代碼很大時容易出現(xiàn)這種情況,特別是過一段時間后又修改該處代碼時更是如此。

       在這里順便對條件編譯(#ifdef, #else, #endif, #if等)進(jìn)行說明。以下分3種情況:
  1. 情況1: 
  #ifdef _XXXX
  ...程序段1...
  #else
  ...程序段2...
  #endif
  這表明如果標(biāo)識符_XXXX已被#define命令定義過則對程序段1進(jìn)行編譯;否則對程序段2進(jìn)行編譯。
  例: 
  #define NUM
  .............
  .............
  .............
  #ifdef NUM
   printf("之前NUM有過定義啦!:) \n");
  #else
   printf("之前NUM沒有過定義!:( \n");
  #endif
  }
  如果程序開頭有#define NUM這行,即NUM有定義,碰到下面#ifdef NUM的時候,當(dāng)然執(zhí)行第一個printf。否則第二個printf將被執(zhí)行。
  我認(rèn)為,用這種,可以很方便的開啟/關(guān)閉整個程序的某項(xiàng)特定功能。
  2:情況2: 
  #ifndef _XXXX 
  ...程序段1... 
  #else 
  ...程序段2... 
  #endif
  這里使用了#ifndef,表示的是if not def。當(dāng)然是和#ifdef相反的狀況(如果沒有定義了標(biāo)識符_XXXX,那么執(zhí)行程序段1,否則執(zhí)行程序段2)。例子就不舉了。
  3:情況3:
  #if 常量 
  ...程序段1...
  #else
  ...程序段2...
  #endif 
  這里表示,如果常量為真(非0,隨便什么數(shù)字,只要不是0),
就執(zhí)行程序段1,否則執(zhí)行程序段2。
如果有#if需要頂格寫


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI