久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 8063|回復(fù): 2
收起左側(cè)

static C語(yǔ)言 靜態(tài)變量和靜態(tài)函數(shù)

[復(fù)制鏈接]
ID:98924 發(fā)表于 2015-12-9 02:42 | 顯示全部樓層 |閱讀模式

問(wèn)題雖然是C語(yǔ)言中的靜態(tài)變量,其實(shí)說(shuō)起來(lái)在其他很多的編程語(yǔ)言中,靜態(tài)變量的意義和用法都和C語(yǔ)言中差不多,所以搞懂了這個(gè)概念在以后學(xué)習(xí)其他的編程語(yǔ)言的時(shí)候是很有作用的。


我們就來(lái)說(shuō)說(shuō)C語(yǔ)言中的靜態(tài)變量是什么樣的一種,靜態(tài)變量在它們自己的函數(shù)或者是文件中是永久的變量,說(shuō)起來(lái),靜態(tài)變量很像是全局變量,但是他們之間是有差別的,靜態(tài)變量在函數(shù)或者是文件中是不被知道的,他們?cè)趦纱握{(diào)用之間將保存自己的值,比如說(shuō),假如一個(gè)靜態(tài)變量的值是1,在第一次調(diào)用靜態(tài)變量之后,將他的值變?yōu)?,那么在我們第二次調(diào)用它的時(shí)候,它的值依然是2,而不會(huì)去初始化它,將它的值又看作是1。
Ex:

c語(yǔ)言 static靜態(tài)變量

#include iostream.h 
int p(int x)
{
static int y=1;
y=y+1;
return (x+y);}
int main()
{
cout<<p(1)<<endl;
cout<<p(2)<<endl;}

答案是3和5,為什么不是3和4呢?

c語(yǔ)言的static變量是在程序加載的時(shí)候就為之分配內(nèi)存的,一直到程序結(jié)束,而不像普通變量那樣函數(shù)執(zhí)行一次分配一次。所以當(dāng)?shù)谝淮螆?zhí)行p(1)的時(shí)候,y已經(jīng)加1了,下次執(zhí)行p(2)時(shí),y不會(huì)恢復(fù)成1,還是2;你就當(dāng)全局變量的功能處理就行,性能上有區(qū)別

-----------------------------------------------------------------------------------------------------------------------
以下是基礎(chǔ)知識(shí)點(diǎn)
-----------------------------------------------------------------------------------------------------------------------

1. static 變量

靜態(tài)變量的類型 說(shuō)明符是static。 靜態(tài)變量當(dāng)然是屬于靜態(tài)存儲(chǔ)方式,但是屬于靜態(tài)存儲(chǔ)方式的量不一定就是靜態(tài)變量。 例如外部變量雖屬于靜態(tài) 存儲(chǔ)方式,但不一定是靜態(tài)變量,必須由 static加以定義后才能成為靜態(tài)外部變量,或稱靜態(tài)全局變量。

2. 靜態(tài)局部變量

靜態(tài)局部變量屬于靜態(tài)存儲(chǔ)方式,它具有以下特點(diǎn):
(1)靜態(tài)局部變量在函數(shù)內(nèi)定義 它的生存期為整個(gè)源程序,但是其作用域仍與自動(dòng)變量相同,只能在定義該變量的函數(shù)內(nèi)使用該變量。退出該函數(shù)后, 盡管該變量還繼續(xù)存在,但不能使用它。

(2)允許對(duì)構(gòu)造類靜態(tài)局部量賦初值 例如數(shù)組,若未賦以初值,則由系統(tǒng)自動(dòng)賦以0值。

(3) 對(duì)基本類型的靜態(tài)局部變量若在說(shuō)明時(shí)未賦以初值,則系統(tǒng)自動(dòng)賦予0值。而對(duì)自動(dòng)變量不賦初值,則其值是不定的。
 

根據(jù)靜態(tài)局部變量的特點(diǎn),可以看出它是一種生存期為整個(gè)源程序的量。雖然離開(kāi)定義它的函數(shù)后不能使用,但如果再次調(diào)用定義它的函數(shù)時(shí),它又可繼續(xù)使用, 而且保存了前次被調(diào)用后留下的值。因此,當(dāng)多次調(diào)用一個(gè)函數(shù)且要求在調(diào)用之間保留某些變量的值時(shí),可考慮采用靜態(tài)局部變量。雖然用全局變量也可以達(dá)到上述目的,但全局變量有時(shí)會(huì)造成意外的副作用,因此仍以采用局部靜態(tài)變量為宜。

