extern关键字详细解释

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

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

1. 全局变量在.cpp中定义,在.hextern声明

如果没有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 __TEST1_H
#define __TEST1_H
extern char g_str[] = "123456"; // 声明&定义全局变量g_str
void fun1();
#endif
#include "test1.h"
void fun1() { cout << g_str << endl; }

然后test2.cpp也需要这个全局变量,就需要在源文件中include <test1.h>
  但这样会报连接错误,这是因为你把全局变量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
但这时想include <test1.h>就只能一个个extern了,很麻烦,所以最好在声明时解决这个问题,而不是使用时。方法如下:

1.2 只在.cpp中声明并定义

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

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

1.2 在.cpp中声明并定义,在.h中声明

这是很好的选择.

#ifndef __TEST1_H
#define __TEST1_H
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"

extern "C"   #告诉C++编译器,使用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语言方式编译和链接.

3.1 C++中引用C的函数变量:方法1(.C中加extern “C”)

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

/*Demo.h*/
#ifndef _DEMO_H_
#define _DEMO_H_
 
#ifdef  __cplusplus//如果在C++中就使用C方式编译,这样就和.c编译方式中一样了
extern "C" {
#endif

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

#endif
/*test.c*/
#include "test.h"
#include <stdio.h>
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;
}

在main函数引用头文件

/*main.cpp*/
#include "Demo.h"
#include <iostream>
using namespace std;
 
void main()
{
	int c = add(1, 2);
	printf("c = 1 + 2 = %d \n", c);
	system("pause");
}
3.2 C++中引用C的函数变量:方法2(.cpp中加extern “C”)

在包含头文件时添加extern "C",告知使用C语言方式编译该头文件,这样也就能和C的源文件保持编译方式一致。

/* c语言头文件:cExample.h */ 
  #ifndef C_EXAMPLE_H 
  #define C_EXAMPLE_H 
  int add(int x, int y); 
  #endif

  /* c语言源文件:cExample.c */ 
  #include "cExample.h" 
  int add(int x, int y) 
  { 
    return x + y; 
  }
-------------------------------------------------------------
  /* C++ main函数,包含cExample.h */ 
  extern "C" 
  { 
    #include "cExample.h"; 
  } 
  //或者extern "C" int add(int x, int y);
  int main() 
  { 
    add(2, 3); 
    return 0; 
  }
3.3 C中引用C++的函数和变量
  • 由于 C语言中不支持extern “C”,但#ifdef __cplusplus后可以使用
  • 所以还得在C++的头文件中给函数声明加上extern "C"
  • C不能直接引用声明了extern “C”的头文件
  • 所以不能像3.1那样直接包含头文件,
  • C.cpp中还必须将C++中定义的extern “C”函数声明为extern类型
/* c++头文件cppExample.h */ 
  #ifndef CPP_EXAMPLE_H 
  #define CPP_EXAMPLE_H 
  extern "C" int add(int x, int y); 
  #endif

  /* c实现文件cFile.c */ 
  extern int add(int x, int y); 
  int main() 
  { 
    add(2, 3); 
    return 0; 
  }
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
extern是C++语言中的一个关键字,其作用主要有以下两个: 1. 声明外部变量或函数 当我们在一个源文件中声明一个变量或函数时,如果我们想要在另一个源文件中使用这个变量或函数,就需要使用extern关键字来声明它是一个外部变量或函数。例如: ``` // file1.cpp int g_var = 0; extern void func(); // file2.cpp extern int g_var; void func() { g_var++; } ``` 在这个例子中,我们在file1.cpp文件中定义了一个全局变量g_var和一个函数func。由于我们希望在file2.cpp文件中使用这个全局变量和函数,所以我们在file1.cpp中使用extern关键字来声明它们是外部变量和函数。在file2.cpp文件中,我们同样使用extern关键字来声明g_var是一个外部变量,并在func函数中使用它。 2. 定义外部变量或函数 除了声明外部变量或函数之外,extern关键字还可以用来定义外部变量或函数。在这种情况下,我们需要在定义时使用extern关键字,并在后面加上初始化表达式。例如: ``` // file1.cpp extern int g_var = 0; extern void func() { g_var++; } // file2.cpp extern int g_var; extern void func(); int main() { func(); return g_var; } ``` 在这个例子中,我们在file1.cpp文件中定义了一个外部变量g_var和一个外部函数func。由于我们希望在file2.cpp文件中使用这个外部变量和函数,所以我们在file1.cpp中使用extern关键字来定义它们。在file2.cpp文件中,我们同样使用extern关键字来声明g_var和func是外部变量和函数,并在main函数中使用它们。 总的来说,extern关键字的作用是声明或定义外部变量或函数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值