博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《编写高质量代码:改善c程序代码的125个建议》——建议8-2:慎用extern声明外部变量...
阅读量:6671 次
发布时间:2019-06-25

本文共 1760 字,大约阅读时间需要 5 分钟。

本节书摘来自华章计算机《编写高质量代码:改善c程序代码的125个建议》一书中的第1章,建议8-2,作者:马 伟 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

建议8-2:慎用extern声明外部变量

我们都知道,程序的编译单位是源程序文件,一个源文件可以包含一个或若干个函数。在函数内定义的变量是局部变量,而在函数之外定义的变量则称为外部变量,外部变量也就是我们所讲的全局变量。它的存储方式为静态存储,其生存周期为整个程序的生存周期。全局变量可以为本文件中的其他函数所共用,它的有效范围为从定义变量的位置开始到本源文件结束。

然而,如果全局变量不在文件的开头定义,有效的作用范围将只限于其定义处到文件结束。如果在定义点之前的函数想引用该全局变量,则应该在引用之前用关键字extern对该变量作“外部变量声明”,表示该变量是一个已经定义的外部变量。有了此声明,就可以从“声明”处起,合法地使用该外部变量。
来看一个简单的例子,如代码清单1-25所示。

代码清单1-25 extern使用示例#include 
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);}

在代码清单1-25中,全局变量g_X与g_Y是在main函数之后声明的,因此它的作用范围不在main函数中。如果我们需要在main 函数中调用它们,就必须使用extern来对变量g_X与g_Y作“外部变量声明”,以扩展全局变量的作用域。也就是说,如果在变量定义之前要使用该变量,则应在使用之前加extern声明变量,使作用域扩展到从声明开始到本文件

结束。
如果整个工程由多个源文件组成,在一个源文件中想引用另外一个源文件中已经定义的外部变量,同样只需在引用变量的文件中用extern关键字加以声明即可。下面就来看一个多文件的示例,如代码清单1-26-max与代码清单1-26-main所示。

代码清单1-26-max 1-26-max.c#include 
/*外部变量声明*/extern int g_X ; extern int g_Y ;int max(){ return (g_X > g_Y ? g_X : g_Y);}
代码清单1-26-main 1-26-main.c#include 
/*定义两个全局变量*/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;}

代码清单1-26-max与代码清单1-26-main的运行结果如图1-40所示。

c978be5a1d36df9c307fd29b8eec4a33ea49ea3f

对于多个文件的工程,都可以采用上面这种方法来操作。对于模块化的程序文件,可在其文件中预先留好外部变量的接口,也就是只采用extern声明变量,而不定义变量,代码清单1-26-max里的g_X与g_Y就是如此操作的。通常,这些外部变量的接口都是在模块程序的头文件中声明的,当需要使用该模块时,只需要在使用时具体定义一下这些外部变量即可。代码清单1-26- main里的g_X与g_Y则是相关示例。

不过,需要特别注意的是,由于用extern引用外部变量,可以在引用的模块内修改其变量的值,因此,如果有多个文件同时要对应用的变量进行操作,而且可能会修改该变量,那就会影响其他模块的使用。因此,我们要慎重使用。

转载地址:http://ejmxo.baihongyu.com/

你可能感兴趣的文章
【MySQL】数据库字符校对规则
查看>>
分形几何算法和实现(C语言)
查看>>
设计模式[2]-Chain of Responsibility
查看>>
Nginx+Tomcat动静分离及Nginx优化(企业案例)
查看>>
软件事务内存导论(五)创建嵌套事务
查看>>
[翻译] ClockView 时钟
查看>>
Cocos2d-X-3.0之后的版本的环境搭建
查看>>
[翻译] TCBlobDownload
查看>>
阿里云DTS VS MySQLdump
查看>>
MonetDB 1.6 billion(384GB) JOIN 2.4 billion(576GB) 60 columns-random-data wide-table
查看>>
类型属性、方法
查看>>
RDS作业功能的支持
查看>>
跟着实例学习ZooKeeper的用法: 计数器
查看>>
JavaScript Function类型
查看>>
linux之select函数用法详解
查看>>
翻翻git之---史上最强的图片选择器 GalleryFinal(顺带附下麦麦,当当的近照)
查看>>
SSL/TLS Bar Mitzvah Attack 漏洞 [ 受诫礼(BAR-MITZVAH) ]
查看>>
web图片优化(5)
查看>>
千里之行始于足下 | 开篇 - 增长极客
查看>>
[知识图谱] 1.2-知识图谱有什么用?
查看>>