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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8195|回復: 2
收起左側

static C語言 靜態變量和靜態函數

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

問題雖然是C語言中的靜態變量,其實說起來在其他很多的編程語言中,靜態變量的意義和用法都和C語言中差不多,所以搞懂了這個概念在以后學習其他的編程語言的時候是很有作用的。


我們就來說說C語言中的靜態變量是什么樣的一種,靜態變量在它們自己的函數或者是文件中是永久的變量,說起來,靜態變量很像是全局變量,但是他們之間是有差別的,靜態變量在函數或者是文件中是不被知道的,他們在兩次調用之間將保存自己的值,比如說,假如一個靜態變量的值是1,在第一次調用靜態變量之后,將他的值變為2,那么在我們第二次調用它的時候,它的值依然是2,而不會去初始化它,將它的值又看作是1。
Ex:

c語言 static靜態變量

#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語言的static變量是在程序加載的時候就為之分配內存的,一直到程序結束,而不像普通變量那樣函數執行一次分配一次。所以當第一次執行p(1)的時候,y已經加1了,下次執行p(2)時,y不會恢復成1,還是2;你就當全局變量的功能處理就行,性能上有區別

-----------------------------------------------------------------------------------------------------------------------
以下是基礎知識點
-----------------------------------------------------------------------------------------------------------------------

1. static 變量

靜態變量的類型 說明符是static。 靜態變量當然是屬于靜態存儲方式,但是屬于靜態存儲方式的量不一定就是靜態變量。 例如外部變量雖屬于靜態 存儲方式,但不一定是靜態變量,必須由 static加以定義后才能成為靜態外部變量,或稱靜態全局變量。

2. 靜態局部變量

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

(2)允許對構造類靜態局部量賦初值 例如數組,若未賦以初值,則由系統自動賦以0值。

(3) 對基本類型的靜態局部變量若在說明時未賦以初值,則系統自動賦予0值。而對自動變量不賦初值,則其值是不定的。
 

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

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

從以上分析可以看出:
把局部變量改變為靜態變量后是改變了它的存儲方式即改變了它的生存期
把全局變量改變為靜態變量 后是改變了它的作用域,限制了它的使用范圍

因此static 這個說明符在不同的地方所起的作用是不同的。

4. static 函數…..

內部函數和外部函數

當一個源程序由多個源文件組成時,C語言根據函數能否被其它源文件中的函數調用,將函數分為內部函數和外部函數。

1 內部函數(又稱靜態函數)
如果在一個源文件中定義的函數,只能被本文件中的函數調用,而不能被同一程序其它文件中的函數調用,這種函數稱為內部函數。
定義一個內部函數,只需在函數類型前再加一個“static”關鍵字即可,如下所示:
static 函數類型 函數名(函數參數表)
{……}
關鍵字“static”,譯成中文就是“靜態的”,所以內部函數又稱靜態函數。但此處“static”的含義不是指存儲方式,而是指對函數的作用域僅局限于本文件。
使用內部函數的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它文件中的函數同名,因為同名也沒有關系。

2 外部函數

外部函數的定義:在定義函數時,如果沒有加關鍵字“static”,或冠以關鍵字“extern”,表示此函數是外部函數:
[extern] 函數類型 函數名(函數參數表)
{……}
調用外部函數時,需要對其進行說明
[extern] 函數類型 函數名(參數類型表)[,函數名2(參數類型表2)……];

[案例]外部函數應用。

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

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


注:此處的extern可有可無,不加extern時默認是外部函數

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

1、概述

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

1)、變量會被放在程序的全局存儲區中,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是它與堆棧變量和堆變量的區別。
 
2)、變量用static告知編譯器,自己僅僅在變量的作用范圍內可見。這一點是它與全局變量的區別。


2、問題:Static的理解


  關于static變量,請選擇下面所有說法正確的內容:

  A、若全局變量僅在單個C文件中訪問,則可以將這個變量修改為靜態全局變量,以降低模塊間的耦合度;

  B、若全局變量僅由單個函數訪問,則可以將這個變量改為該函數的靜態局部變量,以降低模塊間的耦合度;

  C、設計和使用訪問動態全局變量、靜態全局變量、靜態局部變量的函數時,需要考慮重入問題;

  D、靜態全局變量過大,可那會導致堆棧溢出。 

  答案與分析:

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

  對于C:根據本篇概述部分的說明a),我們知道,C是正確的(所謂的函數重入問題,下面會詳細闡述)。

  對于D:靜態變量放在程序的全局數據區,而不是在堆棧中分配,所以不可能導致堆棧溢出,D是錯誤的。

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

  3、問題:不可重入函數

  曾經設計過如下一個函數,在代碼檢視的時候被提醒有bug,因為這個函數是不可重入的,為什么?

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;
}

  答案與分析:

  所謂的函數是可重入的(也可以說是可預測的),即:只要輸入數據相同就應產生相同的輸出。

   這個函數之所以是不可預測的,就是因為函數中使用了static變量,因為static變量的特征,這樣的函數被稱為:帶“內部存儲器”功能的的函數。 因此如果我們需要一個可重入的函數,那么,我們一定要避免函數中使用static變量,這種函數中的static變量,使用原則是,能不用盡量不用。

  將上面的函數修改為可重入的函數很簡單,只要將聲明sum變量中的static關鍵字去掉,變量sum即變為一個auto 類型的變量,函數即變為一個可重入的函數。

  當然,有些時候,在函數中是必須要使用static變量的,比如當某函數的返回值為指針類型時,則必須是static的局部變量的地址作為返回值,若為auto類型,則返回為錯指針。
回復

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av在线一区二区三区 | 欧美视频xxx | 国产在线观看av | 日韩av在线免费 | 国产日韩一区二区 | 一区二区三区在线播放 | 精品国产乱码久久久久久88av | 91精品国产综合久久久亚洲 | 91精品国产91 | 亚洲影视在线 | 久久久久一区二区三区 | 成人福利网站 | 日韩免费一区二区 | 少妇一区二区三区 | 色姑娘av| 日韩精品一二三 | 日韩一级免费观看 | 亚洲在线中文字幕 | 狠狠综合久久av一区二区小说 | 国产精品视频一区二区三区, | 国产精品福利视频 | 日本天堂视频在线观看 | 99热欧美| 国产蜜臀 | 91视频中文 | 成人在线网址 | 夜夜骚视频| 久久精品国产一区二区电影 | 伊人精品久久久久77777 | 亚洲一区精品视频 | 中文字幕日韩一区 | 国产欧美综合在线 | 国产精品777一区二区 | 亚洲不卡在线观看 | 欧区一欧区二欧区三免费 | 国产精品一区二区三区在线 | 91精品麻豆日日躁夜夜躁 | 天天草天天 | 成年人免费在线视频 | 国产中文字幕在线观看 | 在线亚洲精品 |