c++有很多有意思的小點,今天來記錄下這些點
- 字符串
- 變量聲明
- 指針
1、字符串
c++中有兩類字符串:
- c風(fēng)格字符串,其實就是字符數(shù)組,但數(shù)組以
\0結(jié)尾 - string對象,和java中的字符串對象類似,它是一個類對象,并不是數(shù)組
c風(fēng)格字符串的聲明也有好幾種
char cstr[] = "hellookunu";
char cstr2[] = {'a','b' ,'c' ,'d' ,'e'};
const char* p = "hellochengcheng";
以上三種寫法,因為數(shù)組名其實就是數(shù)組第一個元素的指針,可以認(rèn)為 cstr 和 &cstr[0] 這兩種寫法是等價的,所以可以用 char* 來聲明字符串。
值得一題的是,在c++中,"hellookunu" 叫字符串常量或字符串字面值,它在c++中存儲的格式其實是什么呢?
(const char [11])"hellookunu"
所以,字符串常量真實的存儲格式就是c風(fēng)格字符串,以指針形式存儲在內(nèi)存中,返回的是第一個字符的地址。所以c風(fēng)格字符串的三種初始化方式是合法的,因為左右兩邊的類型確實相同。
2、變量聲明
c++和java在使用變量之前都必須進行變量聲明,但java還要求對變量初始化才可以使用變量。c++也有初始化這個過程,但c++和java在細(xì)微之處還是截然不同的。
struct person {
char name[6];
int age;
};
person ok;
strcpy(ok.name, "okunu");
ok.age = 1;
注意結(jié)構(gòu)體ok的聲明,只聲明ok,并沒有對ok進行初始化,之后就可以對ok屬性賦值了。在java中,這種操作肯定會報錯的,必須初始化對象,否則對象為null值,為對象的屬性賦值也會報錯,因為對象為null。但在c++中是可以的。這就是c++和java的細(xì)微差別了。
在c++中,只要為一個對象聲明,就會為此對象分配內(nèi)存了,所以當(dāng)聲明結(jié)構(gòu)體ok時,內(nèi)存中已經(jīng)有一塊區(qū)域?qū)儆谒?,這塊區(qū)域內(nèi)存儲著ok的各項屬性值,此時當(dāng)然可以為ok屬性賦值。
而在java中,如果只聲明一個對象,例如 Person p; java對象的內(nèi)存分為兩塊,p這個對象引用存儲在棧中,而p所指向的person對象存儲在堆中,不過抱歉的是,由于沒有通過new操作初始化,p此時所指向的對象為null,故不能對p的屬性進行賦值,否則會出現(xiàn)空指針異常。
c++中,如果聲明一個指針,例如
person* p;
p->age = 1;
這是一種錯誤的寫法,聲明的是指針 p,而不是對象,指針?biāo)加玫膬?nèi)存通常是4個字節(jié),聲明一個指針后,系統(tǒng)會為指針分配一塊內(nèi)存,用于存儲這個指針,但指針?biāo)赶虻膬?nèi)存區(qū)域并沒有被分配出來,需要開發(fā)者手動分配內(nèi)存,例如通過 new 關(guān)鍵字來分配內(nèi)存。
person* p = new person;
person per;
p = &per;
可以通過上述兩種方法分配指針?biāo)赶虻膬?nèi)存區(qū)域,這樣才算真正地完成了指針地初始化,指針才可以使用,不會報錯。值得一提的是,c++中,通過new 分配的內(nèi)存也是保存在堆中。
分析指針和java的兩種使用方法,其實質(zhì)是一模一樣的,java中的對象名,某種程序上就是指針。java號稱沒有指針,虛擬機自動回收內(nèi)存,不需要開發(fā)者手動來delete內(nèi)存,但它的實質(zhì)和c++使用指針一模一樣,先為指向?qū)ο蟮闹羔樂峙鋬?nèi)存,如果開發(fā)使用new來初始化對象,則為對象真正地分配內(nèi)存。
指針寫法
指針的格式有很多種,常見的有下幾種:
int* pn; //指向int的指針
int* (*fun)(int *); //函數(shù)指針
int** fun(int*); //fun是一個函數(shù),函數(shù)返回值為指向int指針的指針
int* (*fun[3])(int*); //數(shù)組,數(shù)組內(nèi)的元素是函數(shù)指針
指針的寫法必須記住了,其實這與 * 的結(jié)合律有關(guān)系,*它的優(yōu)先級低于() 也低于 [] ,所以第三行中,fun優(yōu)先與后邊的括號結(jié)合,與括號結(jié)合,則表明fun是一個函數(shù)。
第二行中,用括號將 * 和 fun 括起來,則 fun 優(yōu)先與*結(jié)合,說明 fun 是一個指針,它指向的內(nèi)容是一個函數(shù)
第四行中,fun 優(yōu)先與 [] 結(jié)合,所以fun是一個數(shù)組,fun 左邊的 * 號則表明,數(shù)組中的元素是指針。
指針的寫法有很多,還有更多更復(fù)雜的,面試這些,我們可以使用typedef來簡化它,更多的內(nèi)容還得用心一一體會才行。