c,c++里面,头文件里面的ifndef /define/endif的作用

今天和宿舍同学讨论一个小程序,发现有点地方不大懂······

是关于头文件里面的一些地方:

例如:要编写头文件test.h

在头文件开头写上两行:

#ifndef _TEST_H

#define _TEST_H//一般是文件名的大写

············

············

头文件结尾写上一行:

#endif

大概是以前没有学好吧,对这里不是很理解,为什么要用这些呢?刚才上网查了查,借鉴了点高手的,自己总结了一点,就写在这里了,有什么错误之处,请大侠们指出

1.比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。

例如:

假设你的工程里面有4个文件,分别是a.cpp,b.h,c.h,d.h。  
a.cpp的头部是:  
#include   "b.h "  
#include   "c.h "  
b.h和c.h的头部都是:  
#include   "d.h "  
而d.h里面有class   D的定义。  
这样一来,  
编译器编译a.cpp的时候,先根据#include   "b.h "去编译b.h这个问题,再根据b.h里面的#include   "d.h ",去编译d.h的这个文件,这样就把d.h里面的class   D编译了;  
然后再根据a.cpp的第二句#include   "c.h ",去编译c.h,最终还是会找到的d.h里面的class   D,但是class   D之前已经编译过了,所以就会报重定义错误。 加上ifndef/define/endif,就可以防止这种重定义错误。

所以还是把头文件的内容都放在#ifndef和#endif中吧。  
不管你的头文件会不会被多个文件引用,你都要加上这个。  
一般格式是这样的:   
#ifndef   <标识 >   
#define   <标识 >   
......   
......   
#endif   <标识 >  
在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h   
#ifndef   _STDIO_H_   
#define   _STDIO_H_   
......   
#endif

2.在#ifndef中定义变量出现的问题(一般不定义在#ifndef中)。   
#ifndef   AAA   
#define   AAA   
...   
int   i;   
...   
#endif   
里面有一个变量定义在vc中链接时就出现了i重复定义的错误,而在c中成功编译。   
原因:   
(1).当你第一个使用这个头的.cpp文件生成.obj的时候,int   i   在里面定义了当另外一个使用这个的.cpp再次[单独]生成.obj的时候,int   i   又被定义然后两个obj被另外一个.cpp也include   这个头的,连接在一起,就会出现重复定义.   (2).把源程序文件扩展名改成.c后,VC按照C语言的语法对源程序进行编译,而不是C++。在C语言中,若是遇到多个int   i,则自动认为其中一个是定义,其他的是声明。

(3).C语言和C++语言连接结果不同,可能(猜测)时在进行编译的时候,C++语言将全局变量默认为强符号,所以连接出错。C语言则依照是否初始化进行强弱的判断的。  
(参考解决方法:   
(1).把源程序文件扩展名改成.c。   
(2).推荐解决方案:   .h中只声明   extern   int   i;  
        在.cpp中定义   
#ifndef   __X_H__   
#define   __X_H__   
extern   int   i;   
#endif   //__X_H__   int   i;   
注意问题:变量一般不要定义在.h文件中。

推荐:http://www.cnblogs.com/roucheng/p/cfenge.html

头文件里面的ifndef /define/endif的作用的更多相关文章

  1. 头文件中的#ifndef/#define/#endif 的作用

    在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定 ...

  2. 头文件种的ifndef/define/endif 是干什么用的

    头文件种的ifndef/define/endif 是干什么用的? 答:防止头文件被重复包含.

  3. 头文件中ifndef/define/endif的作用以及#pragma once使用

    例如:要编写头文件test.h 在头文件开头写上两行: #ifndef _TEST_H #define _TEST_H//一般是文件名的大写 ············ ············ 头文件 ...

  4. ifndef/define/endif 的作用

    转载自百度百科 ,感谢度娘 1 2 3 #ifdef语句1 //程序2 #endif 可翻译为:如果宏定义了语句1则执行程序2. 作用:我们可以用它区隔一些与特定头文件.程序库和其他文件版本有关的代码 ...

  5. C++头文件为什么要加#ifndef #define #endif

    #ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...

  6. 头文件为什么要加#ifndef #define #endif

    #ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...

  7. #ifndef #define #endif 防止头文件被重复引用

    想必很多人都看过“头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件 ...

  8. 头文件#ifndef #define #endif使用

    想必很多人都看过“头文件中的 #ifndef #define #endif 防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件 ...

  9. #ifndef/#define/#endif以及#if defined/#else/#endif使用详解

    1.#ifndef_WINDOWS_PLAYM4_H_      #define _WINDOWS_PLAYM4_H_ #endif 问题:想必很多人都看过"头文件中的 #ifndef/#d ...

随机推荐

  1. memcache(三)内存管理

    memcached(三)内存管理 memcached使用预申请的方式来管理内存的分配,从而避免内存碎片化的问题.如果采用mallo和free来动态的申请和销毁内存,必然会产生大量的内存碎片. 基本知识 ...

  2. AWS re:Invent 2014回顾

    亚马逊在2014年11月11-14日的拉斯维加斯举行了一年一度的re:Invent大会.在今年的大会上,亚马逊一股脑发布和更新了很多服务.现在就由我来带领大家了解一下这些新服务. 安全及规范相关 AW ...

  3. Windows Live Writer 初次使用

    Windows  Live Writer 博客园文章的一款发布器,这篇文章就是通过其发布的,可以先在word中写好博客内容,直接粘贴到这里发布就OK,之前我都是先在Word中写好一份,然后在blogs ...

  4. EF架构~在T4模版中自定义属性的getter和setter

    回到目录 T4模版为我们在ORM操作上提供了便捷,它很方便的可以对实体进行全局性的修改,之前我介绍过通过T4来为属性加默认性,而今天我主要告诉大家如何使用T4模版将getter,setter块改为自己 ...

  5. javaweb学习总结—Apache的DBUtils框架学习

    注明: 本文转载自http://www.cnblogs.com/xdp-gacl/p/4007225.html 一.commons-dbutils简介 commons-dbutils 是 Apache ...

  6. php的几种运行模式CLI、CGI、FastCGI、mod_php

    1.CLI:就是命令行,例如可以在控制台或者是shell中键入命令: php -f index.php 然后获取输出 2.CGI:以下是不同的说法与理解 公共网关接口”(Common Gateway  ...

  7. javaBean和jsp应用

    原网页:http://www.douban.com/note/102320977/ JavaBean是一种可复用,跨平台的组件.共有两种JavaBean:一种无用户界面,这种一般用于处理数据运算,操作 ...

  8. nodejs字符与字节之间的转换

    new Buffer("Hello World").toString("base64"); /* yields SGVsbG8gV29ybGQNCg== */ ...

  9. Java多线程系列--“JUC集合”02之 CopyOnWriteArrayList

    概要 本章是"JUC系列"的CopyOnWriteArrayList篇.接下来,会先对CopyOnWriteArrayList进行基本介绍,然后再说明它的原理,接着通过代码去分析, ...

  10. Tools - Git与GitHub

    Git Wiki - Git 开源的分布式版本控制系统,用于敏捷高效地管理项目版本. Git - HomePage Git - CHEAT SHEET git_cheat_sheet.pdf GitH ...