我們通過程序控制計算機的執行過程,就像是利用咒語來控制魔法精靈。我們要知道了精靈的名字,才能召喚他。這一個個名字便是程序里的符號,我們可以理解為變量和函數。
符號有兩個重要的屬性 可見性和生命周期(對于函數,他的生命周期和整個程序的執行期是相同的)。static用來修飾符號,有兩種功能:改變符號的鏈接屬性(可見性,不僅可改變變量鏈接屬性,同樣能改變函數的鏈接屬性);改變變量的生命周期。
可見性##
static在c和c++中的區別?我們知道C有局部變量(代碼塊內部聲明)和全局變量(代碼塊外部聲明)。
main.c
int c = 0; //全局變量
int add(int a,int b)
static的值會變嗎,{
c = 1; //全局變量c可以被訪問,也就是說對add函數來說變量c是可見的
int sum = 1; //局部變量
return (a+b);
c語言中%s和%c?}
int main()
{
int a = 3; //局部變量
靜態變量static、int b = 4; //局部變量
int sum = 0; //局部變量 注意和add函數中sum變量區別
sum = add(a,b);
}
c語言靜態變量?對于單個文本的c文件我們可以通過作用域規則判斷變量的可見性。
下面我們看一個多文本的例子,這里我們有main.c和add.c兩個c文件。
main.c
#include
fabs在c語言中意思?extern int version;
int sum = 0;
int add(int a,int b);
int main()
c語言二維數組。{
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 有兩種功能:改變符號的鏈接屬性(可見性,不僅可改變變量鏈接屬性,同樣能改變函數的鏈接屬性);改變變量的生命周期。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态