能不能在头文件中定义全局变量?

首先,这是一篇科普文,所以 比较杂,我尽量写清楚一些。

 

1、ANSI C标准是什么?GNU又是什么?ld是什么?

 

ANSI C是C语言的标准规范,是国际标准化组织制定的国际标准。

 

虽然 ANSI C规范了C语言的实现,但是在实际情况中,各家C语言提供商都会根据平台的不同情况对ANSI C进行一定的扩展。因此可以将现实中C语言实现看作是ANSI C的一个超集。比较有代表性的例子是linux的gcc编译器。由于该编译器对ANSI C进行了非常多的扩展,linux内核源码基本上只能在gcc上面 进行编译,希望通过其他的编译器来编译linux内核几乎是不可能的。

 

GNU计划,又称革奴计划。它的目标是创建一套完全自由的操作系统。1990年,GNU计划已经开发出的软件包括了一个功能强大的文字编辑器Emacs  。GCC(GNU Compiler Collection,GNU编译器集合),是一套由 GNU 开发的编程语言编译器。

 

GNU工具链包括了构建linux开发环境所需的编译、链接、调试、软件工程等工具。GCC(编译器)、Gdb(调试器)、make(软件等工程工具)。GCC下包括gcc,g++工具。GNU binutils是一组二进制工具程序集,是辅助GCC的主要软件,包括我们熟悉的as(GNU汇编器),ar(建立、修改、提取归档文件,归档文件是包含多个文件内容的一个大文件)、ld(连接器,把目标文件和归档文件结合在一起),我们在写程序的时候,有时候报错:[Error] ld returned 1 exit status,这就是程序在链接的时候出错了。

 

 

2、C语言可以在不同的源文件中定义相同名字的全局变量吗?

 

不使用static的时候,两个不同的源文件都可以正常编译,但会出现链接错误,原因是有两个地方存在相同的变量,导致编译器无法识别应该使用哪一个。

 

关于全局变量的几点说明:

①默认情况下,C语言中的全局变量和函数的作用域仅限于定义和声明这个函数或变量的内部,如果需要从这个C文件之外访问这些函数或者全局变量就需要使用 extern关键字进行声明,这是因为C编译器是以C文件为单位进行编译的,如果这个C文件中引用了其他文件中定义的函数或者变量,编译器将无法找到这个函数或者变量的定义,从而给出该函数或者变量未定义的错误信息。

 

②static关键字用于全局变量的声明时,作用类似于函数的情况,这个全局变量的作用域将局限在声明该变量的c文件内部,这个c文件之外的代码将无法访问这个变量。编译的时候将会出现类似undeference to "xxx"的报错,它是找不到xxx的,因为使用static相当于进行了文件隔离。

 

 

3、那么再引申另一个问题,能不能在头文件中定义全局变量?

 

因为变量只能被定义一次,包含了头文件的源文件,都将会定义同样的全局变量,造成冲突,所以,头文件中不能定义全局变量。还有网友从节省内存的角度来分析,还得到了很多赞,我觉得解释的不对啊!详见c语言 中 为什么不将全局变量的定义放在头文件中

 

 

4、本博客的导火索,

 

就是因为在一个大的工程中,需要增加一个全局变量,一开始我是加在了某一个头文件中,然后报重复定义的错误,很显然,就是因为第2点中说的,由于这个头文件被多个源文件include,虽然在编译阶段可能能通过,但是在链接的时候就会出现重复定义的错误。

 

解决办法:

①处于尽可能的改动较少的文件的文件的原则,自己写一个头问价,文件内容就一条:全局变量的定义。这样的话,在需要使用的位置通过include这个头文件就可以了。但是,如果有多个源文件需要使用使用这个变量的话,这种情况也会发生重复定义的错误,因为include的过程就是复制的过程,那么很显然了,这个头文件被拷贝到了多个源文件中,链接时肯定会出现重复定义的错误啊。

 

而且,假设只有一个源文件需要这个全局变量,那么直接在这个源文件中定义全局变量就好了啊!还定义什么鬼头文件哦!

 

②假设工程中的多个源文件需要这个全局变量,那么你就任找一个源文件,把这个全局变量定义到这个源文件中,然后新建一个头文件,在里面进行extern 这个变量的声明,最后在需要使用这个全局变量的源文件中include你新建的头文件就OK了。

 

 

参考:

[1] 嵌入式系统高级C语言编程,凌明编著,第一章概述

[2] C语言可以在不同的源文件中定义相同名字的全局变量吗

  • 34
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值