extern static修饰全局变量的区别

在实际开发C++项目的时候,一个项目里面往往会包含多个cpp文件,多个头文件,有时还会有c文件。由于变量的声明可以有多次,但定义只能有一次,这就不可避免地要使用extern,static关键字。弄清楚这几个关键字之间的用法和区别,能节省很多调试项目的时间,尤其是对于一些难以定位的链接错误。下面分别介绍:

一、extern关键字

这个关键字可能是最容易用错的一个,一方面可能是因为平时写的小程序不太会用到这个关键字,另一方则是这个关键字确实有些不太容易理解的用法。

extern关键字主要有两个作用:1、声明一个全局变量;2、extern “C” { /*用C实现的内容(通常写在另外的.c文件中)*/ }

1、当用extern声明一个全局变量的时候,首先应明确一点:extern的作用范围是整个工程,也就是说当我们在.h文件中写了extern int a;编译的时候编译器会去其他的.cpp文件中找有没有int a的定义,如果没有,编译报错;当extern int a;写在.cpp文件中时,编译器会在这个.cpp文件该声明语句之后找有没有int a的定义,然后去其他的.cpp文件中找,如果都找不到,编译报错。另外值得注意的一点是,当extern语句出现在头文件中时,不要将声明和定义在一条语句中给出,也就是不要在头文件中写类似于这样的语句:

extern int a = 1;

这样做的一个可能的原因是:担心在其他的.cpp文件中忘记给出该变量的定义,所以干脆就在声明的时候直接给出定义得了,什么编译的时候报错说变量a没有定义。

对变量没有定义的忧虑是应该提倡的,但解决这种忧虑的办法却弄巧成拙了。前面已经说了,extern声明全局变量的作用范围是整个工程,如果我们在头文件中给出全局变量的定义,如果工程中有多个.cpp文件包含了此头文件,则这个全局变量在工程中定义了多次,因此编译报错。遵照的法则其实很简单:只在头文件中通过extern给出全局变量的声明,在.cpp文件中用到该变量时才给出定义(并且只能定义一次)。

2、C++完全兼容C,当extern与“C”连用时,作用是告诉编译器用C的编译规则去解析extern “C”后面的内容。最常见的差别就是C++支持函数重载,而标准C是不支持的。如果不指明extern “C”,C++编译器会根据自己的规则在编译函数时为函数名加上特定的后缀以区别不同的重载版本,而如果是按C的标准来编译的话,则不需要。

二、static关键字

static关键字的作用有很多,声明静态全局变量,类的静态成员等。这里主要讨论他在修饰全局变量时与extern的区别。有两点需要注意:

1、static修饰全局变量时,声明和定义是同时给出的;2、static的全局作用域只是自身编译单元。

一个编译单元指一个.cpp文件和他所包含的头文件。也就是说static在修饰全局变量时,“全局”的范围是小于extern的。因此,在头文件中用static声明(和定义)全局变量,是不会出现上面讨论的重复定义的问题的。

时间: 2024-10-14 16:27:26

extern static修饰全局变量的区别的相关文章

(转)全局变量、extern/static/const区别与联系

全局变量.extern/static/const区别与联系 编译单元(模块):     在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LINK ERROR), 因为它不像编译错误那样可以给出你程序错误的具体位置,你常常对这种错误感到懊恼,但是如果你经常使用gcc,makefile等工具在linux或者嵌 入式下做开发工作的话,那么你可能非常的理解编译与连接的区别! 当在VC这样的开发工具上编写完代码,点击编译按钮准备生成exe文件时,V

修饰符 extern/static/const/UIKIT_EXTERN(OC版extern) 的使用

先逐个分析每个修饰符单独代表的含义,然后再分析某些修饰符组合在一起的时候所代表的含义. const const 相对最好理解,就是修饰的东西不能再被修改. 没有 const 修饰的指针,指针 p 和 *p 都能被修改: 1 // // 定义一个指针 2 int *p = NULL; 3 // // 定义2 个int 类型的变量 4 5 int a = 10; 6 int b = 30; 7 8 // p 指向 a 9 NSLog(@"p = %p, a = %d, b = %d", p

