https://www.byvoid.com/blog/c-global-variables-in-multiple-files

首先看一段代码

func.c

int buf = 0;void func() {buf = 2;/* Do something else */
}

main.c

#include <stdio.h>int buf;
void func();int main() {buf = 1;func();printf("%d\n", buf);return 0;
}

编译两个文件,输出的结果是怎样的呢?一眼看上去,可能会输出1,因为两个全局变量buf在不同文件中,又没有extern声明,显然是两个嘛。然而实际上它的运行结果却是2,这说明了这两个文件中引用到的其实是一个变量!

这是为什么呢?原因是在编译时,C语言编译器将全局符号标记为strong和weak两类:

  • 函数和初始化的全局符号被标记为strong
  • 未初始化的全局符号被标记为weak

连接时,连接器对多重定义的全局符号的解析原则如下:

  • 同一个符号不允许有多个strong定义;
  • 假如一个符号有一个strong定义和多个weak定义,那么采用该符号的strong定义;
  • 假如一个符号有多个weak定义,那么选取任意一个weak定义

由于两个变量一个初始化了,一个没有初始化,所以一个是strong,一个是weak,所以连接器在符号解析时会把他们当成一个。

如果我们把main.c中的buf也初始化了:

#include <stdio.h>int buf = 0;
void func();int main() {buf = 1;func();printf("%d\n", buf);return 0;
}

再次编译就会发现

duplicate symbol _buf in:/var/folders/44/_cc501qx1jd1p5bfrjbk6b100000gn/T//ccZ87C6g.o/var/folders/44/_cc501qx1jd1p5bfrjbk6b100000gn/T//ccZlES8n.o
ld: 1 duplicate symbol for architecture x86_64
collect2: ld returned 1 exit status

这是因为两个全局变量都是strong的。

Makefile:

tst:main.o func.o
gcc -o tst main.o func.o

main.o:main.c
func.o:func.c

clean:
rm *.o tst

注意文件里面的对齐是一个tap而不是四个空格

先对两个.c文件编译生成.o文件,再将.o文件链接成可执行文件

如果直接用g++ -o tst main.c func.c编译出错

在.h或者.cpp中定义的全局变量或者全局函数,理论上所有文件都可以直接调用,但是需要注意的是最好不要在.h中定义全局变量或者全局函数,一旦有多个文件include这个.h文件,那么就会出现多次定义的错误

比较合适的做法是:

对于全局变量而言,在.h中用extern声明,在.c中定义

对于全局函数,在.h声明,在.c定义

也可以直接在.c中定义全局变量,但是其他文件就不能直接调用了

http://blog.csdn.net/sunmenggmail/article/details/7568418

