找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5007|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

c語言中static用法總結(jié)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:105323 發(fā)表于 2016-2-12 21:01 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
                        慘痛教訓(xùn):
假設(shè)在test.h中定義了一個(gè)static bool g_test=false;
若test1.c和test2.c都包含test.h,則test1.c和test2.c分別生成兩份g_test,在test1.c中置g_test=true,而test2.c中仍然為false并未改變!shit。
一、c程序存儲(chǔ)空間布局
C程序一直由下列部分組成:
     1)正文段——CPU執(zhí)行的機(jī)器指令部分;一個(gè)程序只有一個(gè)副本;只讀,防止程序由于意外事故而修改自身指令;
     2)初始化數(shù)據(jù)段(數(shù)據(jù)段)——在程序中所有賦了初值的全局變量,存放在這里。
     3)非初始化數(shù)據(jù)段(bss段)——在程序中沒有初始化的全局變量;內(nèi)核將此段初始化為0。
     4)!鲩L方向:自頂向下增長;自動(dòng)變量以及每次函數(shù)調(diào)用時(shí)所需要保存的信息(返回地址;環(huán)境信息)。
     5)堆——?jiǎng)討B(tài)存儲(chǔ)分。
|-----------|
|                |
|-----------|
|   棧        |
|-----------|
|   |           |
|  |/          |
|                |
|                |
|  /|          |
|   |           |
|-----------|
|   堆        |
|-----------|
| 未初始化  |
|-----------|
|   初始化  |
|-----------|
|  正文段   |
|-----------|

二、 面向過程程序設(shè)計(jì)中的static
1. 全局靜態(tài)變量
  在全局變量之前加上關(guān)鍵字static,全局變量就被定義成為一個(gè)全局靜態(tài)變量。
  1)內(nèi)存中的位置:靜態(tài)存儲(chǔ)區(qū)(靜態(tài)存儲(chǔ)區(qū)在整個(gè)程序運(yùn)行期間都存在)
  2)初始化:未經(jīng)初始化的全局靜態(tài)變量會(huì)被程序自動(dòng)初始化為0(自動(dòng)對象的值是任意的,除非他被顯示初始化)
  3)作用域:全局靜態(tài)變量在聲明他的文件之外是不可見的。準(zhǔn)確地講從定義之處開始到文件結(jié)尾。

看下面關(guān)于作用域的程序:
//teststatic1.c
void display();
extern int n;
int main()
{
  n = 20;
  printf("%dn",n);
  display();
  return 0;
}

//teststatic2.c
static int n;  //定義全局靜態(tài)變量,自動(dòng)初始化為0,僅在本文件中可見
void display()
{
  n++;
  printf("%dn",n);
}

文件分別編譯通過,但link的時(shí)候teststatic2.c中的變量n找不到定義,產(chǎn)生錯(cuò)誤。

定義全局靜態(tài)變量的好處:
<1>不會(huì)被其他文件所訪問,修改
<2>其他文件中可以使用相同名字的變量,不會(huì)發(fā)生沖突。
2. 局部靜態(tài)變量
  在局部變量之前加上關(guān)鍵字static,局部變量就被定義成為一個(gè)局部靜態(tài)變量。
  1)內(nèi)存中的位置:靜態(tài)存儲(chǔ)區(qū)
2)初始化:未經(jīng)初始化的全局靜態(tài)變量會(huì)被程序自動(dòng)初始化為0(自動(dòng)對象的值是任意的,除非他被顯示初始化)
3)作用域:作用域仍為局部作用域,當(dāng)定義它的函數(shù)或者語句塊結(jié)束的時(shí)候,作用域隨之結(jié)束。
注:當(dāng)static用來修飾局部變量的時(shí)候,它就改變了局部變量的存儲(chǔ)位置,從原來的棧中存放改為靜態(tài)存儲(chǔ)區(qū)。但是局部靜態(tài)變量在離開作用域之后,并沒有被銷毀,而是仍然駐留在內(nèi)存當(dāng)中,直到程序結(jié)束,只不過我們不能再對他進(jìn)行訪問。
     當(dāng)static用來修飾全局變量的時(shí)候,它就改變了全局變量的作用域(在聲明他的文件之外是不可見的),但是沒有改變它的存放位置,還是在靜態(tài)存儲(chǔ)區(qū)中。
3. 靜態(tài)函數(shù)
  在函數(shù)的返回類型前加上關(guān)鍵字static,函數(shù)就被定義成為靜態(tài)函數(shù)。
函數(shù)的定義和聲明默認(rèn)情況下是extern的,但靜態(tài)函數(shù)只是在聲明他的文件當(dāng)中可見,不能被其他文件所用。
  例如:
//teststatic1.c
void display();
static void staticdis();
int main()
{
  display();
  staticdis();
  renturn 0;
}

//teststatic2.c
void display()
{
  staticdis();
  printf("display() has been called n");
}

static void staticdis()
{
  printf("staticDis() has been calledn");
}

文件分別編譯通過,但是連接的時(shí)候找不到函數(shù)staticdis()的定義,產(chǎn)生錯(cuò)誤。
實(shí)際上編譯也未過,vc2003報(bào)告teststatic1.c中靜態(tài)函數(shù)staticdis已聲明但未定義 ;by imjacob
定義靜態(tài)函數(shù)的好處:
<1> 其他文件中可以定義相同名字的函數(shù),不會(huì)發(fā)生沖突
<2> 靜態(tài)函數(shù)不能被其他文件所用。

存儲(chǔ)說明符auto,register,extern,static,對應(yīng)兩種存儲(chǔ)期:自動(dòng)存儲(chǔ)期和靜態(tài)存儲(chǔ)期。

auto和register對應(yīng)自動(dòng)存儲(chǔ)期。具有自動(dòng)存儲(chǔ)期的變量在進(jìn)入聲明該變量的程序塊時(shí)被建立,它在該程序塊活動(dòng)時(shí)存在,退出該程序塊時(shí)撤銷。
關(guān)鍵字extern和static用來說明具有靜態(tài)存儲(chǔ)期的變量和函數(shù)。用static聲明的局部變量具有靜態(tài)存儲(chǔ)持續(xù)期(staticstorage duration),或靜態(tài)范圍(staticextent)。雖然他的值在函數(shù)調(diào)用之間保持有效,但是其名字的可視性仍限制在其局部域內(nèi)。靜態(tài)局部對象在程序執(zhí)行到該對象的聲明處時(shí)被首次初始化。
由于static變量的以上特性,可實(shí)現(xiàn)一些特定功能。
1. 統(tǒng)計(jì)次數(shù)功能
聲明函數(shù)的一個(gè)局部變量,并設(shè)為static類型,作為一個(gè)計(jì)數(shù)器,這樣函數(shù)每次被調(diào)用的時(shí)候就可以進(jìn)行計(jì)數(shù)。這是統(tǒng)計(jì)函數(shù)被調(diào)用次數(shù)的最好的辦法,因?yàn)檫@個(gè)變量是和函數(shù)息息相關(guān)的,而函數(shù)可能在多個(gè)不同的地方被調(diào)用,所以從調(diào)用者的角度來統(tǒng)計(jì)比較困難。代碼如下:

void count();
int main()
{
int i;
for (i = 1; i <= 3; i++)
  count();
  return 0;
}
void count()
{
static num = 0;
num++;
printf(" I have been called%d",num,"timesn");
}
輸出結(jié)果為:
I have been called 1 times.
I have been called 2 times.
I have been called 3 times.
                                                                       

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表