頭文件的宏定義#ifndef測試


一、入題

  在頭文件的書寫中,都加入了如下內容:

#ifndef __頭文件名_H
#define __頭文件名_H

#endif

  曾經在書中看到的解釋是“防止重復定義”,今天突然想到為什么是這樣的解釋。

二、測試

  測試文件共三個,兩個頭文件:head1.h、head2.h,一個C源程序:program.c。

1、頭文件沒有宏定義的代碼實驗

① 測試代碼

head1.h

unsigned char global[] = "hello world!";  

head2.h

unsigned char global[] = "hello world!"; 

program.c

#include "head1.h"
#include "head2.h"
#include <stdio.h>

int main(void)
{
    printf("%s\n",global);
    return 0;
}

② 測試結果

  程序在編譯時提示:“重復定義了全局變量global”。

2、頭文件含有宏定義的代碼實驗

① 測試代碼

head1.h內容:

#ifndef __HEAD_H
#define __HEAD_H

unsigned char global[] = "hello world!"; 

#endif

head2.h

#ifndef __HEAD_H
#define __HEAD_H

unsigned char global[] = "hello world!"; 

#endif

program.c

#include "head1.h"
#include "head2.h"
#include <stdio.h>

int main(void)
{
    printf("%s\n",global);
    return 0;
}

② 測試結果

  程序正常編譯、連接,生成可執行文件。

三、原因分析

1、頭文件沒有宏定義的代碼實驗

  program.c的預編譯結果:

head1.h被替換為:
unsigned char global[] = "hello world!";
head2.h被替換為:
unsigned
char global[] = "hello world!"; #include <stdio.h> int main(void) { printf("%s\n",global); return 0; }

  顯然,重復定義了global。

2、頭文件含有宏定義的代碼實驗

  program.c的預編譯結果:

 1 head1.h被替換為:
 2 #ifndef  __HEAD_H
 3 #define  __HEAD_H
 4 
 5 unsigned char global[] = "hello world!"; 
 6 #endif
 7 
 8 
 9 head2.h被替換為:
10 #ifndef  __HEAD_H
11 #define  __HEAD_H
12 
13 unsigned char global[] = "hello world!"; 
14 #endif
15  
16 #include <stdio.h>
17 
18 int main(void)
19 {
20     printf("%s\n",global);
21     return 0;
22 }

  由於一開始沒有定義宏__HEAD_H,所以在2行的時候編譯器判斷為真,就定義了宏__HEAD_H和全局變量global。

  由於在3行的時候定義了宏__HEAD_H,所以編譯器判斷10行的條件為假,自然也會將其中的內容忽略掉。結果就是:兩個頭文件實際上只定義一次宏__HEAD_H和全局變量global,所以編譯的時候能正常通過。

三、實際應用中

  比如STM32單片機編程的時候,main.c包含了兩個外設頭文件stm32f10x_gpio.h、stm32f10x_i2c.h,而這兩個頭文件又都包含了stm32f10x.h。在main.c的預編譯過程中,顯然stm32f10x.h要被包含兩次。通過“頭文件的宏定義#ifndef”就可以解決重復包含引起的重復定義的問題。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM