[C]控制外部变量访问权限的extern和static关键字
一、extern
概述
编译器是由上至下编译源文件的,当遇到一些函数引用外部全局变量,而这个变量被定义在该函数声明主体的下方,又或者引用自其它的编译单元,这个情况就需要extern来向编译器表明此变量是一个外部变量
问题1.运用extern实现全局变量声明提升效果
- #include <stdio.h>
- void fun(void);
- int main(void)
- {
- fun();
- }
- void fun(void)
- {
- printf("%d\n", v);
- }
- int v = ;
上述代码,全局变量v被声明在函数fun主体的下方,这时编译器将无法找到变量v,报告错误
- error: ‘v’ undeclared (first use in this function)
这种情况下可以把变量v的声明提升到函数fun之前
- int v = ;
- void fun(void)
- {
- printf("%d\n", v);
- }
又或者在函数内部用extern关键字向编译器表明,这是一个来自外部的变量
- void fun(void)
- {
- extern int v;
- printf("%d\n", v);
- }
extern声明的变量是不能赋值的(但是函数可以),编译器将会自动在外部寻找全局变量v进行赋值
问题2.引用编译单元以外的变量
有一个文件a.c,main函数包含了来自文件b.c的全局变量v
- #include <stdio.h>
- int main(void)
- {
- extern int v;
- printf("%d\n", v);
- }
文件b.c
- int v = ;
如果a文件不声明extern int v,编译器将无法通过编译,而声明了extern int v,可以通过编译器仅编译不链接选项,把a.c和b.c先编译,再进行链接,程序便可以顺利运行
- gcc -c a.c b.c
- gcc -o out a.o b.o
函数和其他类型的变量,数据类型也是可行的哦
- #include <stdio.h>
- extern void fun(void);
- int main(void)
- {
- fun();
- }
定义在一个外部文件b.c的函数fun
- #include <stdio.h>
- void fun(void);
- void fun(void)
- {
- printf("fun\n");
- }
PS:上面提到过extern声明的变量是不能赋值的,但是函数可以。b.c可以改写为
- #include <stdio.h>
- extern void fun(void);
- extern void fun(void)
- {
- printf("fun\n");
- }
表明它是一个外部函数,其实extern是函数存储类修饰符的一个默认类型(extern、static、auto、restrict),所以就算省略掉extern,代码还是可以运行的,请参考c语言核心技术的第11章
二、static
概述
在对extern的描述中得知extern是函数存储类修饰符的一个默认类型,所以就算函数声明中不表明为extern,外部文件也是可以访问该函数的,如果有一种情况希望外部文件不能访问内部文件声明的函数,这时static关键字就派上了用场
让我们修改一下之前的例子
文件a.c
- #include <stdio.h>
- extern void fun(void);
- int main(void)
- {
- fun();
- }
文件b.c
- #include <stdio.h>
- static void fun(void);
- static void fun(void)
- {
- printf("fun\n");
- }
此时fun函数被声明为static,只有内部文件才能够对其进行调用,外部文件a.c若企图调用,在创建链接阶段编译器便会抛出错误提示
- undefined reference to `fun'
[C]控制外部变量访问权限的extern和static关键字的更多相关文章
- iOS重写和成员变量访问权限
一.重写机制 1.覆盖父类的方法 2.对父类方法做进一步的补充 注意:父类声明过得方法,子类无需声明. * 子类如果重写了父类的方法: 1.父类的指针指向子类的对象,则调用方法时,调用的是子类的方法: ...
- C++中extern “C”含义及extern、static关键字浅析
https://blog.csdn.net/bzhxuexi/article/details/31782445 1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C ...
- Struts2 利用拦截器 interceptor 控制登陆和访问权限
最近学习了Struts2的登录和权限控制用到的是拦截器,需要在struts.xml中配置,每个action都默认的继承defaultStack,如果你用了别的拦截器,还需要手动引入defaultSta ...
- 关于private,default,protected,public,成员变量访问权限
关于private,protected,public,default成员变量的访问权限,请参阅上图! 子类要访问父类的private成员变量,必须采用采用get方法: eg: public class ...
- Python变量访问权限控制
oop1.py文件代码 # user/bin/python class Foo: def bar(self): print('ok') def hello(self, name): print(&qu ...
- DACL原理.控制文件的访问权限(文件,注册表.目录.等任何带有安全属性的对象.)
目录 一丶简介 1.DACL是什么. 2.如何创建一个自己控制的文件. 3.SDDL是个什么鬼. 二丶 编写SDDL 控制的文件 一丶简介 1.DACL是什么. DACL称为自主访问的控制列表.是应用 ...
- MVC 5 中Filter控制 action的访问权限
1,创建一个继承自 FilterAttribute, IActionFilter的类 namespace HeatMetering2.Filters { public class HMV2Authen ...
- vue路由权限之访问权限(meta控制是否有访问权限)
首先登录那权限表 router.beforeEach((to, from, next) => { if(to.path === '/login') { next(); }else{ if(!st ...
- 关于extern和static关键字引出的一些关于作用域和链接属性和存储类型的问题
在进入正题前我们必须了解一些概念: 标识符:标识符不仅仅代表着变量的名字,main()函数的main也是一个标识符,这点很重要. 存储类型:即变量的存储位置及其生存周期:静态区:分为两块 .date ...
随机推荐
- XOR 加密
XOR 是一个神奇的运算符, 观察它的真值表, 很容易得到以下结论: 假设现有 a , b 变量, 则 a ^ 0 == a a ^ 0xff == ~a (取反加1等于作为补码的a的真值的相反数的补 ...
- NFine框架全选checkBox列错位
在jqgrid.css里找到 .ui-jqgrid .cbox{margin-left: -1px;position: initial;vertical-align: text-bottom;}.ui ...
- ASP.NET Web API 2 使用 DelegatingHandler(委托处理程序)实现签名认证
Ø 前言 在前一篇ASP.NET Web API 2 使用 AuthorizationFilter(授权过滤器)实现 Basic 认证文章中实现了采用 Basic 认证的方式,但是这种方式存在安全隐 ...
- 【python小练】0020
第 0020 题: 登陆中国联通网上营业厅 后选择「自助服务」 --> 「详单查询」,然后选择你要查询的时间段,点击「查询」按钮,查询结果页面的最下方,点击「导出」,就会生成类似于 2014年1 ...
- for-each 格式
public class D21LX { public static void main(String arge[]){ fish [] a1=new fish[3]; a1[0] = new fis ...
- 时间戳time
时间戳(timestamp)的方式:通常来说,时间戳表示的是从1970年1月1日开始按秒计算的偏移量(time.gmtime(0))此模块中的函数无法处理1970纪元年以前的时间或太遥远的未来(处理极 ...
- bus实现兄弟组件传值
传递的地方:两个组件都要引入这个公共的bus中转函数 Bus.js文件相当于一个公共的对象: 传递的文件中写入这个方法: 兄弟组件通过点击事件输出参数,需要的组件来接收传递过来的参数:
- js获取当前时区GMT
1:js获取当前时区GMT 首先引入插件: <script src="../js/shiqu/jstz-1.0.4.min.js"></script> // ...
- webwork框架
以前都没有用过WebWork这个框架,只是听说过.没想到现在要用,所以就自学了一下.做了个小例子给大家分享下中间遇到的苦难和经验. 准备工作:首先要去下载WebWork框架的开发包.我用的2.2.6版 ...
- C hashtable小例子
参考链接: http://blog.csdn.net/qinpanke/article/details/9171541