C/C++ extern关键字

在阅读代码的时候经常遇见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)" ([email protected]@[email protected]),该符号在函数 _main 中被引用。[email protected]@[email protected]就是编译器自动扩展的函数名了。

如果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关键字

时间: 2024-10-25 11:33:03

C/C++ extern关键字的相关文章

19-C语言static和extern关键字2-对变量的作用

一.在Java中,全局变量的定义没有严格的位置规定 全局变量可以定义在类的最前面,也可以定义在类的最尾端,也就说一个方法可以访问在它之后定义的变量. 可以看到,第4行定义的test方法可以访问第8行定义的变量a,这是完全没有问题的. 二.在C语言中,全局变量定义的位置是有限制的 默认情况下,一个函数不可以访问在它后面定义的全局变量 在第4行定义的main函数中尝试访问第9行定义的变量a,编译器直接报错了. 解决这个错误的话,有2种办法: 第1种办法:将变量a定义在main函数的前面 这样做编译器

16-static和extern关键字2-对变量的作用

上一讲介绍了static和extern对函数的作用,static用来定义一个内部函数,不允许其他文件访问:extern用来定义和声明一个外部函数,允许其他文件访问.static和extern对变量也有作用,不过跟函数有点差别. C语言和Java都有全局变量的概念,但是它们的用法还是有些差别的. 一.在Java中,全局变量的定义没有严格的位置规定 全局变量可以定义在类的最前面,也可以定义在类的最尾端,也就说一个方法可以访问在它之后定义的变量. 可以看到,第4行定义的test方法可以访问第8行定义的

C语言中的 extern 关键字

今天在 BLE 中看到很多 extern 关键字,现在总结一下: extern 关键字主要用于在一个c文件中要用到另一个c文件中的变量或者函数. example: 1 #extern_base.c 2 3 int a = 100; 1 #extern.h 2 3 extern int a; 1 #extern.c 2 3 #include <stdio.h> 4 #include "extern.h" 5 6 int main() 7 { 8 printf("%d

18-C语言static和extern关键字1-对函数的作用

一.extern与函数 在第三讲和第四讲中,我提到过一句话:如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.obj可能会调用c.obj中定义的一个函数.将这些相关联的目标文件链接在一起后才能生成可执行文件. 先来理解2个概念: 外部函数:如果在当前文件中定义的函数允许其他文件访问.调用,就称为外部函数.C语言规定,不允许有同名的外部函数. 内部函数:如果在当前文件中定义的函数不允许其他文件访问

(转)extern关键字两种场景的使用

第一种场景 -- extern extern关键字的作用是声明变量和函数为外部链接,即该变量或函数名在其它文件中可见.用其声明的变量或函数应该在别的文件或同一文件的其它地方定义. 例如语句:extern int a;仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间.变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误.通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明.例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需

extern关键字的使用

A.置于变量或者函数前,以标示变量或者函数的定义在别处,提示编译器遇到此变量和函数时在其他地方寻找其定义. B.可用来进行链接指定. 1.使用extern声明外部变量 1.1在一个文件内声明外部变量 外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾.编译时将外部变量分配在静态存储区. 如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件结束.如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量作"外部变量声

【转】C语言正确使用extern关键字

利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数,下面就结合具体的实例,分类说明一下. 一.引用同一个文件中的变量 1 #include<stdio.h> 2 3 int func(); 4 5 int main() 6 { 7 func(); //1 8 printf("%d",num); //2 9 return 0; 10 } 11 12 int num = 3; 13 14 int func() 15 { 16 printf("%

extern关键字的一般用法

extern关键字会提升变量或者函数的逼格,使得它们可以跨文件被访问.话虽然是这么说,使用这个关键字必须要注意一些东西. 首先,你得在cpp文件里面实现这些全局变量和全局函数,这是最基本的,然后只需要在需要用到这些变量和函数的文件里声明一下,用extern修饰声明,这样弄完之后就可以随意使用这些全局变量和全局函数了.请不要为编译器担心,担心它们找不到这些东西,只要你实现了,不怕编译器找不到. 在别的文件里写一堆的extern声明显得特别不专业,也显得代码十分臃肿,有没有好的做法呢?有的. 我们一

C++(extern关键字的理解和作用深入)

extern关键字的理解和作用深入 extern是一个关键字,它告诉编译器存在着一个变量或者一个函数,如果在当前编译语句的前面中没有找到相应的变量或者函数, 也会在当前文件的后面或者其它文件中定义 引文一.(主要是实战中的各种情况)http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html 1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找

15-static和extern关键字1-对函数的作用

一.extern与函数 如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.obj可能会调用c.obj中定义的一个函数.将这些相关联的目标文件链接在一起后才能生成可执行文件. 先来理解2个概念: 外部函数:如果在当前文件中定义的函数允许其他文件访问.调用,就称为外部函数.C语言规定,不允许有同名的外部函数. 内部函数:如果在当前文件中定义的函数不允许其他文件访问.调用,只能在内部使用,就称为内部函