C语言函数内static关键字详解
来源:互联网 发布:极度恐慌网络 编辑:程序博客网 时间:2024/05/29 03:49
static关键字有两类使用:函数外使用和和函数内使用,其中函数外使用主要用来限制被修饰的函数或变量作用域为本文件,没什么可多说的,下面重点说一下static关键字在函数体内的用法.
如下面的代码:
#include<stdio.h>void test(){ static int a=1; printf("%d",a++);}void main(){ int i; for (i=0;i<5;i++) test();}
输出为12345,如果去掉static关键字,输出将是11111.
我们来看一下使用了static关键字后的汇编代码(只保留了关键部分):
.LC0: .string "%d"test:.LFB0: pushl %ebp movl %esp, %ebp subl $8, %esp movl a.1933, %eax leal 1(%eax), %edx movl %edx, a.1933 subl $8, %esp pushl %eax pushl $.LC0 call printf addl $16, %esp nop leave reta.1933: .long 1可以看到下面三行汇编代码实际完成的是a++操作,如果有不理解第二条指令的可以参考我的上一篇博客.
movl a.1933, %eax leal 1(%eax), %edx movl %edx, a.1933等等,我的变量名不是a吗?a.1933是什么玩意儿?其实这个a.1933像极了一个全局变量.不信看下面的代码:
#include<stdio.h>int a=1;void test(){ printf("%d",a++);}void main(){ int i; for (i=0;i<5;i++) test();}其关键的汇编代码为:
a: .long 1.LC0: .string "%d"test:.LFB0: pushl %ebp movl %esp, %ebp subl $8, %esp movl a, %eax leal 1(%eax), %edx movl %edx, a subl $8, %esp pushl %eax pushl $.LC0 call printf addl $16, %esp nop leave ret看看,何止像,从汇编的角度来看,这里的a和上面的a.1933根本就是一回事嘛.所以函数内的static变量和全局变量从汇编的角度看本质上是一样的.这也就解释了为什么test()退出后static修饰的a还存在的问题,因为人家跟全局变量的地位一样嘛.那如何解释1933这个后缀呢?其实这个是C编译器的限制,也就是说你只有在汇编后才知道函数内static修饰的变量真正叫什么名字,而这个名字只在该函数体内才知道,外部函数是不知道这个真名的.换句话说,C编译器就是靠这个别名的办法限制了外部函数对其的访问.
但是由于这两者实在太像了,我们可以欺骗一下编译器,看下面的代码:
#include<stdio.h>void test(){ static int a=1; printf("%d",a++);}void test2(){ extern int a; printf("%d",a);}void main(){ test(); test2();}这个代码连接时一定不能通过,原因是test2中的a根本没有定义.由于static int a只存在于test内,test2无法访问到.但是上面的代码却可以汇编通过(关键代码如下):
test:.LFB0: movl a.1933, %eax leal 1(%eax), %edx movl %edx, a.1933 subl $8, %esp pushl %eax pushl $.LC0 call printftest2:.LFB1: movl a, %eax subl $8, %esp pushl %eax pushl $.LC0 call printfa.1933: .long 1可以看到static int a被编译器在test中别名为了a.1933,而test2并不知道这一点.因此我们可以手动修改test2让它知道这一点.即把a别名成a.1933,这样再编译执行,这样可以顺利输出12.而此时的static int a完全被改造成了全局变量.
0 0
- C语言函数内static关键字详解
- C语言 static关键字详解
- c语言关键字static
- c语言static关键字
- C语言关键字static
- C语言static关键字
- 关键字static(c语言)
- C语言-关键字static
- c语言关键字--static
- C语言 static 关键字
- C语言static关键字
- C语言 Static关键字
- c语言关键字static
- C语言关键字Static
- C语言 static关键字
- c语言static关键字
- C语言中的extern和static关键字详解
- C/C++static关键字详解
- poj1018(枚举)
- 《Python 核心编程》 学习记录
- C# 带权重的随机 与 不带权重的随机
- Linux常用命令--网络命令、关机重启命令
- HDU 5690 (分治 || 循环节)
- C语言函数内static关键字详解
- C#网络程序设计1-3:线程支持
- php错误日志保存
- 最大的数 nyoj 1170
- XOJ 4.树的构造
- BZOJ 2763 飞行路线(spfa+分层图)
- 【H5】手机浏览器分批次多张上传图片(文件),包含进度条
- C++函数名的修饰规则
- 地铁译:Spark for python developers ---Spark的数据戏法