c++中关于extern的理解
来源:互联网 发布:three.js 全景图 编辑:程序博客网 时间:2024/05/29 03:15
extern int i;/*这是声明*/int i;/*这是定义*/
虽然有人觉得第二行也是声明,但是根据c++ primer的说法,下面的确实是定义,因为这个时候i会被分配内存,而且声明是不会分配内存的。由分不分配内存作为声明和定义的判断标准的话,第二行确实是定义。
当然有的时候声明后也可以立即定义,如
extern int i = 1;/*这是声明+定义*/
在函数外部使用extern的时候,会非常容易。不过在函数内部使用extern(或许这样没什么意义),则会遇到很多让人迷惑的地方。
如下列代码:
void main(){ extern int i; i = 1;}
乍一看觉得这样的代码没什么问题,先声明,然后再定义,很正确。但是这样实际上是错误的,会报一个重定义的错误(redefinition)。
误认为这段代码正确的原因可能是这样:很多人觉得先声明后定义是一件很正常的事情,然而这却不一定。这里有个概念模糊,确切的声明是形如下列代码的
extern int i;
而形如下列代码的,不是声明
int i;extern int i = 1;
我们常说的先声明后定义,是指的这样的情况
int i;i = 1;
但这其实是错误的概念。因为“int i;”这样的语句并不是声明,而是定义。
与上面这种误解恰恰相反,在使用extern作为声明的时候,其实声明往往出现在定义之后,而且应该出现在定义之后
举个例子,在函数外部写如下声明代码
extern int i;
通常是在别的源文件中定义好了i后,才会写这样一句声明,表明要用的i来自别的文件,而且是已经被定义好的i。
而绝对不会先如上声明一次,然后在自己的源文件中又定义一次i(因为这样是多此一举)。所以说,声明往往是在定义之后的。
也就是说,见到了某个对象(如int i)的exten声明,往往代表i是已经被定义好了的。
也就是说,在效果上,声明≈定义。见到了某个对象的extern声明,代表这个对象已经被定义好了,就可以直接对其赋值或用其进行运算(当然之前要确保它是被初始化了的)。
理解了上面的,就能理解在函数体内怎么使用extern了。也能明白下面的代码错在哪了。
void main(){ extern int i; int i = 1;}
因为extern int i;相当于指明某处已经定义过一个i了,接下来又要int i = 1;这显然是重定义了。
改成这样就是没问题的:
void main(){ extern int i; i = 1;}
不过要注意,在适合的地方要确切存在i的定义
那么何谓适合的地方?
我们知道通常c++的作用域是被大括号括起来的,最外层没有被括起来的地方,是最大的作用域,在这里定义的变量是全局变量,可以被任何地方访问。当然访问不是没有限制的,其中一种方法就是通过extern声明。在程序的任何地方,只要是用extern声明了一个全局变量,那这个全局变量就变得可以访问了。因为全局变量的作用域是整个程序。也就是说,最外层没有被括号括起来的地方,是存在定义的适合的地方。
实际上,只有最外层才是适合的地方,因为extern其实只能声明全局变量。下面的代码就是错误的,因为i是局部变量。extern int i会试图找寻一个已经被定义的全局变量i,但是却没找到,所以会出现fatal error LNK1120: 1 unresolved externals (无法连接的外部变量)的错误。
int main(){ int i = 1;{extern int i;cout<<i;}return 0;}
下面的代码是正确的
int i = 3;int main(){ int i = 1;{extern int i;cout<<i;}return 0;}
而且输出的是3
代码改为为下面这样的话,输出的是1,原因是定义域。extern相当于在当前定义域中定义了一个变量,在这个定义域的外部是看不到这个变量的。
int i = 3;int main(){ int i = 1;{extern int i;cout<<i;}cout<<i;return 0;}
体会这几个例子,就能明白extern的一些特点。
1、使用于定义之后
2、只用于外部变量(即全局变量)
3、遵从普通变量的定义域划分规则
......
水平有限,又是特别仓促写的东西,有点不好理解请多包涵,有错误欢迎指正
- 关于extern “C”的理解
- c++中关于extern的理解
- C/C++ 中 extern 的个人理解
- extern "C"的理解
- extern "C"的理解
- extern "C"的理解
- 关于C中extern的说明
- 简单理解一道关于#ifndef 和extern "C"的题
- 关于C++中extern "C"{}
- C语言中extern关键字的使用和理解
- 关于C/C++中extern的使用心得
- 关于 extern "C" 的问题
- 关于extern "C" 的问题
- 关于extern "c"的写法
- 关于extern C的看法
- 深入理解C/C++混合编程(关于#ifdef __cplusplus extern "C" {...}的用法)
- C中extern的用法
- 深入理解extern "C" 的使用
- <DataStructure_1>用栈实现四则运算(c语言)
- iOS学习笔记总结整理
- 顺序串的实现
- 超链分析和PageRank
- android ListView和GridView拖拽移位具体实现及拓展
- c++中关于extern的理解
- go - 函数
- 关于接手项目的改进计划
- 通过show status 优化数据库性能
- POJ 2632 Crashing Robots
- 真机调试报错gen_entitlements.py: No such file or directory
- android图片处理方法(不断收集中)
- 一些经典排序算法的java实现
- 图的匹配问题与最大流问题(二)——最大流问题Ford-Fulkerson方法