01 #include <iostream>
02
03 #include <string>
04 using namespace std;
05 int a = 0; // Initialization Area of Overall
06 char *p1; // Not Initialization Area of Overall
07
08 void main()
09 {
10 int b; // stack
11 char s[] = "abc"; // stack
12 char *p2; // stack
13 char *p3 = "123456"; // p3 in stack
14 static int c =0; // Initialization Area of Static Overall
15 p1 = new char[10];
16 p2 = new char[20];
17 strcpy(p1, "123456");
18 cout<<p1;
19 delete [] p1;
20 delete [] p2;
21 }
程序說(shuō)明:
(1) 第5~6 行分別在函數(shù)體外部定義了兩個(gè)變量a 和p1,它們存儲(chǔ)在內(nèi)存的靜態(tài)存儲(chǔ)區(qū)域。
(2) 第10~13 行定義的變量b、s、p2、p3 為局部變量,存儲(chǔ)在內(nèi)存的堆棧區(qū)。
(3) 第14 行定義的變量c 為靜態(tài)局部變量,存儲(chǔ)在內(nèi)存的靜態(tài)存儲(chǔ)區(qū)域。
(4) 第17 行使用strcpy 函數(shù),將字符串“123456”復(fù)制給指針變量p1 指向的存儲(chǔ)單元。第18 行的輸出結(jié)果為“123456”。
知識(shí)點(diǎn):
(1) 當(dāng)編譯一個(gè)C++程序時(shí),計(jì)算機(jī)的內(nèi)存被分成了4 個(gè)區(qū)域:程序代碼區(qū)、全局變量區(qū)、堆棧區(qū)和堆區(qū)。堆是自由的內(nèi)存區(qū)域,可以通過(guò)new 和delete 把對(duì)象放在此區(qū)域,并可以在任何地方分配和釋放自由存儲(chǔ)區(qū)。
(2) C++中的變量可以分為全局變量、靜態(tài)全局變量、靜態(tài)局部變量和局部變量。其中,全局變量、靜態(tài)全局變量和靜態(tài)局部變量都存放在內(nèi)存的靜態(tài)存儲(chǔ)區(qū)域,局部變量存放在內(nèi)存的棧區(qū)。
① 局部靜態(tài)變量。在局部變量之前加上關(guān)鍵字static,局部變量就被定義成為一個(gè)局部靜態(tài)變量。
內(nèi)存中的位置:靜態(tài)存儲(chǔ)區(qū)。
初始化:未經(jīng)初始化的全局靜態(tài)變量會(huì)被程序自動(dòng)初始化為0(自動(dòng)對(duì)象的值是任意的,除非被顯式初始化)。
作用域:作用域指變量的有效范圍,當(dāng)定義它的函數(shù)或者語(yǔ)句塊結(jié)束時(shí),作用域隨之結(jié)束。
注意:當(dāng)static 用來(lái)修飾局部變量時(shí),它就改變了局部變量的存儲(chǔ)位置,從原來(lái)的棧中存放改為靜態(tài)存儲(chǔ)區(qū)。但是局部靜態(tài)變量在離開(kāi)作用域之后,并沒(méi)有被銷(xiāo)毀,而是仍然駐留在內(nèi)存中,直到程序結(jié)束,只不過(guò)不能再對(duì)它進(jìn)行操作了。
② 全局靜態(tài)變量。在全局變量之前加上關(guān)鍵字static,全局變量就被定義成為一個(gè)全局靜態(tài)變量。
內(nèi)存中的位置:靜態(tài)存儲(chǔ)區(qū)(靜態(tài)存儲(chǔ)區(qū)在整個(gè)程序運(yùn)行期間都存在)。
初始化:未經(jīng)初始化的全局靜態(tài)變量會(huì)被程序自動(dòng)初始化為0(自動(dòng)對(duì)象的值是任意的,除非被顯式初始化)。
作用域:全局靜態(tài)變量在聲明它的文件之外是不可見(jiàn)的,準(zhǔn)確地講,是從定義處開(kāi)始到文件結(jié)尾。
注意:當(dāng)static 用來(lái)修飾全局變量時(shí),它就改變了全局變量的作用域(在聲明它的文件之外是不可見(jiàn)的),但是沒(méi)有改變它的存放位置,還是在靜態(tài)存儲(chǔ)區(qū)。
③ 靜態(tài)函數(shù)。在函數(shù)的返回類(lèi)型前加上關(guān)鍵字static,該函數(shù)就被定義成為靜態(tài)函數(shù)。
函數(shù)的定義和聲明默認(rèn)情況下是 extern 的,但靜態(tài)函數(shù)只在聲明它的文件中可見(jiàn),不能被其他文件所用。
④ 靜態(tài)數(shù)據(jù)成員。
內(nèi)存中的位置:靜態(tài)存儲(chǔ)區(qū)。
初始化和定義:
靜態(tài)數(shù)據(jù)成員定義時(shí)要分配空間,不能在類(lèi)聲明中定義。
靜態(tài)數(shù)據(jù)成員在程序中只能提供一個(gè)定義。靜態(tài)數(shù)據(jù)成員的初始化不能在類(lèi)的頭文件中。
訪問(wèn):
類(lèi)實(shí)例名.靜態(tài)數(shù)據(jù)成員
類(lèi)類(lèi)型名::靜態(tài)數(shù)據(jù)成員
說(shuō)明:
static 數(shù)據(jù)成員和普通數(shù)據(jù)成員一樣遵循public,protected,private 訪問(wèn)規(guī)則。
對(duì)于非靜態(tài)數(shù)據(jù)成員,每個(gè)類(lèi)實(shí)例都有自己的備份。靜態(tài)數(shù)據(jù)成員被當(dāng)做類(lèi)的全局對(duì)象,無(wú)論這個(gè)類(lèi)的對(duì)象被定義了多少個(gè),靜態(tài)數(shù)據(jù)成員在程序中也只有一個(gè)備份,由該類(lèi)類(lèi)型的所有對(duì)象共享訪問(wèn)。
同全局對(duì)象相比,使用靜態(tài)數(shù)據(jù)成員有兩個(gè)優(yōu)勢(shì):
靜態(tài)數(shù)據(jù)成員沒(méi)有進(jìn)入程序的全局名字空間,因此不存在與程序中其他全局名字沖突的可能性。
靜態(tài)數(shù)據(jù)成員可以實(shí)現(xiàn)信息隱藏。靜態(tài)成員可以是 private 成員,而全局對(duì)象不可以。
靜態(tài)數(shù)據(jù)成員的唯一性本質(zhì)(獨(dú)立于類(lèi)的任何對(duì)象而存在的唯一實(shí)例),使它能夠以獨(dú)特的方式被使用,這些方式對(duì)于非static數(shù)據(jù)成員來(lái)說(shuō)是非法的。
⑤ 靜態(tài)成員函數(shù)。在類(lèi)的成員函數(shù)返回值之前加上關(guān)鍵字static,它就被聲明為一個(gè)靜態(tài)成員函數(shù)。靜態(tài)成員函數(shù)不能聲明為const 或volatile,這與非靜態(tài)成員函數(shù)不同。
定義:出現(xiàn)在類(lèi)體外的函數(shù)定義不能指定關(guān)鍵字static。
作用域:主要用于對(duì)靜態(tài)數(shù)據(jù)成員的操作。
靜態(tài)成員函數(shù)與類(lèi)相聯(lián)系,不與類(lèi)的對(duì)象相聯(lián)系。
靜態(tài)成員函數(shù)不能訪問(wèn)非靜態(tài)數(shù)據(jù)成員,因?yàn)榉庆o態(tài)數(shù)據(jù)成員屬于特定的類(lèi)實(shí)例。
靜態(tài)成員函數(shù)沒(méi)有this指針,因此在靜態(tài)成員函數(shù)中隱式或顯式地引用這個(gè)指針都將導(dǎo)致編譯時(shí)刻錯(cuò)誤。試圖訪問(wèn)隱式引用this指針的非靜態(tài)數(shù)據(jù)成員也會(huì)導(dǎo)致編譯時(shí)刻錯(cuò)誤。
訪問(wèn):可以用成員訪問(wèn)操作符(.)和箭頭(->)為一個(gè)類(lèi)實(shí)例或指向類(lèi)實(shí)例的指針調(diào)用靜態(tài)成
員函數(shù),也可以用限定修飾符名直接訪問(wèn)或調(diào)用靜態(tài)成員函數(shù),而無(wú)需聲明類(lèi)實(shí)例