栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

extern关键字详细解释

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

extern关键字详细解释

  extern 可以置于变量或者函数前,以表示这个变量或函数别的文件中定义,提示编译器在遇到此变量或函数的时候在其他模块寻找其定义。
主要使用方式有两种:

  1. 如果函数的声明中带有extern,说明这个函数定义在其他文件中,这样的好处是可以取代include"**.h",在一些复杂的项目中这样使用比较方便。最好的做法是全部函数声明前添加extern.
  2. extern "C"支持C/C++混合编译
1. 全局变量在.cpp中定义,在.h中extern声明

如果没有extern,对于 int a;和int a = 0;,即是定义也是声明
但是有了ertern以后

extern int a;//声明全局变量a,只是声明,且这个全局变量已经被声明&定义过
int a; //声明&定义全局变量a

extern int a =0 ;//声明&定义全局变量a 并给初值。
int a =0;//声明&定义全局变量a,并给初值,
1.1 首先来看在.h中声明并定义的问题: 导致编译冲突
#ifndef TEST1H
#define TEST1H
extern char g_str[] = "123456"; // 声明&定义全局变量g_str
void fun1();
#endif
#include "test1.h"
void fun1() { cout << g_str << endl; }

然后test2.cpp也需要这个全局变量,就需要在源文件中include
  但这样会报连接错误,这是因为你把全局变量g_str的定义放在了头文件之后,test1.cpp这个模块包含了test1.h所以定义了一次g_str,而test2.cpp也包含了test1.h所以再一次定义了g_str,这个时候连接器在连接test1和test2时发现两个g_str.
解决方法:
在test2.cpp中extern char g_str[];,而不用include

1.2 在.cpp中声明并定义的的问题:后面引用必须extern

还有一个问题,如果全局变量在test1.cpp中声明&定义,那么在test2.cpp中再include也没用,这时必须在test2.cpp中extern char g_str;

给程序员的建议就是全局变量使用时,对他声明定义&初始化,这通常会在.cpp中声明和定义

另外一种做法:

#ifndef TEST1H
#define TEST1H
extern char g_str[]; // 声明&定义全局变量g_str
void fun1();
#endif
#include "test1.h"
char g_str[] = "123456"
void fun1() { cout << g_str << endl; }
1.3 总结
  • 头文件中声明并定义全局变量,当其他文件include这个文件时,会编译错误
  • 实际上用到这个全局变量的地方可能很多,使用时每个文件都需要include,所以把声明和定义都放在.cpp,使用的时候extern,而不extern可能也是不错的选择。这时候可以include也不会报错.
  • 但全局变量和定义都放在.h中绝对不可取.
2. extern函数 3. extern "C"

  C++为了多态,编译时会将函数名和参数联合生成一个中间函数名,例如为了支持函数重载,C++会将void foo(int x, int y)编译为_foo_int_int之类的名字,C编译后在符号库中的名字则为_foo,混合编译时二者产生差异。
  我们是在main.cpp文件里包含了test.h,这些函数在main.cpp里,所以会被C++编译一个中间函数名,而test.c里面的实现会被C编译器处理,所以main就找不到test.c的函数.
这个时候就必须用extren "C"了,告诉C++编译器,请使用C语言方式编译和链接.

我们将test.h里面的东西改一下写法即可:

#ifndef _DEMO_H_
#define _DEMO_H_
 
#ifdef  __cplusplus
extern "C" {
#endif

	extern int a;
	extern int b;
	int add(int a, int b);
	
#ifdef  __cplusplus
}
#endif

#endif
//#include "test.h"
#include 
int a = 10;
int b = 20;
 
 int add(int l, int r)
{
#ifndef __cplusplus //C++
	printf("这是一个c程序!n");
#endif

#ifdef __cplusplus //C
	printf("这是一个c++程序!n");
#endif
	return l + r;
}
#include "Demo.h"
#include 
using namespace std;
 
void main()
{
	int c = add(1, 2);
	printf("c = 1 + 2 = %d n", c);
	system("pause");
}
3.1 C++中引用C的函数变量

在包含头文件时添加extern "C"

 
  #ifndef C_EXAMPLE_H 
  #define C_EXAMPLE_H 
  extern int add(int x, int y); 
  #endif

   
  #include "cExample.h" 
  int add(int x, int y) 
  { 
    return x + y; 
  }

   
  extern "C" 
  { 
    #include "cExample.h"; 
  } 
  int main() 
  { 
    add(2, 3); 
    return 0; 
  }
3.2 C中引用C++的函数和变量
  • 由于 C语言中不支持extern “C”
  • 所以还得在C++的头文件中给函数声明加上extern "C"
  • C不能直接引用声明了extern “C”的头文件
  • 所以不能像3.1那样直接包含头文件,
  • C.cpp中还必须将C++中定义的extern “C”函数声明为extern类型

C中不能包含

 
  #ifndef CPP_EXAMPLE_H 
  #define CPP_EXAMPLE_H 
  extern "C" int add(int x, int y); 
  #endif

   
  extern int add(int x, int y); 
  int main() 
  { 
    add(2, 3); 
    return 0; 
  }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/396146.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号