日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言函数内static关键字 疑惑

發布時間:2024/9/5 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言函数内static关键字 疑惑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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 %ebpmovl %esp, %ebpsubl $8, %espmovl a.1933, %eaxleal 1(%eax), %edxmovl %edx, a.1933subl $8, %esppushl %eaxpushl $.LC0call printfaddl $16, %espnopleavereta.1933:.long 1

可以看到下面三行匯編代碼實際完成的是a++操作,如果有不理解第二條指令的可以參考我的上一篇博客.

movl a.1933, %eaxleal 1(%eax), %edxmovl %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 %ebpmovl %esp, %ebpsubl $8, %espmovl a, %eaxleal 1(%eax), %edxmovl %edx, asubl $8, %esppushl %eaxpushl $.LC0call printfaddl $16, %espnopleaveret

看看,何止像,從匯編的角度來看,這里的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, %eaxleal 1(%eax), %edxmovl %edx, a.1933subl $8, %esppushl %eaxpushl $.LC0call printftest2: .LFB1:movl a, %eaxsubl $8, %esppushl %eaxpushl $.LC0call printfa.1933:.long 1

可以看到static int a被編譯器在test中別名為了a.1933,而test2并不知道這一點.因此我們可以手動修改test2讓它知道這一點.即把a別名成a.1933,這樣再編譯執行,這樣可以順利輸出12.而此時的static int a完全被改造成了全局變量.

總結

以上是生活随笔為你收集整理的C语言函数内static关键字 疑惑的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。