C++:extern关键字

extern “C”

它的作用并是直接使用C语言编译器而是让C++编译器在编译阶段按照C语言的标准产生函数的符号名,它只会限制重载不会影响其它的任何特性,让 C++中的函数名具备 C-linkage 性质。
注意:它的作用对象是函数声明不包含函数定义,因而被extern "C"声明的函数内能够随意访问外部函数

extern "C"{
	void fun(){
		auto fun=[](){std::cout<<"ok";};
		fun();
	}
}
int main(){
	fun();//输出ok
}

extern全局声明

extern在C和C++中都可以用于声明全局实例,但是二者使用上有一定的差异

  • C语言中的链接更加宽泛,你在多个文件中定义同名的全局变量,编译器会将它们视为同一个变量。这是因为C语言中全局变量的定义不会引发链接错误,而是会在链接阶段将这些定义合并在一起,由于C++具有更强的类型检查和更严格的链接规则,对同一变量的多次定义通常会导致链接错误。这是C和C++在处理全局变量定义的链接性上的一个主要区别。
//data.c
int a=10;
//main.c
int a=20;
int main(){}
//运行成功
//data.cpp
int a;
//main.cpp
extern int a;
int main(){}
//只能定义一次,在别的文件使用必须加extern
  • C语言中全局函数定义完不声明也可以在别的文件中直接使用,编译器会假定函数的默认声明,即返回类型为int,无参数,但是C++由于引入了重载不允许这种隐式声明所以需要手动声明

实际上C语言的隐式声明会有问题

//function.c
#include<stdio.h>
void fun(int a){
	printf("%d",a);
}
//main.cpp
int main(){
	fun();//调用成功输出3805224,可能是某一存储区域的默认值
}

C++中使用extern注意点:

  • 在头文件中只做声明不做定义,头文件可能多次引入避免重复定义全局实例
  • 记得定义,否则使用仅声明的变量时会造成运行错误
  • extern声明不要和定义一起进行,一起进行extern会失效,没有实际意义不符合代码规范

extern和static的区别

(1) extern 表明该变量在别的地方已经定义过了,在这里要使用那个变量.
(2) static 表示静态的变量,分配内存的时候, 存储在静态区,不存储在栈上面.
extern是声明全局实例,static是创建局部全局实例(仅当前文件可用别的文件识别不到),extern和static水火不容

//test1.cpp
static int a;
//test2.cpp
static double a;
//运行成功,不属于重定义

定义static全局变量不要在头文件中进行

//head.h
#include<iostream>
static int a=10;
//test1.cpp
#include"head.h"
void fun1(){
	std::cout<<&a<<std::endl;
}
//test2.cpp
#include"head.h"
void fun2(){
	std::cout<<&a<<std::endl;
}
//main.cpp
void fun1();
void fun2();
int main(){
	fun1();
	fun2();
}

运行时会发现两个函数返回结果相同,但这并不意味着static具有外部链接性,这是编译器优化的结果,你只需要在某一个函数中对a进行修改返回值就不一样了,因此要避免在头文件中定义static全局变量避免造成混淆

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值