C++中static關鍵字作用總結

from:https://www.cnblogs.com/songdanzju/p/7422380.html

1.先來介紹它的第一條也是最重要的一條:隱藏。(static函數,static變量均可)

當同時編譯多個文件時,所有未加static前綴的全局變量函數都具有全局可見性。
舉例來說明。同時編譯兩個源文件,一個是a.c,另一個是main.c。

復制代碼
//a.c
char a = 'A'; // global variable
void msg()
{printf("Hello\n");
}//main.cint main()
{extern char a; // extern variable must be declared before useprintf("%c ", a);(void)msg();return 0;
}
復制代碼

程序的運行結果是:

A Hello

?

為什么在a.c中定義的全局變量a和函數msg能在main.c中使用?前面說過,所有未加static前綴的全局變量和函數都具有全局可見性,其它的源文件也能訪問。此例中,a是全局變量,msg是函數,并且都沒有加static前綴,因此對于另外的源文件main.c是可見的。
如果加了static,就會對其它源文件隱藏。例如在a和msg的定義前加上static,main.c就看不到它們了。利用這一特性可以在不同的文件中定義同名函數和同名變量,而不必擔心命名沖突。static可以用作函數和變量的前綴,對于函數來講,static的作用僅限于隱藏.


?

2.static的第二個作用是保持變量內容的持久。(static變量中的記憶功能和全局生存期

存儲在靜態數據區的變量會在程序剛開始運行時就完成初始化,也是唯一的一次初始化。共有兩種變量存儲在靜態存儲區:全局變量和static變量,只不過和全局變量比起來,static可以控制變量的可見范圍,說到底static還是用來隱藏的。雖然這種用法不常見

PS:如果作為static局部變量在函數內定義,它的生存期為整個源程序,但是其作用域仍與自動變量相同,只能在定義該變量的函數內使用該變量。退出該函數后, 盡管該變量還繼續存在,但不能使用它。

?

程序舉例:

復制代碼
#include <stdio.h>int fun(){static int count = 10; //在第一次進入這個函數的時候,變量a被初始化為10!并接著自減1,以后每次進入該函數,areturn count--; //就不會被再次初始化了,僅進行自減1的操作;在static發明前,要達到同樣的功能,則只能使用全局變量:    
 
}int count = 1;int main(void)
{printf("global\t\tlocal static\n");for(; count <= 10; ++count)printf("%d\t\t%d\n", count, fun());return 0;
}
復制代碼
?

程序的運行結果是:

global? local static

1 10

2 9

3 8

4 7

5 6

6 5

7 4

8 3

9 2

10 1

?

---基于以上兩點可以得出一個結論:把局部變量改變為靜態變量后是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜態變量后是改變了它的作用域,?限制了它的使用范圍。因此static 這個說明符在不同的地方所起的作用是不同的。


?

3.static的第三個作用是默認初始化為0(static變量)

其實全局變量也具備這一屬性,因為全局變量也存儲在靜態數據區。在靜態數據區,內存中所有的字節默認值都是0x00,某些時候這一特點可以減少程序員的工作量。比如初始化一個稀疏矩陣,我們可以一個一個地把所有元素都置0,然后把不是0的幾個元素賦值。如果定義成靜態的,就省去了一開始置0的操作。再比如要把一個字符數組當字符串來用,但又覺得每次在字符數組末尾加‘\0’;太麻煩。如果把字符串定義成靜態的,就省去了這個麻煩,因為那里本來就是‘\0’;不妨做個小實驗驗證一下。

復制代碼
#include <stdio.h>int a;int main()
{int i;static char str[10];printf("integer: %d; string: (begin)%s(end)", a, str);return 0;
}
復制代碼

程序的運行結果是:

integer: 0; string: (begin) (end)?

?

最后對static的三條作用做一句話總結。首先static的最主要功能是隱藏,其次因為static變量存放在靜態存儲區,所以它具備持久性和默認值0.?


?

4.static的第四個作用:C++中的類成員聲明static(有些地方與以上作用重疊)☆

?在類中聲明static變量或者函數時,初始化時使用作用域運算符來標明它所屬類,因此,靜態數據成員是類的成員,而不是對象的成員,這樣就出現以下作用:

(1)類的靜態成員函數是屬于整個類而非類的對象,所以它沒有this指針,這就導致 了它僅能訪問類的靜態數據和靜態成員函數。 ?????

(2)不能將靜態成員函數定義為虛函數。 ?????

(3)由于靜態成員聲明于類中,操作于其外,所以對其取地址操作,就多少有些特殊 ,變量地址是指向其數據類型的指針 ,函數地址類型是一個“nonmember函數指針”。

