码迷,mamicode.com
首页 > 编程语言 > 详细

C/C++ extern关键字

时间:2014-07-31 05:22:35      阅读:338      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   使用   os   strong   文件   io   

在阅读代码的时候经常遇见extern关键字,由于平时接触很少一般没用到所以不是很熟,这里特别学习一下。

首先得熟悉C++中声明与定义的概念。

变量的定义用于为变量分配存储空间,还可以为变量指定初始值,在一个程序中变量有且仅有一个定义

变量的声明用于向程序表面变量的类型和名字。

定义也是声明:当定义变量时我们声明了它的类型和名字,这时可以用extern关键字声明变量名而不定义它

extern int i;    //声明但是不定义i
int i;           //声明且定义i

extern声明不是定义也不分配存储空间,它只是说明变量定义在程序的其他地方,程序中变量可以声明多次,但只能定义一次

extern double pi = 3.14;   //定义
double pi;                 //错误!重复定义
extern double pi = 3.14;   //定义
extern double pi;          //正确!可重复声明
extern double pi = 3.14;   //错误!重复定义

变量定义在程序的其他地方也就代表了可以在其他.cpp文件中定义,只需要进行extern声明就可以使用。比如有2个.cpp文件:test1.cpp test2.cpp,在test1.cpp中定义int i = 0;在test2.cpp中只需要加上extern int i;就可以使用test1.cpp中的i。但同时,如果在相同作用域内在定义int i;就会出现重复定义错误比如:

// test1.cpp
int i = 0;

// test2.cpp
extern int i;
int i = 1;      //报错,重复定义

因此需要重新定义一个int类型变量i可以定义为局部变量

// test1.cpp
int i = 0;

// test2.cpp
#include <iostream>
extern int i;

int main()
{
    int i = 1;
    std::cout << i << std::endl;
    system("pause");

    return 0;
}

此时输出结果为1

函数以及类的声明和定义也一样可以用extern来声明在外部定义,其实这么做有什么好处呢?比如在a.h定义了全局变量int i = 0;若a1.cpp和a2.cpp中同时include "a.h"则编译不成功,因为i重复定义。这时就会出现非常常见的这种报错fatal error LNK1169: 找到一个或多个多重定义的符号。解决方式如下:

// a.h
int i = 0;

// a1.cpp
#include "a.h"

// a2.cpp
extern int i;

也就是如果有一个.cpp文件包含了.h文件,那么相当于该cpp文件里定义了int i;那么在其他文件中要使用这个全局变量就只需要使用extern int i;进行外部声明即可。注意,如果去掉了包含a.h的a1.cpp,那么编译失败,因为找不到i的定义,因为.h文件并不能单个编译。所以实际编程的时候.h和.cpp都是成对出现,往往包含了一个类的声明和定义。也避免去寻找是否有.cpp文件包含了该.h文件。

 

其实在C和C++混合编程的时候,extern更多的是用在C++里调用C函数。

在C++里,为了实现函数重载,你定义两个函数void fun(int); void fun(double);在调用它时其实相当于定义了两个函数void fun_int(int); void fun_double(int);当然这里只是举例,实际情况不知道改成了什么名字,但肯定不是fun本身。而C语言没有重载的特性,在.cpp中调用.c中的fun()就会因为无法识别函数名出错。

为了使用C语言定义的函数通常使用以下语法

extern "C"

{

  // C语言定义的变量和函数

}

// a1.c
#include <stdio.h>

void fun(int i)
{
    printf("%d\n", i);
}

// a2.cpp
#include <iostream>

extern "C"
{
    void fun(int);
}

int main()
{
    fun(1);
    system("pause");
    return 0;
}

以上代码如果在a2.cpp中直接extern void fun(int);再运行会报错a2.obj : error LNK2019: 无法解析的外部符号 "void __cdecl fun(int)" (?fun@@YAXH@Z),该符号在函数 _main 中被引用。fun@@YAXH@Z就是编译器自动扩展的函数名了。

如果C函数是在头文件中定义只需 extern "C" { #include "a.h" }即可,a.h为.c文件包含的头文件。

 

而在C语言中调用C++的函数,那么在.cpp中为要在.c中调用的函数名前加上extern "C"即可,示例如下

// a2.cpp
#include <iostream>

extern "C" 
{
    void fun(int);
    void fun2(double);
};

void fun(int i)
{
    printf("%d\n", i);
}

void fun2(double x)
{
    printf("%lf\n", x);
}

// a1.c
#include <stdio.h>

extern void fun(int);
extern void fun2(double);

int main()
{
    fun(1);
    fun2(1.2);

    return 0;
}

输出结果为

1

1.200000

C/C++ extern关键字,布布扣,bubuko.com

C/C++ extern关键字

标签:style   blog   color   使用   os   strong   文件   io   

原文地址:http://www.cnblogs.com/HarleyQuinn/p/3879832.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!