ANSIC幾種特殊的標準定義(__FILE__、__LINE__、__STDC__···)

相關標題:__FILE__、__LINE__、__DATE__、__TIME__、__STDC__


爲方便大家閱讀,本文內容已經整理成PDF文件:

http://pan.baidu.com/s/1gfHygyn


Ⅰ、寫在前面

對於我們大部分使用單片機進行裸機開發的朋友來說,可能很少有人在程序中許多關鍵的地方打印一些關鍵信息。

有較大系統開發,或複雜系統開發經驗的朋友一般都會在程序中輸出很多調試信息,如在UCOSfreeRTOSLinux等系統開發調試時打印許多關鍵信息。

 

1.我們在使用STM32庫開發時,在stm32fxxx_conf.h文件下會發現如下這麼一條語句:

#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))

 

這條語句,對於使用寄存器,開發簡單且不大程序的朋友而言,可能他覺得用處不大,它可能就覺得很佔資源,且耗時。

 

其實不然,ST這麼設計是有他一定的道理的,對於開發大型、複雜系統的朋友而言,這條語句其實用處很大。每次,程序運行錯誤之後,它會打印程序代碼指定的位置,方便我們在龐大的程序中很快找到錯誤的位置

 

2.我們的系統會隨着時間的推移,不斷升級更新,也就是需要提交很多版本的可執行文件(hexbin等)。但是,產品後期使用中,我們對某些設備進行了升級,可能忽略了一些設備,也就是有些設備沒有升級,如果出現故障,我們怎樣才能很快找到是哪一個版本的軟件出現故障呢

 

這裏就需要我們在程序中添加一些關於版本的信息,我們最基礎的就是Vx.x.x.x等這種信息,但對於大型系統而言,這種信息是不夠的,還需要更多,比如:編譯日期,時間,編譯環境的版本等。

 

Ⅱ、幾種特殊標準定義

上面說了這麼多,就是需要讓大家知道,這些特殊標準定義的用途。上面說的只是簡單的舉例,其實他們的用途還很廣泛,掌握了基礎之後相信你們都會知道它們更多比較實用的意義。言歸正傳,下面講述這些基礎的知識。

 

本文主要講述下面幾個標準定義:

__FILE__:正在編譯文件的路徑及文件名

__LINE__:正在編譯文件的行號

__DATE__:編譯時刻的日期字符串 Jun 17 2017

__TIME__:編譯時刻的時間字符串  10:00:00

__STDC__:判斷該文件是不是標準C程序

 

1.__FILE__編譯文件名稱

File中文意思即文件,這裏的意思主要是指:正在編譯文件對應正在編譯文件的路徑文件的名稱

 

Keil版本對應的路徑是相對於工程文件而言的路徑IAR版本路徑是相對Windows路徑

 

比如下面提供源代碼工程:

char BuildFile[] = __FILE__;

printf(“編譯文件路徑:%s\n”, BuildFile);

 

Keil:

編譯文件路徑:App\main.c

 

IAR:

編譯文件路徑:C:\Users\Administrator\Desktop\STM32F417ZGIAR_ANSIC幾種特殊的標準定義\App\main.c

 

2.__LINE__編譯文件行號

上面說的是編譯的文件名,是一個字符串,而這裏說的是行號,是一個整型變量,這是這兩者的區別,所以在我提供工程中可以看到的源代碼:

char BuildLine = __LINE__;

printf(“編譯代碼所在行:%d\n”, BuildLine);

 

可以看不是數組的字符串,打印信息:

編譯代碼所在行:44

 

一般情況下,__FILE__是和__LINE__結合一起使用,用於打印我們代碼信息,方便快速定位代碼位置。

 

3.__DATE__編譯日期

__DATE__日期,需要注意的是:這個日期是你在編譯時Windows系統的日期,如果對應那部分代碼之前編譯好了,後面沒有編譯,這個日期還是之前的日期,而不是後面編譯的日期。因此,如果這裏用於定版本,就需要在定版本時對工程進行全部重新編譯,它纔會更新至你最後編譯的日期。

 

代碼:

char BuildDate[] = __DATE__;

printf(“編譯日期:%s\n”, BuildDate);

 

輸出結果:

編譯日期:Jun 17 2017

 

4.__TIME__編譯時間

這個和__DATE__一樣的原理,編譯時的時間,也是一個字符串。

再次提醒:用於定版本:需要重新編譯,這樣纔是最後一次編譯時間。

 

代碼:

char BuildTime[] = __TIME__;

printf(“編譯時間:%s\n”, BuildTime);

 

輸出結果

編譯時間:11:30:15

 

5.__STDC__標準C代碼

這個標準在我們單片機及嵌入式編程中運用的比較少,當要求程序嚴格遵循ANSIC標準時該標識符被賦值爲1,主要是判斷我們的程序文件是不是標準C程序。

 

#ifdef __STDC__

  printf(“標準C代碼文件\n”);

#else

  printf(“非標準C代碼文件\n”);

#endif

 

Ⅲ、源代碼分析與下載

爲了方便大家學習,本文提供的源代碼比較基礎和簡單,也方便理論結合實際學習,僅供參考。

 

我們在之前新建好的Demo工程上添加了如下部分代碼:

char BuildLine = __LINE__;

char BuildFile[] = __FILE__;

char BuildDate[] = __DATE__;

char BuildTime[] = __TIME__;

 

printf(“編譯文件路徑:%s\n”, BuildFile);

printf(“編譯代碼所在行:%d\n”, BuildLine);

 

printf(“編譯日期:%s\n”, BuildDate);

printf(“編譯時間:%s\n”, BuildTime);

 

#ifdef __STDC__

  printf(“標準C代碼文件\n”);

#else

  printf(“非標準C代碼文件\n”);

#endif

 

Keil版本輸出結果

編譯文件路徑:App\main.c

編譯代碼所在行:44

編譯日期:Jun 17 2017

編譯時間:11:30:15

標準C代碼文件

 

IAR版本輸出結果:

編譯文件路徑:C:\Users\Administrator\Desktop\STM32F417ZGIAR_ANSIC幾種特殊的標準定義\App\main.c

編譯代碼所在行:44

編譯日期:Jun 17 2017

編譯時間:11:45:00

標準C代碼文件

 

源代碼工程(STM32F417ZG_ANSIC幾種特殊的標準定義)下載地址:

http://pan.baidu.com/s/1hskScba

 

提示:如果網盤鏈接失效,可以微信公衆號“底部菜單”查看更新鏈接。

Ⅳ、最後

微信搜索EmbeddDeveloper” 或者掃描下面二維碼、關注,查看更多精彩內容!

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章