条件编译与重复定义的问题————————————————

安放天天 2014-01-14 10:35:00
假设头文件head.h:
#ifndef __S1_H__
#define __S1_H__
void led_init(void);
#endif

建立2个文件,
第一个文件为file1.c ,并将头文件包含进去
第二个文件为file2.c ,也将头文件包含进去。
首先编译file1.c,头文件肯定会被包含进去并编译,
接着编译file2.c,头文件会被包含进去并编译吗?

个人认为:编译file2.c,头文件会被包含进去并编译。原因如下:
file1.c里面include了head.h
而尽管head.h里面有#define __S1_H__
事实上,#define 的作用域只限于单个文件,所以__S1_H__在file1.c编译完后就没了,编译file2.c时,#ifndef __S1_H__依然是成立的,因此file2.c会继续 include并编译。条件编译是为了防止同一文件中多次包含的。
--------------------------对吗????

...全文
558 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
大奶兔白糖 2014-01-14
  • 打赏
  • 举报
回复
引用 楼主 u013393674 的回复:
假设头文件head.h: #ifndef __S1_H__ #define __S1_H__ void led_init(void); #endif 建立2个文件, 第一个文件为file1.c ,并将头文件包含进去 第二个文件为file2.c ,也将头文件包含进去。 首先编译file1.c,头文件肯定会被包含进去并编译, 接着编译file2.c,头文件会被包含进去并编译吗? 个人认为:编译file2.c,头文件会被包含进去并编译。原因如下: file1.c里面include了head.h 而尽管head.h里面有#define __S1_H__ 事实上,#define 的作用域只限于单个文件,所以__S1_H__在file1.c编译完后就没了,编译file2.c时,#ifndef __S1_H__依然是成立的,因此file2.c会继续 include并编译。条件编译是为了防止同一文件中多次包含的。 --------------------------对吗????
正确
zhxianbin 2014-01-14
  • 打赏
  • 举报
回复
#ifndef __S1_H__ //如果没有定义 __S1_H__ 就会包含
lm_whales 2014-01-14
  • 打赏
  • 举报
回复
.h 可以被 .h 包含,也可以被.c 包含 如果 .h 和.c 都包含了某个.h 则这个共同包含的文件被重复包含; 一个.h 也可能被一个.c 单独 包含若干次。 那么用了 #ifndef __S1_H__ #define __S1_H__ 。。。。。。。 #endif 那种方法以后, 。。。。这部分 就只有一次包含被编译,另一次(n-1次)被忽略,不再编译第二次。 这就是,防止重复包含的意义。 这是利用,所有编译器,一定支持的技术实现的,算是一种技巧。 #pragma once作用类似。 不过需要编译器支持该预编译指令; 编译器实现的时候,需要记录,头文件是否已经编译。 对于不同的.c,.cpp ,编译器是分别编译的,所以互不相干。 有些编译器,为了加快编译速度, 会对某些头文件,专门进行独立的预编译, 然后所有.c,.cpp 等,实现文件编译时; 利用预编译头文件的成果,加快编译速度。 BCB 是 #include 在某些区域时, 对包含的头文件,进行独立的预编译。 VC 是 对 stdafx.h 或者设定的头文件 该头文件,包含许多文件,在项目中许多.c,.cpp 都要用到 进行独立的预编译。
zhuobattle 2014-01-14
  • 打赏
  • 举报
回复
yes,所以如果那个.h里有一个全局变量就会重复定义。
漫步者、 2014-01-14
  • 打赏
  • 举报
回复
#ifndef __S1_H__
#define __S1_H__
//你的数据定义处
#endif
ouyh12345 2014-01-14
  • 打赏
  • 举报
回复
#ifndef __S1_H__ #define __S1_H__ #endif 类似于#pragma once 是防止重复包含的 条件编译是类似于: #ifdef ___AAA #define AAA AAAS #endif
vipcxj 2014-01-14
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
事实上,#define 的作用域不限于单个文件。
LZ指的单个文件应该是单个编译单元,所谓include其实就是个复制黏贴,把头文件的内容复制到include的地方。 一个源文件会包含很多头文件,这些头文件有的会包含其他头文件,导致最终一个源文件包含了重复的头文件,那个#define就能保证这些重复头文件中只有一个的内容是有效的,其他都被忽略。同样,这些头文件里的#define的东西也只在这一个源文件里有效。若希望其他源文件中也有相同的宏定义,只要在那些源文件中再次包含相应的头文件即可。否则那些源文件就不存在此宏定义。 总而言之,LZ的说法应该是对滴
赵4老师 2014-01-14
  • 打赏
  • 举报
回复
事实上,#define 的作用域不限于单个文件。
绿皮蛙 2014-01-14
  • 打赏
  • 举报
回复
#include 只是单纯的复制而已 就是在预处理的时候把head.h的内容复制到两个点c里 编译只是编译点c文件 然后看makefile是先编译file1还是先编译file2 然后#define也是编译之前预处理的时候就会做的 这样写是不会被编译两次的

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