标签:style class blog c code java
一、入题
在头文件的书写中,都加入了如下内容:
#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”就可以解决重复包含引起的重复定义的问题。
头文件的宏定义#ifndef测试,布布扣,bubuko.com
标签:style class blog c code java
原文地址:http://www.cnblogs.com/amanlikethis/p/3750478.html