純為MARK sizeof strlen

來源:互聯網
上載者:User

援引:

http://www.vckbase.com/document/viewdoc/?id=1054

 

深入理解sizeof

作者:房秉毅

  最近在論壇裡總有人問關於sizeof的問題,並且本人對這個問題也一直沒有得到很好的解決,索性今天對它來個較為詳細的總結,同時結合strlen進行比較,如果能對大家有點點協助,這是我最大的欣慰了。

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

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

sizeof Operatorsizeof expressionThe 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是如何定義的:

strlenGet the length of a string.Routine Required Header:strlen <string.h>size_t strlen( const char *string );Parameterstring:Null-terminated string LibrariesAll versions of the C run-time libraries.Return ValueEach of these functions returns the number of characters in string, excluding the terminal NULL. No return value is reserved to indicate an error.RemarksEach 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+1sizeof(*ss) 結果 1 ===》*ss是第一個字元char ss[100] = "0123456789";sizeof(ss) 結果是100 ===》ss表示在記憶體中的大小 100×1strlen(ss) 結果是10 ===》strlen是個函數內部實現是用一個迴圈計算到/0為止之前int ss[100] = "0123456789";sizeof(ss) 結果 400 ===》ss表示再記憶體中的大小 100×4strlen(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<<sizeof(X)<<endl; 結果 12 ===》記憶體補齊cout<<sizeof(x)<<endl; 結果 12 同上

第三個例子:

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給出其指標的大小。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.