1. 程式人生 > >sizeof和strlen的區別總結

sizeof和strlen的區別總結

一、sizeof的概念 
  sizeof是C語言的一種單目操作符,如C語言的其他操作符++、--等。它並不是函式。sizeof操作

符以位元組形式給出了其運算元的儲存大小。運算元可以是一個表示式或括在括號內的型別名。運算元

的儲存大小由運算元的型別決定。 

二、sizeof的使用方法 
  1、用於資料型別 

  sizeof使用形式:sizeof(type) 

  資料型別必須用括號括住。如sizeof(int)。 

  2、用於變數 

  sizeof使用形式:sizeof(var_name)或sizeof var_name 

  變數名可以不用括號括住。如sizeof (var_name),sizeof var_name等都是正確形式。帶括號

的用法更普遍,大多數程式設計師採用這種形式。 

  注意:sizeof操作符不能用於函式型別,不完全型別或位欄位。不完全型別指具有未知儲存大小

的資料型別,如未知儲存大小的陣列型別、未知內容的結構或聯合型別、void型別等。 

  如sizeof(max)若此時變數max定義為int max(),sizeof(char_v) 若此時char_v定義為char 

char_v [MAX]且MAX未知,sizeof(void)都不是正確形式。 

三、sizeof的結果 
  sizeof操作符的結果型別是size_t,它在標頭檔案中typedef為unsigned int型別。該型別保證能

容納實現所建立的最大物件的位元組大小。 

  1、若運算元具有型別char、unsigned char或signed char,其結果等於1。 

  ANSI C正式規定字元型別為1位元組。 

  2、int、unsigned int 、short int、unsigned short 、long int 、unsigned long

 、float、double、long double型別的sizeof 在ANSI C中沒有具體規定,大小依賴於實現,一

般可能分別為2、2、2、2、4、4、4、8、10。 

  3、當運算元是指標時,sizeof依賴於編譯器。例如Microsoft C/C++7.0中,near類指標位元組數

為2,far、huge類指標位元組數為4。一般Unix的指標位元組數為4。 

  4、當運算元具有陣列型別時,其結果是陣列的總位元組數。 

  5、聯合型別運算元的sizeof是其最大位元組成員的位元組數。結構型別運算元的sizeof是這種型別

物件的總位元組數,包括任何墊補在內。 

  讓我們看如下結構: 

  struct {char b; double x;} a; 

  在某些機器上sizeof(a)=12,而一般sizeof(char)+ sizeof(double)=9。 

  這是因為編譯器在考慮對齊問題時,在結構中插入空位以控制各成員物件的地址對齊。如double

型別的結構成員x要放在被4整除的地址。 

  6、如果運算元是函式中的陣列形參或函式型別的形參,sizeof給出其指標的大小。 

四、sizeof與其他操作符的關係 
  sizeof的優先順序為2級,比/、%等3級運算子優先順序高。它可以與其他操作符一起組成表示式。如

i*sizeof(int);其中i為int型別變數。 

五、sizeof的主要用途 
  1、sizeof操作符的一個主要用途是與儲存分配和I/O系統那樣的例程進行通訊。例如: 

  void *malloc(size_t size), 

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

  2、sizeof的另一個的主要用途是計算陣列中元素的個數。例如: 

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

六、建議 
  由於運算元的位元組數在實現時可能出現變化,建議在涉及到運算元位元組大小時用ziseof來代替常

量計算。

深入理解sizeof

一、好首先看看sizeof和strlen在MSDN上的定義:

首先看一MSDN上如何對sizeof進行定義的:
sizeof Operator

sizeof expression

The sizeof keyword gives the amount of storage, in bytes, associated with a variable or

a type
(including aggregate types). This keyword returns a value of type size_t.

The expression is either an identifier or a type-cast expression (a type specifier

enclosed in
parentheses).

When applied to a structure type or variable, sizeof returns the actual size, which may

include
padding bytes inserted for alignment. When applied to a statically dimensioned array,

sizeof
returns the size of the entire array. The sizeof operator cannot return the size of

dynamically
allocated arrays or external arrays.
然後再看一下對strlen是如何定義的:

strlen

Get the length of a string.

Routine Required Header:
strlen

size_t strlen( const char *string );
Parameter
string:Null-terminated string
Libraries
All versions of the C run-time libraries.

Return Value
Each of these functions returns the number of characters in string, excluding the

terminal
NULL. No return value is reserved to indicate an error.

Remarks
Each of these functions returns the number of characters in string, not including the
terminating null character. wcslen is a wide-character version of strlen; the argument

of
wcslen is a wide-character string. wcslen and strlen behave identically otherwise.

二、由幾個例子說開去。

第一個例子:
char * ss = "0123456789";
sizeof(ss) 結果 4 ===》ss是指向字串常量的字元指標
sizeof(*ss) 結果 1 ===》*ss是第一個字元

char ss[] = "0123456789";
sizeof(ss) 結果 11 ===》ss是陣列,計算到\0位置,因此是10+1
sizeof(*ss) 結果 1 ===》*ss是第一個字元

char ss[100] = "0123456789";
sizeof(ss) 結果是100 ===》ss表示在記憶體中的大小 100×1
strlen(ss) 結果是10 ===》strlen是個函式內部實現是用一個迴圈計算到\0為止之前