(4)由于靜態成員函數沒有this指針,所以就差不多等同于nonmember函數,結果就 產生了一個意想不到的好處:成為一個callback函數,使得我們得以將C++和C-based X W indow系統結合,同時也成功的應用于線程函數身上。?(這條沒遇見過)??

(5)static并沒有增加程序的時空開銷,相反她還縮短了子類對父類靜態成員的訪問 時間,節省了子類的內存空間。 ?????

(6)靜態數據成員在<定義或說明>時前面加關鍵字static。 ?????

(7)靜態數據成員是靜態存儲的,所以必須對它進行初始化。?(程序員手動初始化,否則編譯時一般不會報錯,但是在Link時會報錯誤)?

(8)靜態成員初始化與一般數據成員初始化不同:

初始化在類體外進行,而前面不加static,以免與一般靜態變量或對象相混淆;
初始化時不加該成員的訪問權限控制符private,public等;????????
初始化時使用作用域運算符來標明它所屬類;
?????????? 所以我們得出靜態數據成員初始化的格式:
<數據類型><類名>::<靜態數據成員名>=<值>

(9)為了防止父類的影響,可以在子類定義一個與父類相同的靜態變量,以屏蔽父類的影響。這里有一點需要注意:我們說靜態成員為父類和子類共享,但我們有重復定義了靜態成員,這會不會引起錯誤呢?不會,我們的編譯器采用了一種絕妙的手法:name-mangling 用以生成唯一的標志。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458351.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458351.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458351.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C Primer Plus 第7章 C控制語句:分支和跳轉 7.4 一個統計字數的程序

2019獨角獸企業重金招聘Python工程師標準>>> 首先&#xff0c;這個程序應該逐個讀取字符&#xff0c;并且應該有些方法判斷何時停止&#xff1b;第二&#xff0c;它應該能夠識別并統計下列單位&#xff1a;字符、行和單詞。下面是偽代碼描述&#xff1a; read a cha…

深入理解extern用法

from&#xff1a;https://blog.csdn.net/z702143700/article/details/46805241一、 extern做變量聲明 l 聲明extern關鍵字的全局變量和函數可以使得它們能夠跨文件被訪問。 我們一般把所有的全局變量和全局函數的實現都放在一個*.cpp文件里面&#xff0c;然后用一個同名的*.h文…

收集整理的非常有用的PHP函數

為什么80%的碼農都做不了架構師&#xff1f;>>> 1、PHP加密解密 2、PHP生成隨機字符串 3、PHP獲取文件擴展名&#xff08;后綴&#xff09; 4、PHP獲取文件大小并格式化 5、PHP替換標簽字符 6、PHP列出目錄下的文件名 7、PHP獲取當前頁面URL 8、PHP強制下載文件 9、…

進程間的通信方式——pipe(管道)

from&#xff1a;https://blog.csdn.net/skyroben/article/details/715133851.進程間通信每個進程各自有不同的用戶地址空間,任何一個進程的全局變量在另一個進程中都看不到&#xff0c;所以進程之間要交換數據必須通過內核,在內核中開辟一塊緩沖區,進程A把數據從用戶空間拷到內…

bash中(),{},(()),[],[[]]的區別

前言:在bash中遇到各種括號&#xff0c;同時在進行字符數值比較判定時&#xff0c;總是不斷出現問題&#xff0c;于是通過參考《advanced bash-scripting guide》&#xff0c;同時在centos 6.7版本上進行測試&#xff0c;現況總結如下。如有紕漏&#xff0c;望指正。一.()一個命…

多進程和多線程之間的通信方式及通信實現步驟小結

進程間通信方式 # 管道( pipe )&#xff1a;管道是一種半雙工的通信方式&#xff0c;數據只能單向流動&#xff0c;而且只能在具有親緣關系的進程間使用。進程的親緣關系通常是指父子進程關系。 # 有名管道 (namedpipe) &#xff1a; 有名管道也是半雙工的通信方式&#xff0c;…

highcharts 顯示網格

