一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

字符串文字量

 若渴若愚 2011-11-17

站在巨人肩上的思考[連載] (8)

5.2 數(shù)組

5.2.2 字符串文字量

類似”this is a string.”這樣一個字符串文字量,它是一個常量。正如代碼中一個顯式的數(shù)字0xff08一樣,其值不可以被更改。如想修改,可以通過復(fù)制給一個變量來實現(xiàn):

int a = 0xff08;

a = 0xff18;

對于字符串文字量則有一點要注意:

char* cp = “this is a string”; //危險!賦值給一個普通字符指針;

cp[4] = ‘e’; //未定義行為!不能給常量賦值;

char p[] = “this is a string”; //可以;

p[4] = ‘e’; //正確執(zhí)行;

可以看出,用char *來引用字符串文字量是一個十分危險的地方。在上例中cp[4]=’e’;可以通過編譯,但是在執(zhí)行期間產(chǎn)生了一個Segmentation Fault。也就是說編譯器并不能幫助程序員發(fā)現(xiàn)這類錯誤。

我個人是這樣認(rèn)為的:字符串文字量是一中很底層的數(shù)據(jù),編譯器把他放進匯編語言中的數(shù)據(jù)段;普通的char*指針也是一種很底層的指針,他可以指向內(nèi)存空間中的任何地址;char* cp = “this is a string”;僅僅在??臻g生成一個指針,然后把他指向位于數(shù)據(jù)段的”this is a string”,初始化并不會導(dǎo)致錯誤。但是利用cp[4]更改數(shù)據(jù)段中的數(shù)據(jù)內(nèi)容將會導(dǎo)致段錯誤,數(shù)據(jù)段是只讀的。而利用char p[]形式的時候,意味著將在??臻g中生成一個字符數(shù)組,然后用”this is a string”來進行初始化,而后p指向這個棧空間中字符數(shù)組的首地址。此時p[4]=’e’;修改的是??臻g中的值,而不是數(shù)據(jù)段中的值。

但是p是什么類型呢?是char*么?他的大小是多少?是1么?為了使指針和數(shù)組首地址之間的區(qū)別更具普遍意義,我們用int類型來測試一下:

char p[] = "hello";

char* ptr = p;

cout << sizeof(p) << ":" << sizeof(*p) << endl;

cout << p << ":" << *p << endl;

cout << sizeof(ptr) << ":" << sizeof(*ptr) << endl;

cout << ptr << ":" << *ptr << endl;

這段代碼在我的電腦上的輸出是:

[/home/gavin/test]# ./test

6:1

hello:h

4:1

hello:h

ptr是真正的char*類型,其sizeof4,但是psizeof卻是6,也就是”hello”加一個‘\0’的長度。除此之外,ptrp表現(xiàn)都一樣。但我們最好認(rèn)為p是字符數(shù)組類型,而ptr才是字符指針類型,因為他們的行為上存在差異。很多教師、教材都說:“數(shù)組名就是指向數(shù)組首地址的指針?!边@其實并不完全正確。

再仔細(xì)看看,我們cout<<pcout<<ptr的期望輸出應(yīng)該是pptr分別表示的地址。但事實上卻是數(shù)組的內(nèi)容。為了明顯區(qū)分,再看下面這段代碼:

int arr[4] = {0};

int* pa = arr;

cout << sizeof(arr) << ":" << sizeof(*arr) << endl;

cout << arr << ":" << *arr << endl;

cout << sizeof(pa) << ":" << sizeof(*pa) << endl;

cout << pa << ":" << *pa << endl;

在我的電腦上輸出為:

[/home/gavin/test]# ./test

16:4

0xbfc26e5c:0

4:4

0xbfc26e5c:0

sizeof的輸出剛才已經(jīng)說過。這里可以看出,int數(shù)組名和char數(shù)組名的行為也不一樣。事實上,cha數(shù)組名與標(biāo)準(zhǔn)類型數(shù)組名的行為都不一樣。這也就是為什么C風(fēng)格字符串為許多人詬病的地方。

C++在這方面提供了很好的改進:用一種更上層的類型string來代替C風(fēng)格字符串。并強烈建議程序員在程序中盡量使用string來代替char *。這里是你需要做出選擇的地方:

string str1("1");

string str2("1234567");

string str3("1234567890123456789012345678901234567890");

/*

char str1[] = "1";

char str2[] = "1234567";

char str3[] = "1234567890123456789012345678901234567890";

*/

cout << sizeof(str1) << endl;

cout << sizeof(str2) << endl;

cout << sizeof(str3) << endl;

當(dāng)利用C風(fēng)格字符串的輸出為:

[/home/gavin/test]# ./test

2

8

41

[/home/gavin/test]# ls -l

-rwxrwxr-x 1 863 863 6559 Dec 3 14:29 test

-rw-rw-r-- 1 863 863 391 Dec 3 14:29 test.cpp

而當(dāng)使用string時:

[/home/gavin/test]# ./test

4

4

4

[/home/gavin/test]# ls -l

-rwxrwxr-x 1 863 863 7578 Dec 3 14:30 test

-rw-rw-r-- 1 863 863 390 Dec 3 14:30 test.cpp

我們也許可以得到如下結(jié)論:stingchar[]需要更少的運行時內(nèi)存空間,但是char[]卻比string占用更少的磁盤空間。你可以自己選擇向左還是向右走。不過相比string的易用性、安全性、以及諸多的成員函數(shù)帶來的實用功能來說,我個人并不認(rèn)為char[]節(jié)省的磁盤空間是很突出的優(yōu)點。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日本高清不卡一二三区| 91在线播放在线播放观看| 一区二区日韩欧美精品| 国产偷拍精品在线视频| 国产三级视频不卡在线观看| 91精品蜜臀一区二区三区| 国产成人国产精品国产三级| 好吊视频一区二区在线| 久七久精品视频黄色的| 五月的丁香婷婷综合网| 午夜传媒视频免费在线观看| 91欧美激情在线视频| 日韩欧美综合在线播放| 国产精品美女午夜福利| 亚洲国产精品久久网午夜| 国产人妻熟女高跟丝袜| 亚洲国产精品一区二区| 国产精品福利一级久久| 日韩av欧美中文字幕| 午夜午夜精品一区二区| 欧美日韩欧美国产另类| 懂色一区二区三区四区| 欧美日不卡无在线一区| 欧美成人一区二区三区在线 | 国产精品福利一二三区| 日本黄色高清视频久久| 中文字幕乱码亚洲三区| 亚洲欧美日产综合在线网| 亚洲熟女乱色一区二区三区| 好吊妞在线免费观看视频| 91在线国内在线中文字幕| 91在线国内在线中文字幕| 超碰在线免费公开中国黄片| 欧美日韩乱码一区二区三区| 日本加勒比系列在线播放| 日本在线不卡高清欧美| 日本妇女高清一区二区三区| 亚洲一区二区三区有码| 亚洲欧美国产中文色妇| 日韩精品一区二区一牛| 精品欧美在线观看国产|