zoukankan      html  css  js  c++  java
  • 头文件的宏定义#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
    ",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
    ",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 ",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
    ",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”就可以解决重复包含引起的重复定义的问题。

  • 相关阅读:
    地铁结队开发(一)
    构建之法(一)——软件工程师的成长
    第二周学习总结
    新的开始
    开学第一周作业
    第一周学习总结
    软件工程第六周总结
    软件工程第五周总结
    清明节第三天
    清明节第二天
  • 原文地址:https://www.cnblogs.com/amanlikethis/p/3750478.html
Copyright © 2011-2022 走看看