3.靜態(tài)全局變量
全局變量(外部變量)的說(shuō)明之前再冠以static 就構(gòu)成了靜態(tài)的全局變量。全局變量本身就是靜態(tài)存儲(chǔ)方式, 靜態(tài)全局變量當(dāng)然也是靜態(tài)存儲(chǔ)方式。這兩者在存儲(chǔ)方式上并無(wú)不同。這兩者的區(qū)別雖在于非靜態(tài)全局變量的作用域是整個(gè)源程序,當(dāng)一個(gè)源程序由多個(gè)源文件組成時(shí),非靜態(tài)的全局變量在各個(gè)源文件中都是有效的。 而靜態(tài)全局變量則限制了其作用域, 即只在定義該變量的源文件內(nèi)有效, 在同一源程序的其它源文件中不能使用它。由于靜態(tài)全局變量的作用域局限于一個(gè)源文件內(nèi),只能為該源文件內(nèi)的函數(shù)公用,因此 可以避免在其它源文件中引起錯(cuò)誤。

從以上分析可以看出:
把局部變量改變?yōu)殪o態(tài)變量后是改變了它的存儲(chǔ)方式即改變了它的生存期
把全局變量改變?yōu)殪o態(tài)變量 后是改變了它的作用域,限制了它的使用范圍

因此static 這個(gè)說(shuō)明符在不同的地方所起的作用是不同的。

4. static 函數(shù)…..

內(nèi)部函數(shù)和外部函數(shù)

當(dāng)一個(gè)源程序由多個(gè)源文件組成時(shí),C語(yǔ)言根據(jù)函數(shù)能否被其它源文件中的函數(shù)調(diào)用,將函數(shù)分為內(nèi)部函數(shù)和外部函數(shù)。

1 內(nèi)部函數(shù)(又稱靜態(tài)函數(shù))
如果在一個(gè)源文件中定義的函數(shù),只能被本文件中的函數(shù)調(diào)用,而不能被同一程序其它文件中的函數(shù)調(diào)用,這種函數(shù)稱為內(nèi)部函數(shù)。
定義一個(gè)內(nèi)部函數(shù),只需在函數(shù)類型前再加一個(gè)“static”關(guān)鍵字即可,如下所示:
static 函數(shù)類型 函數(shù)名(函數(shù)參數(shù)表)
{……}
關(guān)鍵字“static”,譯成中文就是“靜態(tài)的”,所以內(nèi)部函數(shù)又稱靜態(tài)函數(shù)。但此處“static”的含義不是指存儲(chǔ)方式,而是指對(duì)函數(shù)的作用域僅局限于本文件。
使用內(nèi)部函數(shù)的好處是:不同的人編寫(xiě)不同的函數(shù)時(shí),不用擔(dān)心自己定義的函數(shù),是否會(huì)與其它文件中的函數(shù)同名,因?yàn)橥矝](méi)有關(guān)系。

2 外部函數(shù)

外部函數(shù)的定義:在定義函數(shù)時(shí),如果沒(méi)有加關(guān)鍵字“static”,或冠以關(guān)鍵字“extern”,表示此函數(shù)是外部函數(shù):
[extern] 函數(shù)類型 函數(shù)名(函數(shù)參數(shù)表)
{……}
調(diào)用外部函數(shù)時(shí),需要對(duì)其進(jìn)行說(shuō)明
[extern] 函數(shù)類型 函數(shù)名(參數(shù)類型表)[,函數(shù)名2(參數(shù)類型表2)……];

[案例]外部函數(shù)應(yīng)用。

(1)文件mainf.c
main()
{ extern void input(…),process(…),output(…); /*調(diào)用外部函數(shù)*/
input(…); process(…); output(…);
}

(2)文件subf1.c
……
extern void input(……) /*定義外部函數(shù)*/
{……}
(3)文件subf2.c
……
extern void process(……) /*定義外部 函數(shù)*/
{……}
(4)文件subf3.c
……
extern void output(……) /*定義外部函數(shù)*/
{……}


注:此處的extern可有可無(wú),不加extern時(shí)默認(rèn)是外部函數(shù)

------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------

1、概述

static 聲明的變量在C語(yǔ)言中有兩方面的特征:

1)、變量會(huì)被放在程序的全局存儲(chǔ)區(qū)中,這樣可以在下一次調(diào)用的時(shí)候還可以保持原來(lái)的賦值。這一點(diǎn)是它與堆棧變量和堆變量的區(qū)別。
 
2)、變量用static告知編譯器,自己僅僅在變量的作用范圍內(nèi)可見(jiàn)。這一點(diǎn)是它與全局變量的區(qū)別。


