博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
extern和#ifndef解决多个文件使用一个全局变量的问题
阅读量:2384 次
发布时间:2019-05-10

本文共 1596 字,大约阅读时间需要 5 分钟。

转载原文地址:

#ifndef_XX_头文件.H

#define_XX_头文件.H
intA;
#endif

那么,很糟糕的是,这里的intA是个全局变量的定义,所以如果这个头文件被多次引用的话,你的A会被重复定义

显然语法上错了。只不过有了这个#ifndef的条件编译,所以能保证你的头文件只被引用一次,不过也许还是会岔子,但若多个c文件包含这个头文件时还是会出错的,因为宏名有效范围仅限于本c源文件,所以在这多个c文件编译时是不会出错的,但在链接时就会报错,说你多处定义了同一个变量。

该头文件被重复引用:

对于写好的a.h文件,对于变量A的赋值在A.CPP文件中进行

b.cpp:引用a.h,然后c.cpp引用b.h,此时c执行时,走到了b.h发现a已经被定义过了,那么就不会再次进行定义了,也就是a只被定义了一次。

但是如果对于b.cpp,c.cpp,d.cpp同时使用这一个头文件,在b中定义了一个a变量,此时这个宏定义在c中已经没有用了,所以在c.cpp中会再次定义这么一个a变量,d.cpp也会定义a变量。在编译时期不会报错,但是在链接时因为会找到多个变量a,此时会报错。

所以,ifndef只能解决一个头文件在同一个c文件中被重复定义的问题。除了这个c文件,其他的c文件还是有可能重复定义这个变量,导致链接过程中出错。

使用extern的好处是,extern 是对变量的声明而不是定义,这样可以避免变量的重复定义,最后只使用这样一个变量。

使用static:

修饰局部变量-->该函数内全局变量

修饰全局变量?

使用static修饰在头文件中修饰的变量,此时不会产生冲突(用static修饰的全局变量的作用域为定义的源文件),在多个源文件中引用该头文件,等于是在每个源文件中都定义了该变量一次,而且此变量仅在本源文件中有效,这样的使用方式不是本身想要的全局变量,也浪费了内存空间,不推荐使用 。

因为本身我们想使用全局变量是想多个文件同步使用一个变量的数据,也就是一个文件中的数据可以传递给另一个文件,所以一开始想到的是通过include加头文件的方式,但是这样每一个引用该头文件的源文件,都会再次定义一次该变量,也就是该变量已经不是我们想要共享的变量数据了。

所以想到的第一个解决办法通过extern,多个源文件共享一个变量数据。

第二就是通过static方式,但是这样的话,虽然不会引起重复定义,因为每个源文件都为该变量开辟出一块只属于该源文件的内存存放数据。但是这样也起不到全局变量的作用。

static修饰的全局变量的作用范围会被限制在声明的源文件内。

举个例子, 

a.c

b.c

c.h

其中c.h被a.c,b.c引用, 而且c.h中定义了:

static int test = 0;

在编译的时候,a.c会和c.h一起编译, 然后b.c也会和c.h一起编译, 但是要注意, 编译器分别编译这两组文件的时候, 变量test会分别分配地址, 然后初始值也都为0;

这就意味着, 在a.c中如果调用了test, 其初始值为0;假设在a.c中test随后被修改为了2, 然后b.c中也调用test,这时test的初始值还是0, 而不是2! 

如果不加上这个static,那么因为两个源文件都需要定义这个全局变量test,那么在链接过程中会出错,因为重复定义test。

如果加上这个static,那么链接过程中不会出错,但是每个源文件都为这个变量分配了单独的空间,全局变量没有意义。最好的办法就是加上extern使得每个源文件都是引用,而不是重新定义从而出错。

最后这个问题跟ifndef解决的问题不一样,ifndef解决不了这个全局变量重复定义的问题,只能解决头文件在一个源文件中重复定义的问题,也解决不了多个源文件引用同一个头文件引起的重复定义问题。只能解决嵌套引用的问题

 

你可能感兴趣的文章
php curl通过代理获取数据
查看>>
6 个 Linux性能监控命令行工具
查看>>
mysql 编码字符集配置
查看>>
php查看opcode编码的扩展 opdumper
查看>>
php转换html格式为文本格式
查看>>
mysql-proxy主从服务架构下读写分离和负载均衡实现及原理
查看>>
Nginx location 和 rewrite retry
查看>>
基于nginx的FastCGI的缓存配置
查看>>
Nginx模块fastcgi_cache的几个注意点
查看>>
PHP使用curl伪造IP地址和header信息
查看>>
代理服务器中的HTTP代理与SOCKS代理有什么区别?
查看>>
零基础Python学习路线,小白的进阶之路!
查看>>
CSS的23个垂直居中技巧,你都学会了吗?
查看>>
黑客攻击用的最短代码大揭秘,颠覆你的世界观!
查看>>
零基础的自学前端之路,当年的入坑之旅
查看>>
新手程序员?教你解决办法!基础都掌握了,动手敲代码就一脸懵逼
查看>>
程序员快速进阶学习到底要看书还是要看视频?
查看>>
web游戏框架哪家强?国内外精选优质框架分析及注意事项
查看>>
各行业都爱用什么编程语言开发?
查看>>
css3实现ps蒙版效果以及动画,炫酷吊炸天!
查看>>