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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章