2、問(wèn)題:Static的理解


  關(guān)于static變量,請(qǐng)選擇下面所有說(shuō)法正確的內(nèi)容:

  A、若全局變量?jī)H在單個(gè)C文件中訪問(wèn),則可以將這個(gè)變量修改為靜態(tài)全局變量,以降低模塊間的耦合度;

  B、若全局變量?jī)H由單個(gè)函數(shù)訪問(wèn),則可以將這個(gè)變量改為該函數(shù)的靜態(tài)局部變量,以降低模塊間的耦合度;

  C、設(shè)計(jì)和使用訪問(wèn)動(dòng)態(tài)全局變量、靜態(tài)全局變量、靜態(tài)局部變量的函數(shù)時(shí),需要考慮重入問(wèn)題;

  D、靜態(tài)全局變量過(guò)大,可那會(huì)導(dǎo)致堆棧溢出。 

  答案與分析:

  對(duì)于A,B:根據(jù)本篇概述部分的說(shuō)明b),我們知道,A,B都是正確的。

  對(duì)于C:根據(jù)本篇概述部分的說(shuō)明a),我們知道,C是正確的(所謂的函數(shù)重入問(wèn)題,下面會(huì)詳細(xì)闡述)。

  對(duì)于D:靜態(tài)變量放在程序的全局?jǐn)?shù)據(jù)區(qū),而不是在堆棧中分配,所以不可能導(dǎo)致堆棧溢出,D是錯(cuò)誤的。

  因此,答案是A、B、C。

  3、問(wèn)題:不可重入函數(shù)

  曾經(jīng)設(shè)計(jì)過(guò)如下一個(gè)函數(shù),在代碼檢視的時(shí)候被提醒有bug,因?yàn)檫@個(gè)函數(shù)是不可重入的,為什么?

unsigned int sum_int( unsigned int base )
{
 unsigned int index;
 static unsigned int sum = 0; // 注意,是static類型的。 
 for (index = 1; index <= base; index++)
 {
  sum += index;
 }
 return sum;
}

  答案與分析:

  所謂的函數(shù)是可重入的(也可以說(shuō)是可預(yù)測(cè)的),即:只要輸入數(shù)據(jù)相同就應(yīng)產(chǎn)生相同的輸出。

   這個(gè)函數(shù)之所以是不可預(yù)測(cè)的,就是因?yàn)楹瘮?shù)中使用了static變量,因?yàn)閟tatic變量的特征,這樣的函數(shù)被稱為:帶“內(nèi)部存儲(chǔ)器”功能的的函數(shù)。 因此如果我們需要一個(gè)可重入的函數(shù),那么,我們一定要避免函數(shù)中使用static變量,這種函數(shù)中的static變量,使用原則是,能不用盡量不用。

  將上面的函數(shù)修改為可重入的函數(shù)很簡(jiǎn)單,只要將聲明sum變量中的static關(guān)鍵字去掉,變量sum即變?yōu)橐粋(gè)auto 類型的變量,函數(shù)即變?yōu)橐粋(gè)可重入的函數(shù)。

  當(dāng)然,有些時(shí)候,在函數(shù)中是必須要使用static變量的,比如當(dāng)某函數(shù)的返回值為指針類型時(shí),則必須是static的局部變量的地址作為返回值,若為auto類型,則返回為錯(cuò)指針。
回復(fù)

使用道具 舉報(bào)

ID:99580 發(fā)表于 2015-12-19 20:56 | 顯示全部樓層
好,謝謝樓主分享。
回復(fù)

使用道具 舉報(bào)

ID:296746 發(fā)表于 2018-3-26 17:07 | 顯示全部樓層
牛人!!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久免费观看 | 国产精品亚洲视频 | 中文字幕一区二区三区在线视频 | 日韩一区二区在线看 | 午夜视频导航 | 91精品91久久久 | 拍戏被cao翻了h承欢 | 久久综合影院 | 国产亚洲精品美女久久久久久久久久 | 亚洲 中文 欧美 日韩 在线观看 | 欧美日韩久久精品 | 96国产精品久久久久aⅴ四区 | 国产蜜臀97一区二区三区 | 久久99视频 | 亚洲黄色网址视频 | www.99热| 国产日韩欧美中文字幕 | 日韩在线一区二区三区 | 国产福利免费视频 | 少妇黄色 | 综合伊人| 国产色黄 | 国产区第一页 | 国产一区二区三区四区三区四 | 欧美专区日韩 | 在线观看国产视频 | 午夜影视| 欧美激情va永久在线播放 | 国产精品久久久久婷婷二区次 | 中文区中文字幕免费看 | 在线免费看黄 | 韩国理论电影在线 | 精品在线一区 | 亚洲福利在线观看 | 欧美韩一区二区三区 | 精品99爱视频在线观看 | 日韩国产一区二区三区 | 欧美高清视频一区 | 麻豆av在线免费观看 | 中文字幕精品一区 | 在线观看国产视频 |