c语言中用static修饰的函数与普通函数的区别

C程序一直由下列部分组成:1)正文段——CPU执行的机器指令部分:一个程序只有一个副本:只读,防止程序由于意外事故而修改自身指令:2)初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放在这里.3)非初始化数据段(bss段)——在程序中没有初始化的全局变量:内核将此段初始化为0.4)栈——增长方向:自顶向下增长:自动变量以及每次函数调用时所需要保存的信息(返回地址:环境信息).5)堆——动态存储分. 在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量.1)内存中

static extern const修饰符

const const修饰的东西不能被修改(由左至右解读-->顺时针螺旋法则) 指针类型根据位置的不同可以理解成3种情况: 1.常量指针 NSString * const pt1; //常量指针,指向一个字符串 //pt1初始化之后不能赋值,指向的对象值可以修改. //定义字符串常量 //NSString* const [email protected]"123"; @"123"存储在文字常量区,相同的字符串只存储一份 NSString* [email pro

IOS总结 静变量static、全局变量extern、局部变量、实例变量

1.静态变量 static 什么是静态变量:从面向对象的角度触发,当需要一个数据对象为整类而非某个对象服务,同时有力求不破坏类的封装性,既要求此成员隐藏在类的内部,有要求对外不可见的时候,就可以使用static. 静态变量的优点:1.节省内存.静态变量只存储一处,但供所有对象使用. 2.它的值是可以更新的. 3.可提高时间效率.只要某个对象对静态变量更新一次,所有的对象都能访问更新后的值. 2.全局变量extern 什么是全局变量:也称之为外部变量,是在方法外部定义的变量.它不属于哪个方法,而是

static修饰的静态变量与实例变量的区别,及其在初始化和内存中的运行机制详解

1. 静态变量的定义 静态变量(Static Variable)在计算机编程领域指在程序执行前系统就为之静态分配(也即在运行时中不再改变分配情况)存储空间的一类变量. 说明:静态变量(用static修饰),它所被分配的空间是一直伴随程序运行的,空间将会保持到程序的结束关闭,才会被释放. 2.用static修饰的静态变量与普通变量的区别 假若在定义一个类的过程中,定义了一个static修饰的变量,那么这个类在被加载的同时,被static修饰的变量就存在于内存当中了,这样一来就独立于该类的所有对象,

Objective-C中的const ,extern,static

一.const 1>对于const,记住关键的一点,它只是修饰右边的变量. 例如: - (void)viewDidLoad { [super viewDidLoad]; // const两种用法 // const:修饰基本变量p // 这两种写法是一样的,const只修饰右边的基本变量b const int b = 20; // b:只读变量 int const b = 20; // b:只读变量 // const修饰指针变量访问的内存空间,修饰的是右边*p1, // 两种方式一样 const

C语言中auto,register,static,const,volatile的区别

1)auto 这个关键字用于声明变量的生存期为自动,即将不在任何类.结构.枚举.联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量.这个关键字不怎么多写,因为所有的变量默认就是auto的. (2)register 这个关键字命令编译器尽可能的将变量存在CPU内部寄存器中而不是通过内存寻址访问以提高效率. (3)static 常见的两种用途: 1>统计函数被调用的次数; 2>减少局部数组建立和赋值的开销.变量的建立和赋值是需要一定的处理器开销的,特别是数组等含有较多元素的存储类

OC中extern,static,const的用法

1.const的作用: const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p). 例如 NSString *const SIAlertViewWillDismissNotification;修饰的是SIAlertViewWillDismissNotification 被const修饰的变量是只读的 2.static的作用: 修饰局部变量: 1.延长局部变量的生命周期,程序结束才会销毁. 2.局部变量只会生成一份内存,只会初始化一次. 3.改变局部变量的作用域. 修饰全局变量 1.只能在