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

C語(yǔ)言

有趣的C語(yǔ)言預(yù)處理

時(shí)間:2024-07-29 15:38:20 C語(yǔ)言 我要投稿
  • 相關(guān)推薦

有趣的C語(yǔ)言預(yù)處理

  #define和#include是最常用的預(yù)處理,單片機(jī)程序不用其他預(yù)處理也完全可行。所以初學(xué)者并不深究預(yù)處理的應(yīng)用。下面是有趣的C語(yǔ)言預(yù)處理,歡迎閱讀了解。

  分類解釋

  在編譯器編譯之前,會(huì)首先搜索預(yù)處理指令,按照指令完成編譯,預(yù)處理又分為:文件包含、條件編譯、布局控制(雜注)和宏替換。

  文件包含:

  #include""和#include<>,前者是和該c文件相同目錄下的.h,如 #include "os_cfg.h" ,或指明路徑的.h,如 #include "softwareucos-iisourceucos_ii.h" ;

  后者是編譯器系統(tǒng)路徑中的.h,一般C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù)在編譯器里集成,如 #include 。

  只要包含了.h,而.h里有函數(shù)聲明(或變量、結(jié)構(gòu)體實(shí)例),那么不論這個(gè)函數(shù)(變量、結(jié)構(gòu)體實(shí)例)在那個(gè).c文件里定義的,都可以在主C文件中使用。

  對(duì)于函數(shù),可以按功能分類成各種模塊,集合在一起寫成一個(gè).c文件,然后作同名的.h給出函數(shù)聲明,如果模塊太多,也可以再用一個(gè).h來(lái)包含各模塊的.h,uCOS-II中的includes.h就是這樣。

  對(duì)于變量,C模塊中的全局變量只對(duì)該模塊有效,如果想要被其他C文件訪問,就得在.h里聲明,如果主C包含了這個(gè).h,那么此變量就成了真正全局的了。

  對(duì)于結(jié)構(gòu)體實(shí)例,其結(jié)構(gòu)的定義可以放在.h里,(如果不需要到處定義很多實(shí)例放在c里也可以),實(shí)例定義在c里,而聲明放在.h里,這樣就到處可用此實(shí)例了。

  #include 的對(duì)象直接被 插入到了該位置,所以可能出現(xiàn)#include重復(fù)甚至嵌套,用#ifndef...#define...代碼...#endif的方法可以保證重復(fù)包含的.h那個(gè)只在第一次出現(xiàn)時(shí)編譯.

  條件編譯:

  上面的#ifndef就是條件編譯的一種。條件編譯主要用于跳過某些代碼不編譯,這樣可以用來(lái)寫一個(gè)C文件,但是適應(yīng)不同硬件版本,或者可采用不同算法。我就經(jīng)常用多種算法寫同一個(gè)功能,#define method 1,#if methof==1...#endif, #if method ==2...#endif

  Protothread的神奇功能就是用宏和條件編譯來(lái)實(shí)現(xiàn)的。舉個(gè)例子:

  #define LC_INIT(s) s = 0;

  #define LC_RESUME(s) switch(s) { case 0:

  #define LC_SET(s) s = __LINE__; case __LINE__:

  #define LC_END(s) }

  #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)

  每個(gè)線程執(zhí)行一次 PT_BEGIN(pt),這樣就創(chuàng)建了一個(gè)switch,一開始 pt->lc=0, PT_BEGIN(pt)之后繼續(xù)執(zhí)行語(yǔ)句(本protothread的語(yǔ)句,一般是while(1)),執(zhí)行到PT_WAIT_UNTIL(pt, condition)之類會(huì)調(diào)用LC_SET((pt)->lc);然后return,于是pt->lc記錄了行號(hào),創(chuàng)建了case:,下次進(jìn)到線程之直接走 LC_RESUME(s)里的switch到上次的位置

  布局控制/雜注:

  主要是#pragma,從實(shí)用的角度講,就是編譯器為了簡(jiǎn)化用戶操作,給用戶提供了一些命令,不同編譯器是不一樣的,比如,IAR EW430就可以直接定義中斷函數(shù)而不用管中斷向量表在哪兒。(比如ARM7就要編譯前手動(dòng)改程序段的中斷向量表,DSPF2812就要用程序指令改數(shù)據(jù)段的中斷向量表,而51則由keil自動(dòng)放置中斷跳轉(zhuǎn)指令。)

  #pragma vector=PORT1_VECTOR

  __interrupt void Port_1(void)

  {

  //code

  }

  編譯器會(huì)自動(dòng)給中斷函數(shù)指定中斷向量。

  宏替換:

  宏函數(shù)其實(shí)可以巧妙的代替函數(shù),尤其是很短又沒有局部變量的一些語(yǔ)句,還可以代換很多復(fù)雜的格式,如

  #define F "%6.2f"

  #define F3 F " " F " " F" "

  用函數(shù)printf(F3,a,b,c),可以同時(shí)指定a,b,c 的格式

  其他:

  預(yù)定義標(biāo)識(shí)符

  為了處理一些有用的信息,預(yù)處理定義了一些預(yù)處理標(biāo)識(shí)符,雖然各種編譯器的預(yù)處理標(biāo)識(shí)符不盡相同,但是他們都會(huì)處理下面的4種:

  __FILE__ 正在編譯的文件的名字

  __LINE__ 正在編譯的文件的行號(hào)

  __DATE__ 編譯時(shí)刻的日期字符串,例如: "25 Dec 2000"

  __TIME__ 編譯時(shí)刻的時(shí)間字符串,例如: "12:30:55"


【有趣的C語(yǔ)言預(yù)處理】相關(guān)文章:

C語(yǔ)言預(yù)處理知識(shí)11-26

C語(yǔ)言預(yù)處理概述03-30

c#中預(yù)處理指令#if的使用11-30

C語(yǔ)言考點(diǎn)精選03-18

C語(yǔ)言試題03-28

C語(yǔ)言的應(yīng)用12-12

C語(yǔ)言的結(jié)構(gòu)12-12

什么是C語(yǔ)言03-19

C語(yǔ)言試題(精選)12-05