曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 3720|回复: 0
打印 上一主题 下一主题

extern 关键字(限定符)

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2011-8-10 18:47:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如果程序有两个或多个文件组成,那么每个文件都必须知道程序中使用的所有全局变量的名字和类型。但是,并不能简单地在每个文件中声明全局变量的副本。原因是,在 C++ 中每个全局变量在程序中只能有一个副本。因此,试图在每个文件中都声明所需的全局变量将产生链接错误。当链接器将所有产生的目标文件链接在一起时,它将会发现重复的全局变量,因此不能链接程序。

解决上面问题的方法是,在一个文件中声明所有的全局变量,而在其它的文件中使用 extern 来声明所需要的全局变量。

如下面程序,先看其未用 extern 来声明会发现什么样的编译错误:

extern1.cc
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;

int x = 10;
int y = 20;

void func2();
int main()
{
        func2();
        return 0;
}

extern2.cc
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;

int x, y;
void func2()
{
        cout << "use extern1.txt var x = " << x << '\n';
        cout << "use extern1.txt var y = " << y << '\n';

}

编译这两个文件会发现:
[beyes@centos C]$ vi extern2.cc
[beyes@centos C]$ g++ extern1.cc extern2.cc -o main
/tmp/ccClQsis.o:(.bss+0x0): multiple definition of `x'
/tmp/ccw6fzMj.o:(.data+0x0): first defined here
/tmp/ccClQsis.o:(.bss+0x4): multiple definition of `y'
/tmp/ccw6fzMj.o:(.data+0x4): first defined here
从错误信息中知道,x 和 y 被重复定义了。

修正办法是在 extern2.cc 中的 int x, y; 前面使用 extern 关键字,即  extern int x, y;

另外需要注意的一个问题时,在 extern1.cc 中 void func2(); 这句话不可少,否则编译时会提示 func2() 函数未声明 (编译器为 g++):
[beyes@centos C]$ g++ extern1.cc extern2.cc -o main
extern1.cc: In function ‘int main()’:
extern1.cc:10: 错误:‘func2’ 在此作用域中尚未声明
但是如果使用的是 gcc 来编译相应的 C 语言程序,则不需要做这种声明,且不会出错。

extern 可以让编译器知道全局变量的名字和类型,但并不会再次为它们分配内存。当链接器将两个文件模块链接时,就可以确定所有使用到的外部变量。

上面的是 extern 关键字的一种用法。还有另外一种用法,看下面一段程序:
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;

int main()
{
        extern int x, y;

        cout << "using var defined after main: x = " << x << " y = " << y << '\n';

        return 0;
}

int x = 10;
int y = 20;

上面程序中,变量 x 和 y 定义在 main() 之后,如果在 main() 中不使用 extern 来声明 x 和 y,那么编译会出错。当然,x 和 y 若是定义在 main() 之前,那么是没必要使用 extern 的。

总之,如果编译器发现某个变量没有被定义在当前的代码块中,那么它将会检查变量是否匹配在当前代码块所在程序中声明的其它变量,如果还是没发现,那么编译器将检查在前面定义过的全局变量。如果找到匹配的变量定义,编译器就会假设当前代码块中使用的就是这个变量。只有当你希望使用一个在文件后面部分定义或者在其它文件中定义的变量时,才需要使用关键字 extern  。

一个变量可以被多次声明,但只能被一次定义!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-18 00:05 , Processed in 0.084866 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表