头文件的宏定义#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 ;
}
② 测试结果
程序在编译时提示:“重复定义了全局变量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 ;
}
② 测试结果
程序正常编译、连接,生成可执行文件。
三、原因分析
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 ;
}
显然,重复定义了global。
2、头文件含有宏定义的代码实验
program.c的预编译结果:
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 #include <stdio.h> int main(void)
{
printf("%s\n",global);
return ;
}
由于一开始没有定义宏__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测试的更多相关文章
- glibc头文件和宏定义
头文件没啥好说的,无非就是" "和< >的区别,这估计只要是学过C/C++的人都明白.现在的编译器对头文件的包含顺序没有要求,但老的C实现则不一样.当然,我们现在无需关 ...
- C语言的头文件和宏定义详解
原文链接:https://blog.csdn.net/abc_12366/article/details/79155540
- C++头文件为什么要加#ifndef #define #endif
#ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...
- C 头文件、宏、编译问题
@2019-02-15 [小记] > C 头文件的防重复包含是针对同一个源文件而言 原因: #include 头文件就是一段代码的拷贝,头文件中若有类型定义等,重复包含就会造成编译错误,若无类型 ...
- 头文件为什么要加#ifndef #define #endif
#ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...
- C++ 包含头文件 和 宏的使用 和 条件编译
1 #define命令剖析 1.1 #define的概念 #define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本. ...
- extern 用法,全局变量与头文件(重复定义)
转自 https://www.cnblogs.com/chengmin/archive/2011/09/26/2192008.html 当你要引用一个全局变量的时候,你就要声明,extern int ...
- [转]避免头文件重复包含以及#ifndef 与 #program once 的区别
为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式.在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一 ...
- Cmake 脚本对项目输出路径和输出头文件的路径定义
对Lib项目的统一输出路径以下时解决方案: set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Lib)set(CMAKE_LIBRARY_O ...
随机推荐
- FindWindowEx
procedure CloseGameSver(); var H1, h2: HWND; begin H1 := FindWindow('TForm1', nil); h2 := FindWindow ...
- Centos6下yum安装MariaDB5.5(转)
原文地址:http://www.cnblogs.com/kgdxpr/p/3209009.html vi /etc/yum.repos.d/MariaDB.repo 加入下面内容 [mariabd]n ...
- JSON返回的自定义
当返回json格式的数据时,不想自己组织结果集,可以利用类的call方法. json类: <?php class Json { private $_data; public function _ ...
- RHCA442学习笔记-Unit11内存缓存
Unit 11 Memory Caches 内存缓存 学习目标: A. 使用内存来改善运行慢的子系统的服务时间. 11.1 Strategi ...
- 导演类(CCDirector)
- ArrayList的实现原理--转
1. ArrayList概述: ArrayList是List接口的可变数组的实现.实现了所有可选列表操作,并允许包括 null 在内的所有元素.除了实现 List 接口外,此类还提供一些方法来操作内部 ...
- Zookeeper简介与安装
Zookeeper:A Distributed Coordination Service for Distributed Applications. 一.Zookeeper简介 众所周知,协同服务是分 ...
- Sql Server 与CLR集成
.NET编程和SQL Server ——Sql Server 与CLR集成 一.SQL Server 为什么要与CLR集成 1. SQL Server 提供的存储过程.函数等十分有限,经常需要外部 ...
- java中substring和indexof() 和lastindexof()
java中substring和indexof() 和lastindexof() str=str.substring(int beginIndex);截取掉str从首字母起长度为beginIndex的字 ...
- Unity3D 之2D动画机
这里来讲解一下2D动画机的使用 2D的时候,默认的情况下,可以调用默认的站立之类的动画,然后通过触发,可以变化自己的动画. 一:将一个图切成一些一个元素 二:创建一个精灵,给精灵添加一个动画机 三:给 ...