-
C++extern声明的外部变量 | 使用extern输出
2020-11-30 17:01:33在此作用域内,全局变量可以为本文件中各个函数所引用。编译时将全局变量分配在静态存储区,有时需要用extern来声明全局变量,以扩展全局变量的作用域。 C++文件内声明全局变量 如果外部变量不在文件的开头定义,其...C++外部变量
上一节有读者咨询extern是什么,这节主要用来解释一下extern在C++中的用法,外部变量在函数的外部定义的,它的作用域为从变量的定义处开始,到本程序文件的末尾。
在此作用域内,全局变量可以为本文件中各个函数所引用。编译时将全局变量分配在静态存储区,有时需要用extern来声明全局变量,以扩展全局变量的作用域。
C++文件内声明全局变量
如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。
如果在定义点之前的函数想引用该全局变量,则应该在引用之前用关键字extern,对该变量作外部变量声明,表示该变量是一个将在下面定义的全局变量。
有了声明,就可以合乎规则地引用该全局变量,这种声明称为提前引用声明。
C++多文件程序声明外部变量
如果一个程序包含两个文件,在两个文件中都要用到同一个外部变量,不能分别在两个文件中各自定义一个外部变量。
正确的做法是:在任一文件中定义外部变量,而在另一文件中用extern对该变量作外部变量声明。
用extern扩展全局变量的作用域,虽然能为C++编码带来方便,但应十分慎重,因为在执行一个文件中的函数时,可能会改变了该全局变量的值,从而会影响到另一文件中的函数执行结果。
经典案例:C++实现用extern对外部变量作引用声明。
源码分析:
#include<iostream>//头文件 using namespace std;//命名空间 int Max(int num1,int num2);//函数声明 int num1=10,num2=5;//定义全局变量 int main() //主函数 { extern int num1,num2;//对全局变量num1,num2做引用声明 cout<<"较大的值是:"<<Max(num1,num2)<<endl; } int Max(int num1,int num2)//自定义求两个数中的较大值 { int temp;//定义一个中间变量 if(num1>num2)//判断条件 { temp=num1; } else { temp=num2; } return temp;//函数返回值为temp }
编译后的结果:
较大的值是:10 -------------------------------- Process exited after 0.07294 seconds with return value 0 请按任意键继续. . .
更多案例可以go公众号:C语言入门到精通
-
c 编程中extern关键字 使用跨文件全局变量
2020-09-26 12:02:24全局变量可以为本文件中的其他函数所共用,它的有效范围为从定义变量的位置开始到本源文件结束。 然而,如果全局变量不在文件的开头定义,有效的作用范围将只限于其定义处到文件结束。如果在定义点之前的函数想引用...我们知道,程序的编译单位是源程序文件,一个源文件可以包含一个或若干个函数。在函数内定义的变量是局部变量,而在函数之外定义的变量则称为外部变量,外部变量也就是我们所讲的全局变量。它的存储方式为静态存储,其生存周期为整个程序的生存周期。全局变量可以为本文件中的其他函数所共用,它的有效范围为从定义变量的位置开始到本源文件结束。
然而,如果全局变量不在文件的开头定义,有效的作用范围将只限于其定义处到文件结束。如果在定义点之前的函数想引用该全局变量,则应该在引用之前用关键字 extern 对该变量作“外部变量声明”,表示该变量是一个已经定义的外部变量。有了此声明,就可以从“声明”处起,合法地使用该外部变量。#include <stdio.h> int max(int x,int y); int main(void) { int result; /*外部变量声明*/ extern int g_X; extern int g_Y; result = max(g_X,g_Y); printf("the max value is %d\n",result); return 0; } /*定义两个全局变量*/ int g_X = 10; int g_Y = 20; int max(int x, int y) { return (x>y ? x : y); }
代码中,全局变量 g_X 与 g_Y 是在 main 函数之后声明的,因此它的作用范围不在 main 函数中。如果我们需要在 main 函数中调用它们,就必须使用 extern 来对变量 g_X 与 g_Y 作“外部变量声明”,以扩展全局变量的作用域。也就是说,如果在变量定义之前要使用该变量,则应在使用之前加 extern 声明变量,使作用域扩展到从声明开始到本文件结束。
如果整个工程由多个源文件组成,在一个源文件中想引用另外一个源文件中已经定义的外部变量,同样只需在引用变量的文件中用 extern 关键字加以声明即可。下面就来看一个多文件的示例:/****max.c****/ #include <stdio.h> /*外部变量声明*/ extern int g_X ; extern int g_Y ; int max() { return (g_X > g_Y ? g_X : g_Y); } /***main.c****/ #include <stdio.h> /*定义两个全局变量*/ int g_X=10; int g_Y=20; int max(); int main(void) { int result; result = max(); printf("the max value is %d\n",result); return 0; }
运行结果为:
the max value is 20
对于多个文件的工程,都可以采用上面这种方法来操作。对于模块化的程序文件,可在其文件中预先留好外部变量的接口,也就是只采用 extern 声明变量,而不定义变量,max.c 文件中的 g_X 与 g_Y 就是如此操作的。
通常,这些外部变量的接口都是在模块程序的头文件中声明的,当需要使用该模块时,只需要在使用时具体定义一下这些外部变量即可。main.c 里的 g_X 与 g_Y 则是相关示例。
不过,需要特别注意的是,由于用 extern 引用外部变量,可以在引用的模块内修改其变量的值,因此,如果有多个文件同时要对应用的变量进行操作,而且可能会修改该变量,那就会影响其他模块的使用。因此,我们要慎重使用。 -
c语言中变量的存储区域和时效
2015-01-23 11:33:05参考:C程序设计,谭浩强 一,大分类(从存储空间) ...1:局部变量 ...在一个{ }之内定义的变量,作用区域只限于这个符号范围之内,通常包含的{ }有一...定义在函数体外部的变量,作用范围为本文件(一个c语言文件,参考:C程序设计,谭浩强一,大分类(从存储空间)1:局部变量在一个{ }之内定义的变量,作用区域只限于这个符号范围之内,通常包含的{ }有一个函数,主函数子函数等等,while,for循环等等。(关于for循环括号中定义的变量,作用区域多大,好像是根据编译器不同而不同,最好只在本循环内使用。)2:全局变量定义在函数体外部的变量,作用范围为本文件(一个c语言文件,即是以“.c”结束的文件)变量定义的地方到此文件结束的区域。如果定义在文件末尾,那么上面就不能用啦。所以最好将一个文件的全局变量放在预编译文件之后的地方,省的编译问题。二:变量的存储类别(变量的存在时间)用户可以使用的区域依次为:1,程序区;2,静态存储区;3,动态存储区静态存储区:固定的存储区域,主要存放1:全局变量2:使用static申明的局部变量(静态局部变量只在编译的时候赋初始值,默认为零,之后每次运行到此子函数使用的值是上次使用的时候计算的结果)动态存储区:程序运行过程中动态分配的存储空间,主要存放1:未声明或者使用auto声明的局部变量(因为局部变量默认就是auto型的,这里的变量就是每次调用就赋初始值,默认不确定)2:函数的形式参数,其实也是子函数(被调用函数的局部变量,至少可以这样理解,都是出了这个函数就无效了)3:函数调用的现场保护和返回地址(子函数调用的时候,会将父函数的一些变量暂时压入栈中进行保护)寄存器存储区:在一个函数运行过程中,有些变量需要高频率使用而加的一种声明方式但是它只能声明使用动态存储的局部变量(我觉得这是合理的,因为寄存器资源十分珍贵,不可能任由静态存储的一些变量总是霸占着,这是资源的浪费)extern声明方式:适用于需要在其他文件中使用的全局变量,在本文件定义,在需要使用的其他文件声明即可使用。但是这引入一个问题,有些全局变量并不想被其他文件使用,那么只需在本源文件定义出加上静态static声明即可。三:关于声明和定义程序有声明和执行两部分组成,声明根据是否分配存储空间分为两类一类是分配存储空间的声明,俗称定义;一类是不分配存储空间的声明,俗称声明。例如:文件A中,定义全局变量int a;//这个语句执行的结果是在静态存储区给a分配了32bit,也就是4个字节的存储空间供它使用文件B中,想要使用a,因此添加了语句 externa a;//此处的语句,不分配存储空间,仅仅是一个声明。四:内部函数和外部函数默认情况下,文件中定义的函数为外部函数,即其他文件的父函数想要使用此函数,只需要相应的声明之后就可以使用了但是有些情况下,不希望函数被其他文件的函数调用,即使该父函数声明了也不能使用,这就需要在函数定义的时候加上static的声明标签。五:个人小结:关于上述基础知识就没有多说的必要了,仔细体会即可,这个时候我们主要将这些东西与c++做一些类比在c++中关于声明有两个关键字:public,private;对比此处的extern 和 static 似乎是很有一番相似之处,可以仔细体会,这里的一个文件做单元,换到c++中就是以一个class做单元。具体的问题,由于本人目前c++只是浅陋,留待后文。 -
C/C++中的extern的使用
2016-07-14 22:52:49一、用extern声明外部变量 外部变量是在函数的外部定义的全局变量,它的作用域是...如果外部变量不在文件的开头定义,其有效范围只限于定义处到文件结束。如果在定义点之前的函数想要引用该外部变量,则应该在应用之一、用extern声明外部变量
外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。有时需要用extern来声明外部变量,以扩展外部变量的作用域。1、在一个文件内声明外部变量
如果外部变量不在文件的开头定义,其有效范围只限于定义处到文件结束。如果在定义点之前的函数想要引用该外部变量,则应该在应用之前用关键字extern对该变量作“外部变量声明”,表明该变量是一个已经定义的外部变量。有了此声明,就可以从“声明”处起,合法地使用该外部变量。例如:#include<stdio.h> void main() { int max(int,int); extern A,B;//外部变量声明; printf("%d\n",max(A,B)); } int A=13,B=-8;//定义外部变量 int max(int x,int y)//定义函数 { int z; z=x>y?x:y; return(z); }
用extern声明外部变量时,类型名可以省略,也可以写。2、在多文件的程序中声明外部变量
一个C程序可以有一个或者多个源程序文件组成。如果一个程序包含两个文件,在这两个文件中都要用到同一个外部变量Num,不能分别在两个文件中各自定义一个外部变量Num,否则在进行程序连接时会出现“重复定义”的错误。正确的做法:在任一个文件中定义外部变量Num,而在另一个文件中用extern对Num作“外部变量声明”。即“extern Num”。在编译与连接时,系统会有此知道Num是一个已经在别处定义的外部变量,并将在另一个文件中定义的外部变量的作用域扩展到本文件,在本文件中可以合法地引用外部变量Num。//文件file1.c中的内容 #include<stdio.h> int A;//定义外部变量 void main() { int power(int); int b=3,c,m; printf("enter the number a and its power m :\n"); scanf("%d,%d",&A,&m); c=A*b; printf("%d*%d",A,b,c); } //以下为file2.c中的内容: extern A;//声明A为一个已定义的外部变量,声明完成后本文件内可以使用; int power(int n) { int i,y=1; for(i=1;i<=n;i++) { y *=A; } return(y); }
extern声明的外部变量扩展的到本文件使用,它的定义在其他地方,注意声明与定义的区别。下面的内部函数与外部函数也是一样。二、内部函数与外部函数
函数本质上是全局的,因为一个函数要被另一个函数调用,但是也可以指定函数不能被其他文件调用。根据能否被其他文件调用,将函数区分为内部函数与外部函数。1、内部函数
如果一个函数只能被本文件中其他函数所调用,它称为内部函数。在定义内部函数时,函数名和函数类型的前面加上static。内部函数也称静态函数,因为它的声明用static使用内部函数只局限于所在文件。通常把只能由同一文件使用的函数和外部变量放在一个文件中,在它们的前面都冠以static使之局部化,其他文件不能使用。2、外部函数
(1)在定义函数时,如果在函数的首部的最左端加上关键字extern,则表示此函数是外部函数,可供其他文件调用。如函数首部可以这样写extern int fun(int a,int b);这样,函数fun就可以为其他文件调用。C语言规定,如果在定义函数时省略extern,则隐含为外部函数。(2)在需要调用此函数的文件中,用extern对函数声明,表示该函数是在其他文件中定义的外部函数。//file1.c void main() { extern void enter_string(char str[]); extern void delete_string(char str[],char ch);//两个外部函数,它们的定义在其他文件中; char c; char str[80]; enter_string(str); scanf("%c",&c); delete_string(str,c); }
//file2.c #include<stdio.h> void enter_string(char str[80])//定义外部函数 { gets(str); } //file3.c #include<stdio.h> void delete_string(char str[],char ch) { int i,j; for(i=j=0;str[i]!='\0';i++) if(str[i]!=ch) str[j++]=str[i]; str[j]='\0'; }
程序中2个函数都定义为外部函数。在main函数中用extern声明在main函数中用到enter_string,delete_string是在其他文件中定义的外部函数。三、extern的理解
理解extern关键在于是extern是声明而不是在定义,其变量和函数的定义别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。声明可以多次,定义只能一次。函数的声明extern关键词是可有可无的,因为函数本身不加修饰的话就是extern的。但是引用的时候一样是需要声明的。而全局变量在外部使用声明时,extern关键词是必须的,如果变量无extern修饰且没有显式的初始化,同样成为变量的定义,因此此时必须加extern,而编译器在此标记存储空间在执行时加载如内存并初始化为0。而局部变量的声明不能有extern的修饰,且局部变量在运行时才在堆栈部分分配内存。extern的使用最常见的用法就是在声明文件即头文件(.h)与定义文件即(.c/.cpp),我们在头文件(.h)中用extern声明某个变量或者函数为外部变量或者函数,在.cpp/.c文件中定义函数或者变量。然后我们在其他文件或者工程中使用该.cpp/.c文件中定义的函数或者变量时,只需#include<该头文件>即可。因为你在头文件中用extern声明的某个变量或者函数,将在本工程或者函数中预编译时展开该头文件。也即相当于实现了本工程或者本文件的自己声明extern某变量或者函数。它这种用法关键在于extern实现声明,而不是定义。定义在另一个文件中。四、extern "C"的理解
1、C++保留了一部分过程式语言的特点,因而它可以定义不属于任何类的全局变量和函数。但是,C++毕竟是一种面向对象的程序设计语言,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同。2、extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般之包括函数名。
比如说你用C 开发了一个DLL 库,为了能够让C ++语言也能够调用你的DLL输出(Export)的函数,你需要用extern "C"来强制编译器不要修改你的函数名。3、extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的;其次,被它修饰的目标是“C”的。
被extern "C"限定的函数或变量是extern类型的;本文章最后部分来自于博客http://www.jianshu.com/p/5d2eeeb93590原作者写的更加详细关于extern "C"。 -
c++变量的作用域、生存期和可见性
2015-07-13 15:13:04范围:在一个函数内部定义的变量,作用范围只限于本函数体内。 生存期:程序执行到本函数才会给局部变量分配内存单元,函数执行完毕局部变量所占的存储单元就被释放 全局变量 在函数体外部定义的变量是全局... -
extern关键字的使用
2020-07-03 17:41:30全局变量可以为本文件中的其他函数所共用,它的有效范围为从定义变量的位置开始到本源文件结束。 然而,如果全局变量不在文件的开头定义,有效的作用范围将只限于其定义处到文件结束。如果在定义点之前的函数想引用... -
关于C语言中 extern 关键字用法
2019-06-05 10:37:33总结:extern 其实就是对函数进行隐藏,只限于本模块使用,其他用不了! ! 我们知道,程序的编译单位是源程序文件,一个源文件可以包含一个或若干个函数。在函数内定义的变量是局部变量,而在函数之外定义的变量... -
extern
2013-02-19 18:11:01在此作用域内,全局变量可以为本文件中各个函数所引用。编译时将全局变量分配在静态存储区。有时需要用extern来声明全局变量,以扩展全局变量的作用域。 1. 在一个文件内声明全局变量 全局变量的作用域:只限于... -
mysql数据库my.cnf配置文件
2019-04-22 13:59:30# 主线程中每秒会将重做日志缓冲写入磁盘的重做日志文件(REDO LOG)中。不论事务是否已经提交)默认的日志文件是ib_logfile0,ib_logfile1 # 1:当设为默认值1的时候,每次提交事务的时候,都会将log buffer刷写到日志... -
C语言程序设计标准教程
2009-05-22 18:41:51在{}中的函数体内, 除形参外没有使用其它变量,因此只有语句而没有变量类型说明。 上边这种定义方法称为“传统格式”。 这种格式不易于编译系统检查,从而会引起一些非常细微而且难于跟踪的错误。ANSI C 的新标准中... -
Android 上百实例源码分析以及开源分析 集合打包4
2012-07-10 21:54:03为了编译jChat,你要使用Eclipse创建一个新的Android项目,然后添加外部JAR和移动的jChat目录选择到libs目录JadeLeapAndroid.jar库。jChat使用了的MapView访问谷歌地图数据。 本项目有25个目标文件。项目里面有代码... -
[Oracle.11g权威指南(第2版)].谷长勇.扫描版.pdf
2013-06-23 21:16:09本章主要介绍了以下内容:SQL语言概述、如何使用简单和复杂的SELECT检索语句、如何使用基本函数、如何使用DDL语句、如何使用DML语句、如何使用描述语句。 5.1 SQL语言概述 70 5.1.1 SQL语言特点 71 5.1.2 SQL语言... -
UNIX网络编程 第2卷 进程间通信
2013-12-30 13:22:0212.3 在内存映射文件中给计数器持续加1 12.4 4.4bsd匿名内存映射 12.5 svr4/dev/zero内存映射 12.6 访问内存映射的对象 12.7 小结 12.8 习题 第13章 posix共享内存区 13.1 概述 13.2 shm_open和shm_... -
易语言程序免安装版下载
2011-04-07 09:28:50注意:静态编译后常量数据位于PE文件的.rdata段中,只可读不可写,编程时请避免修改它们。譬如以下的代码,静态编译后就可能会出现问题: a = " " GetWindowTextA(hWnd, a, 20) 正确的代码为: a = 取空白文本 ... -
数据结构演示软件
2013-06-02 21:32:36图示窗口显示二叉树的存储结构,但结点中只含标志域,而以结点间的黑色连线表示指针,红色连线表示前驱线索,蓝色连线表示后继线索。在二叉树线索化的过程中,图中指针 p 指向当前层二叉树的根结点,指针 pre 指向... -
用c描述的数据结构演示软件
2012-07-24 13:31:25图示窗口显示二叉树的存储结构,但结点中只含标志域,而以结点间的黑色连线表示指针,红色连线表示前驱线索,蓝色连线表示后继线索。在二叉树线索化的过程中,图中指针 p 指向当前层二叉树的根结点,指针 pre 指向... -
深入理解Android:卷I--详细书签版
2012-12-12 15:51:21第9章分析了Vold和Rild,其中Vold负责Android平台中外部存储设备的管理,而Rild负责与射频通信有关的工作。本章的拓展思考部分介绍了嵌入式系统中与存储有关的知识,还探讨了 Rild和Phone设计优化方面的问题。 ... -
webpack工程化打包原理解析与实现
2020-11-27 16:01:51也就是我们文件中所有的 <code>import xxxx from xxxx</code>,我们将这些依赖都放在 dependencies 的数组里面,之后统一进行导出,traverse 函数是一个遍历 AST 的方法,由 babel-traverse... -
数据结构(C++)有关练习题
2008-01-02 11:27:18e. 如有可能,请建立一个存储商品名称和数量的文本文件,并为二叉搜索树建立一个成员函数SetupInventory(),用于从该文本文件中读取库存商品的数据, 实验报告要求: 1、 按要求记录下二叉搜索树的完整实验...