一.本質區別
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)的結果又是多少呢?這個數就不一定了,原因是strlen會去計算a地址開始的字符串的長度,由於前一種賦值方式會將hh以字 符串的形式賦值給數組會將字符串結束符’\0’一同賦值,這時strlen就會檢查到結束符停止計算,而第二種復值方式是以單個字符的形式賦值沒有結束 符’\0’,這時我們用sizeof得到的結果是正常的,而用strlen由於找不到結束符,會繼續的計算直到找到結束符為止。所以這個數是不確定。
作者“成長之路”