c语言static能改变吗,理解c语言中的static

我们通过程序控制计算机的执行过程,就像是利用咒语来控制魔法精灵。我们要知道了精灵的名字,才能召唤他。这一个个名字便是程序里的符号,我们可以理解为变量和函数。

符号有两个重要的属性 可见性和生命周期(对于函数,他的生命周期和整个程序的执行期是相同的)。static用来修饰符号,有两种功能:改变符号的链接属性(可见性,不仅可改变变量链接属性,同样能改变函数的链接属性);改变变量的生命周期。

可见性##

我们知道C有局部变量(代码块内部声明)和全局变量(代码块外部声明)。

main.c

int c = 0; //全局变量

int add(int a,int b)

{

c = 1; //全局变量c可以被访问,也就是说对add函数来说变量c是可见的

int sum = 1; //局部变量

return (a+b);

}

int main()

{

int a = 3; //局部变量

int b = 4; //局部变量

int sum = 0; //局部变量  注意和add函数中sum变量区别

sum = add(a,b);

}

对于单个文本的c文件我们可以通过作用域规则判断变量的可见性。

下面我们看一个多文本的例子,这里我们有main.c和add.c两个c文件。

main.c

#include

extern int version;

int sum = 0;

int add(int a,int b);

int main()

{

sum = add(1,2);

printf("version = %d\n",version);

}

执行命令gcc -c main.c -o main.o生成目标文件,然后我们通过nm命令查看main.o文件的符号表

nm main.o

U add

0000000000000000 T main

U printf

0000000000000000 B sum

U version

由上我们看到函数add,和变量version被标识为U(未定义),printf我们这里不讨论

add.c

int version = 0x100; //1.00版本

int add(int a,int b)

{

return (a+b);

}

我们查看一下add.c的目标文件add.o的符号表

gcc -c add.c -o add.o

nm add.o

0000000000000000 T add

0000000000000000 D version

我们可以看到对于main.c文件中未定义的两个符号add和version在这里都有了具体的定义,我们看一下最后生成的可执行文件a.out的符号表

000000000040055f T add

...

000000000040052d T main

U printf@@GLIBC_2.2.5

...

0000000000601048 B sum

...

0000000000601040 D version

我们可以看到最后生成的可执行文件中对add和version都分配了地址.

修改一下add.c,再看一看

static int version = 0x100; //1.00版本 添加了static 修饰

static int add(int a,int b) //添加了static修饰

{

return (a+b);

}

查看一下此文件编译后的符号表

0000000000000000 t add

0000000000000000 d version

我们看到,add和version两个符号的前面分别是一个小写的t和d,这代表着此类符号不能被外部文件链接.

这样我们再来链接main.o和add.o会看到

main.o:在函数‘main’中:

main.c:(.text+0xf):对‘add’未定义的引用

main.c:(.text+0x1b):对‘version’未定义的引用

collect2: error: ld returned 1 exit status

请体会一下static的用途

生命周期##

自动变量###

c语言当中的自动变量是可以自动创建和销毁的,由编译器负责在栈空间上进行分配

main.c

#include

void fun()

{

int a = 0;

printf("%p\n",&a); //打印自动变量a的地址

}

void pfun()

{

int i = 0;

fun();

}

int main()

{

fun();

pfun();

}

输出结果

0x7fff3165a4ac        //位于栈空间地址

0x7fff3165a48c

我们看到自动变量a的地址是有变化的,编译器在程序执行过程中处理了对变量a的地址分配和销毁.

我们修改下main.c文件

#include

void fun()

{

static int a = 0; //增加static修饰,声明为静态变量

printf("%p\n",&a);

}

void pfun()

{

int i = 0;

fun();

}

int main()

{

fun();

pfun();

}

输出结果

0x601044 //低地址,数据段

0x601044

我们看到我们通过增加static修饰,变量a不再在栈上分配,其生命周期和程序的整个执行周期相同.

static 有两种功能:改变符号的链接属性(可见性,不仅可改变变量链接属性,同样能改变函数的链接属性);改变变量的生命周期。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值