c/c++的全局变量相关推荐

  1. Linux shell 学习笔记(4)— linux 环境变量(全局变量、局部变量及变量持久化)

    1. 环境变量概念及分类 bash shell 用一个叫作环境变量(environment variable)的特性来存储有关 shell 会话和工作环境的信息(这也是它们被称作环境变量的原因).这项 ...

  2. java局部变量全局变量,实例变量的理解

    java局部变量全局变量,实例变量的理解 局部变量 可以理解为写在方法中的变量. public class Variable {//类变量static String name = "小明&q ...

  3. python的 局部变量与全局变量

    局部变量: 只在函数内部定义并使用的变量,只在定义的函数内部使用有效, def function_a():a = 1def function_b(): a =1 只能在函数function_a 中使用 ...

  4. Java:全局变量(成员变量)与局部变量

    分类细则: 变量按作用范围划分分为全局变量(成员变量)和局部变量 成员变量按调用方式划分分为实例属性与类属性 (有关实例属性与类属性的介绍见另一博文https://blog.csdn.net/Drag ...

  5. C++ 笔记(06)— 变量作用域(局部变量、全局变量、静态局部变量)

    作用域是程序的一个区域,一般来说有三个地方可以定义变量: 在函数或一个代码块内部声明的变量,称为局部变量: 在函数参数的定义中声明的变量,称为形式参数: 在所有函数外部声明的变量,称为全局变量: 1. ...

  6. 在PHP中使用全局变量的几种方法

    简介 即使开发一个新的大型PHP程序,你也不可避免的要使用到全局数据,因为有些数据是需要用到你的代码的不同部分的.一些常见的全局数据有:程序设定类.数据库连接类.用户资料等等.有很多方法能够使这些数据 ...

  7. 链接全局变量再说BSS段的清理

    废话就不多说了,开始... 再说BSS段的清算 以前遇到一个裸机程序不能改变全局变量值的问题,最后模模糊糊处理了:手动添加了一个链接脚本,清算了BSS段.问题得以处理,就认定是BSS段清算的问题,全局 ...

  8. php 魔术变量和超级全局变量,PHP超级全局变量与魔术变量

    PHP在设计的时候已经预定义了9个超级全局变量.8个魔术变量和13魔术函数,这些变量和函数可以在脚本的任何地方不用声明就可以使用. 在PHP开发时会频繁的使用这些变量,这些变量可以方便的帮我们解决很多 ...

  9. pythonclass全局变量_Python-多处理全局变量更新未返回给父级

    我正在尝试从子流程中返回值,但是不幸的是这些值无法拾取.因此,我在线程模块中成功使用了全局变量,但在使用多处理模块时却无法检索在子流程中完成的更新.我希望我想念一些东西. 在给定var dataDV0 ...

  10. python 函数递归一次增加一次变量_python3--函数(函数,全局变量和局部变量,递归函数)...

    1.1函数 1.1.1什么是函数 函数就是程序实现模块化的基本单元,一般实现某一功能的集合. 函数名:就相当于是程序代码集合的名称 参数:就是函数运算时需要参与运算的值被称作为参数 函数体:程序的某个 ...

最新文章

  1. 事业单位计算机专业知识试卷,计算机专业知识试题(事业单位计算机专业知识考试试卷).doc...
  2. matlab 绘制方格网格(二维)
  3. Oracle Eneterprise Linux 5.8上安装Database 12c
  4. Homework 8 测试计划
  5. 5月28日任务 Apache和PHP结合、Apache默认虚拟主机
  6. python中浮点数类型_Python基本数据类型之浮点型
  7. Jmeter之CSS选择器/JQuery选择器关联
  8. linux libz-dev,Linux-based Development
  9. AI技术宅:女神说什么,听我的!
  10. Java 基础——日期(Date)的解析
  11. 小甲鱼Python第二十八讲(文件)
  12. sed 替换文件中的字符串
  13. TEM波以及TEM TE TM模的区别
  14. perfmon 端口修改_Jmeter插件之PerfMon监控插件使用说明
  15. 三维空间几何变换矩阵
  16. 消防应急疏散通道问题1(难度系数3)
  17. 二叉排序树,平衡二叉树和哈夫曼树
  18. windows录屏html文件,录音、录屏、共享屏幕怎么玩?
  19. github汉化注意事项(Chrome)
  20. 项目管理之监控:进展“巧”汇报,学会用数据说话

热门文章

  1. 今日arXiv精选 | 31篇EMNLP 2021最新论文
  2. F-Principle:初探深度学习在计算数学的应用
  3. 本周最热 AI 论文大集合,还不快一键收藏?
  4. 南瑞变压器保护装置说明书_电力试验:变压器感应耐压试验(二)
  5. 03 | 高可用保证:Nacos 如何有效构建注册中心集群
  6. IntelliJ IDEA快捷键学习
  7. 手把手带你领略双十一背后的核心技术Sentinel之服务的熔断降级
  8. Mybatis-sql语句的抽取
  9. CTF Geek Challenge——第十一届极客大挑战Misc Write Up
  10. C#——Ellipse(椭圆)类[继承Ellipse(椭圆)类重构Circle(圆)类]