2019獨角獸企業重金招聘Python工程師標準>>> xAxis: { gridLineColor: #197F07, gridLineWidth: 1 }, yAxis: { gridLineColor: #197F07, gridLineWidth: 2 }, 轉載于:https://my.oschina.net/LingBlog/blog/697885

Cheat—— 給Linux初學者和管理員一個終極命令行備忘單

編譯自&#xff1a;http://www.tecmint.com/cheat-command-line-cheat-sheet-for-linux-users/作者&#xff1a; Avishek Kumar原創&#xff1a;LCTT https://linux.cn/article-3760-1.html譯者&#xff1a; su-kaiyao原文稍有改動 當你不確定你所運行的命令&#xff0c;尤其是…

串口操作之API篇 CreateFile

CreateFile http://bbs.fishc.com/thread-72944-1-1.html(出處: 魚C論壇) ------------------------------------------------------------------------CreateFile用于打開串口,如果操作成功,返回一個句柄.1 function CreateFile(lpFileName: PChar; dwDesiredAccess, dwShareM…

云數據庫·ApsaraDB 產品6月刊

【重點關注】RDS發布新規格 RDS于5月下旬發布新產品規格&#xff0c;新規格對齊ECS配置:1.連接數大幅提升 互聯網型的應用特點是發展快速&#xff0c;在云上應用層會基于VM進行橫向擴展&#xff0c;對數據庫的要求除了資…

【同行說技術】教你玩轉iOS的5篇技術干貨

在文章《iOS從小白到大神必讀資料匯總一到四》這個系列中&#xff0c;深入介紹了iOS入門學習及進階的相關技術資料&#xff0c;今天小編繼續發布iOS學習的5篇干貨文章&#xff0c;趕緊來看看吧 &#xff01;喜歡寫博客的工程師博主可以加工程師博主交流群&#xff1a;391519124…

Qt Console Application 與 Qt GUI Application互轉

在桌面開發中&#xff0c;總的來說&#xff0c;包含兩種類型的應用程序&#xff1a;無界面的Console程序和有界面的GUI程序。Qt也不例外&#xff0c;包含Qt Console Application和Qt GUI Application。一、Qt Console Application在VS2015中創建一個Qt Console Application&…

Create Volume 操作(Part I) - 每天5分鐘玩轉 OpenStack(50)

2019獨角獸企業重金招聘Python工程師標準>>> 前面已經學習了 Cinder 的架構和相關組件&#xff0c;從本節我們開始詳細分析 Cinder 的各種操作&#xff0c;首先討論 Cinder 如何創建 volume。 Create 操作流程如下&#xff1a; 客戶&#xff08;可以是 OpenStack 最…

如何有效解決C與C++的相互調用問題

from&#xff1a;https://blog.csdn.net/gobitan/article/details/1532769在實際工作中可能經常要進行C和C的混合編程&#xff0c;C調用C語言的代碼通常都比較容易&#xff0c;但也有一些細節需要注意。C要調用C的代碼就略為麻煩一些&#xff0c;因為C不支持面向對象的特征。一…

Eclipse開發工具之崩潰和備份

1.通過在命令行中輸入“where java”&#xff0c;找到除jdk目錄下的所有java相關程序&#xff0c;直接刪掉&#xff08;一般會在C:WINDOWSsystem32下&#xff09;以后再也不用怕找不到目錄了 2.內存不足&#xff0c;打開Eclipse目錄下的eclipse.ini&#xff0c;把里面的-Xmx512…

IOS-網絡(監聽網絡狀態)

1 //2 // BWNetWorkTool.h3 // IOS_0131_檢測網絡狀態4 //5 // Created by ma c on 16/1/31.6 // Copyright © 2016年 博文科技. All rights reserved.7 //8 9 #import <Foundation/Foundation.h> 10 11 interface BWNetWorkTool : NSObject 12 ///是否是WiFi …

C++中的friend詳細解析

C中的友元機制允許類的非公有成員被一個類或者函數訪問&#xff0c;友元按類型分為三種&#xff1a;普通非類成員函數作為友元,類的成員函數作為友元&#xff0c;類作為友元。友元包括友元的聲明以及友元的定義。 友元的聲明默認為了extern&#xff0c;就是說友元類或者友元函數…

【VMCloud云平臺】擁抱Docker(六)關于DockerFile(1)

之前我們說過通過Docker pull來下載Images創建容器&#xff0c;這一次我們來聊下如何通過DockerFile創建Images再創建容器&#xff0c;Dockerfile也是Docker中的重點&#xff0c;使用DockerFile能夠更加便捷輕量的存儲標準化環境&#xff0c;也是環境管理的重要手段&#xff0c…

C++中相對路徑與絕對路徑以及斜杠與反斜杠的區別 及 處理代碼

轉載自&#xff1a;http://blog.csdn.net/sszgg2006/article/details/8447176文件路徑正斜杠和反斜杠正斜杠&#xff0c;又稱左斜杠&#xff0c;符號是"/"&#xff1b;反斜杠&#xff0c;也稱右斜杠&#xff0c;符號是"\"。文件路徑的表示可以分為絕對路徑…

01參考資料

《Visual C#經典游戲編程開發》 目標&#xff1a; 掌握小游戲開發的思路&#xff0c;在實際開發過程中&#xff0c;思考實踐面向對象&#xff0c;為cocos2d-x開發打下基礎轉載于:https://www.cnblogs.com/sharpfeng/p/5181260.html