int ss[100] = "0123456789";
sizeof(ss) 結果 400 ===》ss表示再記憶體中的大小 100×4
strlen(ss) 錯誤 ===》strlen的引數只能是char* 且必須是以''\0''結尾的

char q[]="abc";
char p[]="a\n";
sizeof(q),sizeof(p),strlen(q),strlen(p);
結果是 4 3 3 2     
第二個例子:
class X
{
int i;
int j;
char k;
};
X x;
cout<cout<
第三個例子:
char szPath[MAX_PATH]

  如果在函式內這樣定義,那麼sizeof(szPath)將會是MAX_PATH,但是將szPath作為虛參宣告時(

void fun(char szPath[MAX_PATH])),sizeof(szPath)卻會是4(指標大小)

三、sizeof深入理解。
1.sizeof操作符的結果型別是size_t,它在標頭檔案中typedef為unsigned int型別。該型別保證能容

納實現所建立的最大物件的位元組大小。
2.sizeof是算符,strlen是函式。
3.sizeof可以用型別做引數,strlen只能用char*做引數,且必須是以''\0''結尾的。sizeof還可以

用函式做引數,比如:
short f();
printf("%d\n", sizeof(f()));
輸出的結果是sizeof(short),即2。
4.陣列做sizeof的引數不退化,傳遞給strlen就退化為指標了。
5.大部分編譯程式 在編譯的時候就把sizeof計算過了 是型別或是變數的長度這就是sizeof(x)可以

用來定義陣列維數的原因
char str[20]="0123456789";
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;

6.strlen的結果要在執行的時候才能計算出來,編譯時用來計算字串的長度,不是型別佔記憶體的大小。
7.sizeof後如果是型別必須加括弧,如果是變數名可以不加括弧。這是因為sizeof是個操作符不是個

函式。
8.當適用了於一個結構型別時或變數, sizeof 返回實際的大小, 當適用一靜態地空間陣列,

sizeof 歸還全部陣列的尺 寸。 sizeof 操作符不能返回動態地被分派了的陣列或外部的陣列的尺寸
9.陣列作為引數傳給函式時傳的是指標而不是陣列,傳遞的是陣列的首地址,如:
fun(char [8])
fun(char [])

都等價於 fun(char *) 在C++裡傳遞陣列永遠都是傳遞指向陣列首元素的指標,編譯器不知道陣列的

大小如果想在函式內知道陣列的大小, 需要這樣做:進入函式後用memcpy拷貝出來,長度由另一個

形參傳進去
fun(unsiged char *p1, int len)
{
unsigned char* buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}

有關內容見: C++ PRIMER?
10.計算結構變數的大小就必須討論資料對齊問題。為了CPU存取的速度最快(這同CPU取數操作有關

,詳細的介紹可以參考一些計算機原理方面的書),C++在處理資料時經常把結構變數中的成員的大

小按照4或8的倍數計算,這就叫資料對齊(data alignment)。這樣做可能會浪費一些記憶體,但理論

上速度快了。當然這樣的設定會在讀寫一些別的應用程式生成的資料檔案或交換資料時帶來不便。MS

VC++中的對齊設定,有時候sizeof得到的與實際不等。一般在VC++中加上#pragma pack(n)的設定即

可.或者如果要按位元組儲存,而不進行資料對齊,可以在Options對話方塊中修改Advanced compiler頁

中的Data alignment為按位元組對齊。
11.sizeof操作符不能用於函式型別,不完全型別或位欄位。不完全型別指具有未知儲存大小的資料

型別,如未知儲存大小的陣列型別、未知內容的結構或聯合型別、void型別等。如sizeof(max)若此

時變數max定義為int max(),sizeof(char_v) 若此時char_v定義為char char_v [MAX]且MAX未知

,sizeof(void)都不是正確形式
四、結束語

sizeof使用場合。
1.sizeof操作符的一個主要用途是與儲存分配和I/O系統那樣的例程進行通訊。例如: 
  void *malloc(size_t size), 
  size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。

2.用它可以看看一型別的物件在記憶體中所佔的單元位元組。
void * memset(void * s,int c,sizeof(s))

3.在動態分配一物件時,可以讓系統知道要分配多少記憶體。
4.便於一些型別的擴充,在windows中就有很多結構內型就有一個專用的欄位是用來放該型別的位元組大

小。
5.由於運算元的位元組數在實現時可能出現變化,建議在涉及到運算元位元組大小時用sizeof來代替常量

計算。
6.如果運算元是函式中的陣列形參或函式型別的形參,sizeof給出其指標的大小。

注意:

sizeof是運算子 當編譯器編譯時 會自動運算這個變晨的大小的 並使用它的大小代替sizeof的值

int len = sizeof(int);
編譯時 編譯器計算出int的大小 大小為4 所以把上面這句變成
int len = 4

偶用到 sizeof 和 strlen 的時候,通常是計算字串陣列的長度
看了上面的詳細解釋,發現兩者的使用還是有區別的,從這個例子可以看得很清楚:

char str[20]="0123456789";
int a=strlen(str); //a=10; >>>> strlen 計算字串的長度,以結束符 0x00 為字串結束。
int b=sizeof(str); //而b=20; >>>> sizeof 計算的則是分配的陣列 str[20] 所佔的記憶體空間的大

小,不受裡面儲存的內容改變。

strlen計算的是字串的長度
sizeof計算的是變數使用的記憶體大小