字符串所占字節(jié)數(shù)分析

string與strlen

字符串賦值的時候會不會在末尾自動添加'\0'?

char *s="\ta\017bc"中指針變量s 指向的字符串所占字節(jié)數(shù)是6的原因。

'\t' 是一個轉(zhuǎn)義字符相當(dāng)于鍵盤“Tab”鍵

‘a(chǎn)’ 普通字符

'\017'轉(zhuǎn)義字符ASCII代碼值為8進制數(shù)17即10進制數(shù)15的那個符號(LZ可以自己去查下看是什么符號)

‘b’ 普通字符

‘c’普通字符

然后再加一個字符串結(jié)束標(biāo)志‘\0’所以指針變量s,指向的字符串所占字節(jié)數(shù)是6

char *s="\ta\017bc";

for(;*s!='\0';s++)printf("*")//用查詢的方法去統(tǒng)計字節(jié)數(shù)

需要明確的第一點,strlen所作的僅僅是一個計數(shù)器的工作,它從內(nèi)存的某個位置(可以是字符串開頭,中間某個位置,甚至是某個不確定的內(nèi)存區(qū)域)開始掃描,直到碰到第一個字符串結(jié)束符'\0'為止,然后返回計數(shù)器值。

例如以下代碼片斷理論上也是可以編譯通過的:

char str[]="abcdefg";

printf("%d\n",strlen(&str[5]));

結(jié)果應(yīng)當(dāng)為2。該例中,strlen從字符str[5]即'f'開始計數(shù),當(dāng)?shù)竭_'g'之后遇到'\0'并停止計數(shù)。因此結(jié)果為2。

str2和str3的主要區(qū)別就在于C/C++字符串中,允許形如“\056”這樣的所謂轉(zhuǎn)義字符存在,它們僅表示一個字節(jié)位(byte),一般用于輸出無法直接通過鍵盤輸入的字符。

str0的sizeof為8,導(dǎo)致沒有\(zhòng)0結(jié)束,因此strlen的返回是不可預(yù)期的。

str1的sizeof實際上是9,會自動加\0結(jié)束。

str2的\056會被解釋成8進制數(shù)056表示的字符,因此strlen是9,轉(zhuǎn)義字符

str3的\0會被解釋為結(jié)束符

二、sizeof深入理解。

1.sizeof操作符的結(jié)果類型是size_t,它在頭文件中typedef為unsigned int類型。該類型保證能容納實現(xiàn)所建立的最大對象的字節(jié)大小。

2.sizeof是算符,strlen是函數(shù)。

3.sizeof可以用類型做參數(shù),strlen只能用char*做參數(shù),且必須是以'\0'結(jié)尾的。sizeof還可以用函數(shù)做參數(shù),比如:

short f();

printf("%d\n", sizeof(f()));

輸出的結(jié)果是sizeof(short),即2。

4.數(shù)組做sizeof的參數(shù)不退化,傳遞給strlen就退化為指針了。

5.大部分編譯程序 在編譯的時候就把sizeof計算過了是類型或是變量的長度這就是sizeof(x)可以用來定義數(shù)組維數(shù)的原因

char str[20]="0123456789";

int a=strlen(str); //a=10;

int b=sizeof(str); //而b=20;

6.strlen的結(jié)果要在運行的時候才能計算出來,時用來計算字符串的長度,不是類型占內(nèi)存的大小。

7.sizeof后如果是類型必須加括弧,如果是變量名可以不加括弧。這是因為sizeof是個操作符不是個函數(shù)。

8.當(dāng)適用了于一個結(jié)構(gòu)類型時或變量, sizeof 返回實際的大小, 當(dāng)適用一靜態(tài)地空間數(shù)組, sizeof 歸還全部數(shù)組的尺 寸。sizeof 操作符不能返回動態(tài)地被分派了的數(shù)組或外部的數(shù)組的尺寸

9.數(shù)組作為參數(shù)傳給函數(shù)時傳的是指針而不是數(shù)組,傳遞的是數(shù)組的首地址,如:

fun(char [8])

fun(char [])

都等價于 fun(char *)在C++里傳遞數(shù)組永遠都是傳遞指向數(shù)組首元素的指針,編譯器不知道數(shù)組的大小如果想在函數(shù)內(nèi)知道數(shù)組的大小,需要這樣做:進入函數(shù)后用memcpy拷貝出來,長度由另一個形參傳進去

10.計算結(jié)構(gòu)變量的大小就必須討論數(shù)據(jù)對齊問題。為了CPU存取的速度最快(這同CPU取數(shù)操作有關(guān),詳細的介紹可以參考一些計算機原理方面的書),C++在處理數(shù)據(jù)時經(jīng)常把結(jié)構(gòu)變量中的成員的大小按照4或8的倍數(shù)計算,這就叫數(shù)據(jù)對齊(dataalignment)。這樣做可能會浪費一些內(nèi)存,但理論上速度快了。當(dāng)然這樣的設(shè)置會在讀寫一些別的應(yīng)用程序生成的數(shù)據(jù)文件或交換數(shù)據(jù)時帶來不便。MSVC++中的對齊設(shè)定,有時候sizeof得到的與實際不等。一般在VC++中加上#pragmapack(n)的設(shè)定即可.或者如果要按字節(jié)存儲,而不進行數(shù)據(jù)對齊,可以在Options對話框中修改Advancedcompiler頁中的Data alignment為按字節(jié)對齊。

11.sizeof操作符不能用于函數(shù)類型,不完全類型或位字段。不完全類型指具有未知存儲大小的數(shù)據(jù)類型,如未知存儲大小的數(shù)組類型、未知內(nèi)容的結(jié)構(gòu)或聯(lián)合類型、void類型等。如sizeof(max)若此時變量max定義為int max(),sizeof(char_v) 若此時char_v定義為char char_v [MAX]且MAX未知,sizeof(void)都不是正確形式

三、結(jié)束語

sizeof使用場合。

1.sizeof操作符的一個主要用途是與存儲分配和I/O系統(tǒng)那樣的例程進行通信。例如:

void *malloc(size_t size),

size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。

2.用它可以看看一類型的對象在內(nèi)存中所占的單元字節(jié)。

void * memset(void * s,int c,sizeof(s))

3.在動態(tài)分配一對象時,可以讓系統(tǒng)知道要分配多少內(nèi)存。

4.便于一些類型的擴充,在windows中就有很多結(jié)構(gòu)內(nèi)型就有一個專用的字段是用來放該類型的字節(jié)大小。

5.由于操作數(shù)的字節(jié)數(shù)在實現(xiàn)時可能出現(xiàn)變化,建議在涉及到操作數(shù)字節(jié)大小時用sizeof來代替常量計算。

6.如果操作數(shù)是函數(shù)中的數(shù)組形參或函數(shù)類型的形參,sizeof給出其指針的大小。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容