天天看點

C語言中sizeof與strlen差別

一.本質差別

sizeof和strlen有本質上的差別。sizeof是c語言的一種單目運算符,如++、--等,并不是函數,sizeof的優先級為2級,比/、% 等3級運算符優先級高,sizeof以位元組的形式給出操作數的存儲空間的大小。而strlen是一個函數,是由c語言的标準庫提供的。strlen計算的 是字元串的長度。

二.使用差別

1.sizeof

sizeof的操作數可以是資料類型、函數、變量,表達式使用方式為:

(1)資料類型

sizeof (type)

例如我們要計算一個int型資料的存儲空間可以用: sizeof(int)。需要注意的是sizeof的操作數是資料類型時要加括号。其數值大小為該資料類型所占的存儲空間的位元組數。

(2)變量

sizeof(變量名)

如果定義 int a ,可以使用sizeof (a)計算a變量占據的存儲空間。具體大小與a的類型有關。

注意:由于sizeof是操作符sizeof a或sizeof (a)都可以。(可以不使用括号),如果操作數是數組名則給出數組所占用記憶體的位元組數。如果數組名做函數的參數傳遞時退化為指針。

(3)表達式

sizeof (表達式)

sizeof可以對一個表達式求值,編譯器根據表達式的最終結果類型來确定大小,一般不會對表達式進行計算。例如:sizeof(1+1.5)

(4)函數調用

sizeof(函數名())

sizeof也可以對一個函數調用求值,其結果是函數傳回類型的大小,函數并不會被調用,舉例來說定義如下函數:

int myprint()

{

   printf(“hello\n”);

   return 0;

}

int main()

printf(“%d”,sizeof(mypaint()));

return 0;

結果隻列印函數傳回類型的sizeof值,并沒有列印hello說明函數myprint并沒有調用。

c99标準規定,函數、不能确定類型的表達式以及位域(bit-field)成員不能被計算sizeof值,即下面這些寫法都是錯誤的:

如:sizeof(myprint)(注意sizeof(myprint()是可以的))

或者sizeof一個void傳回類型的函數如:

void foo () { }

sizeof( foo () );

     以及位域:

struct s

unsigned int f1 : 1;

unsigned int f2 : 5;

unsigned int f3 : 12;

};

sizeof( s.f1 );

2.strlen

strlen的應用則不像sizeof那麼廣泛,strlen的參數必須是char *的指針,如果用strlen計算資料類型strlen(int)這種用法是錯誤的。strlen的計算必須依賴字元序列中的’\0’字元,strlen 就是通過判斷是否遇到’\0’來判斷字元序列是否結束的。

它的計算原理類似于下面的兩條語句

while(*p!=’\0’)

    length++

strlen的用法:分為以下幾種參數

(1)char * 指針

strlen(指針名)

如果參數是指針則計算該指針指向字元序列的長度。(以’\0’作為判斷标志)例如:

定義char *p=“hello world”;strlen(p)=11,而sizeof (p)=4。可以看到strlen計算的是指針指向的字元串的長度而sizeof計算的是指針本身所占用的記憶體空間的大小。

(2)數組

strlen(數組名)

如果參數是數組的話,實際傳遞的是一個指針,strlen會按照上面處理指針的模式處理該數組。

我們可以看下面的例子:

char a[]=”hh”;

         strlen(a);

很顯然strlen的結果是2。但是如果數組是這樣指派的呢?

char a[]={‘h’,’h’};

那麼現在strlen(a)的結果又是多少呢?這個數就不一定了,原因是strlen會去計算a位址開始的字元串的長度,由于前一種指派方式會将hh以字 符串的形式指派給數組會将字元串結束符’\0’一同指派,這時strlen就會檢查到結束符停止計算,而第二種複值方式是以單個字元的形式指派沒有結束 符’\0’,這時我們用sizeof得到的結果是正常的,而用strlen由于找不到結束符,會繼續的計算直到找到結束符為止。是以這個數是不确定。