C语言extern关键字
1.使用场景有两种情况
一种是对变量而言,另一种是对函数而言
1): 对变量而言
变量的声明有两种情况:一 是需要建立存储空间的,不用加extern;另外一种是不需要建立存储空间的,需要加extern。
如果想在本源文件中使用另外一个源文件的变量,就需要在使用前用 extern声明该变
量,或者在头文件中用extern声明该变量
2):对函数而言
对函数而言,如果想在本源文件中使用另一个源文件的函数,就需要在使用前对函数进行
声明,声明函数加不加extern都没关系,所以在文件中函数不用加extern。
2.注意事项
-
全局变量: 当你要引用一个全局变量时,extern关键词必须不能忘, 如果变量无 extern 修饰且没有显式的初始化,同样也变成了变量的定义,因此全局 变量在外部使用时,声明必须使用extern,如不加extern,编译器 在此标记存储空间,在执行时加载内存并初始化为0。注意以下几种全局变 量:
int a ;//定义一个全局变量a
extern int a ;//声明一个全局变量a
int a = 3;//定义一个全局变量并初始化为3
extern int a = 3;//定义一个全局变量并初始化为3
/******************************************************************
*举例验证全局变量被编译器初始化为0
******************************************************************/
#include <stdio.h>
int a;
int main(void)
{
printf ("a = %d\n",a);
return 0;
}
//程序运行的结果是a = 0;
-
局部变量的声明不能有extern的修饰,因为局部变量在运行时才在堆栈部 分分配内存。
/******************************************************************
*举例验证局部变量不能使用extern
******************************************************************/
#include <stdio.h>
int main(void)
{
extern int a = 3;
printf ("a = %d\n",a);
return 0;
}
//编译器提示错误:使用未初始化的内存“a”
3.extern "C"的用法
-
extern "C"是链接指示符 -
在C++源文件中的语句前面加上extern “C”,表明它按照类C的编译和连接规约来编译和连接,而不是C++的编译的连接规约。
-
注意:我在这里所说的类C,代表的是跟C语言的编译和连接方式一致的所有语言 -
如果程序员想在C++中调用其他程序设计语言(如C函数),那么需要在 调用函数时必须告诉编译器我们的要求。例如:C函数被C++调用,C++编译 器会导致c函数名或参数的名称或顺序发生变化,无论是C++函数调用它还 是用其他语言写的函数调用它,程序员用链接指示符linkage directive 告 诉编译器该函数是用其他的程序设计语言(C语言)编写的,链接指示符有两种形式 既可以是单一语句 single statement 形式也可以是复合语句compound statement 形式。
1):第一种形式
// 单一语句形式的链接指示符
extern "C" void exit(int);
- 第一种形式是由关键字extern 后跟一个字符串常量以及一个普通的函数构成。虽然函数是用另外一种语言(C语言或别的)编写的但他调用时,仍然需要类型检查。例如;编译器会检查传递给函数exit()的实参的类型是否是int 或者能够隐式地转换成int 型。
2):第二种形式
// 复合语句形式的链接指示符
extern "C" {
int printf( const char* ... );
int scanf( const char* ... );
}
// 复合语句形式的链接指示符
extern "C" {
#include <cmath>
}
- 第二种形式是由关键字extern后跟一个字符串常量以及多个普通的函数构成。花扩号的作用是分割符——表示链接指示符应用在花括号里的几个函数声明上。例如例子中复合语句extern "C"表示函数printf()和scanf()是用C 语言中写的,表示括号里的几个函数编译和连接时,应遵循C语言规则。
- 当复合语句链接指示符的括号中含有#include 时,作用是——在头文件中声明的函数都被编译器认为是用链接指示符(本文是c语言)的程序设计语言所写的,在上述例子中头文件中声明的函数都是C函数链接指示符。
3):注意:
extern不能出现在函数体中,如下列代码段将会导致编译错误。
int main()
{
// 错误: 链接指示符不能出现在函数内
extern "C" double sqrt( double );
305 第七章函数
double getValue(); //ok
double result = sqrt ( getValue() );
//...
return 0;
}
如果把链接指示符移到函数体外程序编译将无错误
extern "C" double sqrt( double );
int main()
{
double getValue(); //ok
double result = sqrt ( getValue() );
//...
return 0;
}
4): 附加说明
- 在本节中我们只看到为C 语言提供的链接指示extern “C”,但是每个编译器实现都可为其环境下常用的语言提供其他链接指示,例如extern "Ada"可以用来声明是用Ada 语言写的函数,extern "FORTRAN"用来声明是用FORTRAN 语言写的函数,等等因为其他的链接指示随着具体实现的不同而不同所以建议读者查看编译器的用户指南以获得其他链接指示符的进一步信息。
本文详细介绍了C语言中extern关键字的使用,包括两种情况:声明变量和引用外部函数。讲解了extern "C"的用法,如何在C++中按照C语言规则编译和链接。并强调了extern不能出现在函数体内的注意事项。

1万+

被折叠的 条评论
为什么被折叠?



