extern关键字总结
【本文链接】
http://www.cnblogs.com/hellogiser/p/extern.html
【extern 变量/函数】
extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,有2种方式:
(1)extern告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数。
(2)extern说明变量或者函数声明在其他的源文件里,而不用include头文件的方式来引用该函数时,链接器在各个模块中搜索这个变量或者函数来进行最终链接。
与extern对应的关键字是 static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。
【extern_include方案】
extern 变量和函数的声明必须在B.h文件中,其定义必须在B.cpp文件中;在A.cpp中引用的时候要include "b.h"
例如MyClass.h
|
1
2 3 4 5 |
#pragma once
// method 1 |
MyClass.cpp
|
1
2 3 4 5 6 7 8 9 |
#include "StdAfx.h"
#include "MyClass.h" // method 1 definition |
如何在main.cpp中使用?
main.cpp
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include "stdafx.h"
#include <iostream> #include "MyClass.h" // extern int myA; extern int myAdd(int,int) using namespace std; void test_extern_include() void test_main() int main() |
【extern方案】
MyClass.h
extern 变量必须定义在B.h文件中,extern函数通常定义在B.cpp文件中,也可以定义在B.h文件中。在A.cpp中引用的时候要不能够添加include "b.h",但是要添加extern变量和函数声明。
MyClass.h
|
1
2 3 4 5 |
#pragma once
// method 2 |
MyClass.cpp
|
1
2 3 4 5 6 7 8 |
#include "StdAfx.h"
#include "MyClass.h" // method 2 definition |
main.cpp
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include "stdafx.h"
#include <iostream> //#include "MyClass.h" // extern int myA; extern int myAdd(int,int) using namespace std; extern int myB; void test_extern() void test_main() int main() |
【extern 变量】
在一个源文件里定义了一个数组:char a[6];
在另外一个文件里用下列语句进行了声明:extern char *a;
请问,这样可以吗?
答案与分析:
不可以,程序运行时会告诉你非法访问。原因在于,指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组,因此与实际的定义不同,从而造成运行时非法访问。应该将声明改为extern char a[ ]。
【extern 函数】
当函数提供方单方面修改函数原型时,如果使用方不知情继续沿用原来的extern申明,这样编译时编译器不会报错。但是在运行过程中,因为少了或者多了输入参数,往往会照成系统错误,这种情况应该如何解决?
答案与分析:
目前业界针对这种情况的处理没有一个很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供对外部接口的声明,然后调用方include该头文件,从而省去extern这一步。以避免这种错误。
【extern “C”】
在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况,应该如何解决这种情况呢?
答案与分析:
C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,这是一个用C写成的函数,请用C的方式来链接它们,不要生成用于链接的中间函数名。
带extern “C”的代码在处理函数名称时,直接使用函数的名称,不采用特别的方法生成一个中间函数名称;
而没有带extern ”C”的代码在处理函数名称时,使用特别方法生成一个中间函数名称。所以C++函数在使用C函数时,加上extern “C”才能正确的找到指定的函数。
【解决方案】
1.如果函数库没有考虑C++引用的情况,已生成库文件。我们在使用它的头文件时,可以如此使用可解决连接问题,这样时候后编译在引用cgi.h中的函数时,会按照C语言方式引用:
|
1
2 3 |
extern "C" {
#include "cgi.h" } |
2.如果要写一个C函数库,我们应当尽量采用如下书写方式,而避免C++用户出现1中的问题。
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// at the start of cgi.h
#ifdef __cplusplus extern "C" { #endif /* __cplusplus */ //============================ |
extern关键字总结的更多相关文章
- 16-static和extern关键字2-对变量的作用
上一讲介绍了static和extern对函数的作用,static用来定义一个内部函数,不允许其他文件访问:extern用来定义和声明一个外部函数,允许其他文件访问.static和extern对变量也有 ...
- 15-static和extern关键字1-对函数的作用
一.extern与函数 如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.obj可能会调用c.ob ...
- 【转载】C/C++中extern关键字详解
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- C++中extern关键字用法小结
总结C++中关于extern关键字的用法. 1.变量的生明和定义中 C++语言支持分离式编译机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译.为了将程序分为许多文件,则需要在文件中共享代码 ...
- 解决全局变量共享---C语言的extern关键字用法
在调试程序时,有一个参数需要在多个函数之间传递,因为是作为调试参数,不想将参数引入到函数中. 很自然的想到使用全局变量来表示这个公共参数,工程代码的结构如下: main.c test.c test.h ...
- C语言中的 extern 关键字
今天在 BLE 中看到很多 extern 关键字,现在总结一下: extern 关键字主要用于在一个c文件中要用到另一个c文件中的变量或者函数. example: #extern_base.c ; # ...
- 转载 浅谈C/C++中的static和extern关键字
浅谈C/C++中的static和extern关键字 2011-04-21 16:57 海子 博客园 字号:T | T static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.ext ...
- 浅谈C/C++中的static和extern关键字 转
原文:http://developer.51cto.com/art/201104/256820.htm static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.extern, &quo ...
- 关于全局变量和函数,在其他类中调用问题,extern关键字
1个工程下有几个类文件,和1个全局的文件comm.h, comm.h中存放了这几个类同时需要的变量和同时调用的函数. 当时,我只在comm.h中定义: int commData1: vector&l ...
- C语言的static和extern关键字
我的博客:www.while0.com 如果A.c要包含B.c里的一个变量或函数,则在A.c中要用extern关键字声明.注意: ①如果是包含的B.c里的函数,则在A.c里声明的时候可以不写exter ...
随机推荐
- JS精粹:下半部分
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- LightOJ1348 树链剖分
简单题,看题目就懂. #include<queue> #include<stack> #include<cmath> #include<cstdio> ...
- 10.Android之ProgressDialog进度对话框学习
APP应用中经常会下载某些东西,这里面有涉及到进度对话框,今天来学习下. 首先,布局里放进两个按钮,点击一个显示条形进度条,另一个显示圆形进度条.代码如下: <?xml version=&quo ...
- 模拟Modbus协议问题
问题: 在嵌入式系统开发中,Modbus协议是工业控制系统中广泛应用的一种协议.本题用来简单模拟Modbus协议,只需根据条件生成符合该协议的数据帧,并解析所获取的数据.假设设备使用的协议发送数据格式 ...
- BZOJ-1934 Vote 善意的投票 最大流+建图
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1551 Solved: 951 [Submit][S ...
- BZOJ-1012[JSOI2008]最大数maxnumber 线段树区间最值
这道题相对简单下面是题目: 1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MB Submit: 6542 Solve ...
- [转]基于overlayfs的硬盘资源隔离工具troot
原文在这里:http://blog.donghao.org/tag/overlayfs/ 某些开发测试团队会有这样的需求:多个开发或测试人员在一台物理机上搭环境.装rpm包.测试等,目录很可能互相干扰 ...
- 2016年4月7日 js的全选和反选
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title> ...
- eclipse中文乱码问题解决方案
eclipse之所以会出现乱码问题是因为eclipse编辑器选择的编码规则是可变的.一般默认都是UTF-8或者GBK,当从外部导入的一个工程时,如果该工程的编码方式与eclipse中设置的编码方式不同 ...
- UVa OJ 175 - Keywords (关键字)
Time limit: 3.000 seconds限时3.000秒 Problem问题 Many researchers are faced with an ever increasing numbe ...