C語言中sizeof()與strlen()函數(shù)的使用入門及對比
sizeof()函數(shù)
1,是什么?
sizeof其實就是一個運算符,和那些+,-一樣的東西,在程序編譯的時候進行解析轉(zhuǎn)換。雖然我們經(jīng)常見到sizeof后面跟著個小括號,長得和函數(shù)差不多,但它和函數(shù)完全是兩碼事。
2,有什么用?
sizeof其實就是用于告訴我們編譯器在為某一特定數(shù)據(jù)或者某種數(shù)據(jù)類型的數(shù)據(jù)在存儲空間中開辟空間時,開辟的空間大小,以字節(jié)為單位。
3,怎么用?
sizeof(類型),或者sizeof(變量)都可以,得到的就是類型或者變量的存儲空間。當(dāng)對變量用的時候,也可以沒有括號,直接 sizeof 變量,但一般不用(我一般都是只記一種通用的用法……)。
4,用的時候要注意什么?
(1)sizeof返回的占用空間大小是為這個變量開辟的大小,而不只是它用到的空間。和現(xiàn)今住房的建筑面積和實用面積的概念差不多。所以對結(jié)構(gòu)體用的時候,大多情況下就得考慮字節(jié)對齊的問題了。
(2)對位域成員等連編譯器都無法確定存儲空間的東西不能用。這個應(yīng)該比較好理解,因為sizeof返回的都是以字節(jié)為單位的數(shù)據(jù),你讓它去求那些以位為單位的大小,這不是存心難為編譯器嘛。所以編譯器采用的方案是統(tǒng)一不受理,即使你說你剛好是8位,占一個字節(jié),編譯器也不理你。
(3)sizeof返回的數(shù)據(jù)類型是unsigned int。因為C中不同類型數(shù)據(jù)混合運算時的自動轉(zhuǎn)換,有時候不注意的話可能會出問題,具體可以參照下面的程序例子。
(4)要注意數(shù)組名和指針變量的區(qū)別。通常情況下,我們總覺得數(shù)組名和指針變量差不多,但是在用sizeof的時候差別很大,對數(shù)組名用sizeof返回的是整個數(shù)組的大小,而對指針變量進行操作的時候返回的則是指針變量本身所占得空間,在32位機的條件下一般都是4。而且當(dāng)數(shù)組名作為函數(shù)參數(shù)時,在函數(shù)內(nèi)部,形參也就是個指針,所以不再返回數(shù)組的大小。
5,實例分析
源碼:
#include<stdio.h> int main() { int iVal = 3; printf("The size of type int is %d \n", sizeof(int)); printf("The size of iVal is %d\n", sizeof(iVal)); printf("The size of iVal is %d\n", sizeof iVal); if((iVal - sizeof(int)) < 0) { printf("The return type is int\n"); } else { printf("The return type is unsigned int\n"); } char chArrayCon[7]; char *chp; chp = chArrayCon; printf("The size of chArrayCon is %d, The size of chp is %d\n", sizeof(chArrayCon), sizeof(chp)); int iArraySize = 3; char chArrayVar[iArraySize]; printf("The size of chArrayVar is %d\n", sizeof(chArrayVar)); return 0; }
運行結(jié)果:
The size of type int is 4 The size of iVal is 4 The size of iVal is 4 The return type is unsigned int The size of chArrayCon is 7, The size of chp is 4 The size of chArrayVar is 3
結(jié)果分析:
代碼第一部分主要就是簡單的表示了一下用法。
第二部分說明了注意事項的第三項。按說,iVal的值是3,減4的話應(yīng)該是-1,小于0,輸出的應(yīng)該是"he return type is int"。但是由于當(dāng)int和unsigned int一起運算時,會默認(rèn)變成unsigned int,所以結(jié)果會是一個很大的unsigned int類型的數(shù),是大于0的。
代碼第三部分就簡單說明了數(shù)組名和指針變量的區(qū)別,即使你把指針變量指向數(shù)組名,編譯器依然能夠分辨出區(qū)別。
以上講述的都沒有考慮在C99標(biāo)準(zhǔn)下的情況。因為在C99標(biāo)準(zhǔn)下有種特殊情況,那就是不定長數(shù)組的使用。當(dāng)對不定長數(shù)組名使用sizeof的話,返回的也是整個數(shù)組的大小,就像實例中第四塊代碼一樣。但是這并不是在編譯階段執(zhí)行的,而是在程序運行階段執(zhí)行的。因為在編譯的時候,編譯器一般不知道變量的值是多少。(當(dāng)然例子中我直接賦值3,可能不方便理解,可以假想iArraySize是通過scanf來獲得實際數(shù)值的,然后再聲明數(shù)組的)。對于這種情況,實際中應(yīng)用的并不多,大家可以當(dāng)做特殊情況對待即可,或者直接忽略掉也行……
6總結(jié)
其實sizeof的作用就是告訴我們分配給變量的“建筑面積”的大小,只要記得這一點應(yīng)該就夠了,不管這個變量類型是普通的整型數(shù)據(jù),還是結(jié)構(gòu)體,共用體,枚舉……記住這一點后,當(dāng)我們再去想知道sizeof對不同數(shù)據(jù)類型操作返回的值到底是什么的時候,只需搞明白那些數(shù)據(jù)類型到底要消耗多少“建筑面積”就可以啦!
strlen()函數(shù)
C庫函數(shù) size_t strlen(const char *str) 計算字符串str的長度,但不包括終止空字符。
聲明
以下是聲明的strlen() 函數(shù)。
size_t strlen(const char *str)
參數(shù)
str -- 這是字符串的長度要計算的。
返回值
這個函數(shù)返回字符串的長度。
例子
下面的例子顯示使用strlen() 函數(shù)。
#include <stdio.h> #include <string.h> int main () { char str[50]; int len; strcpy(str, "This is yiibai.com"); len = strlen(str); printf("Length of |%s| is |%d| ", str, len); return(0); }
讓我們編譯和運行上面的程序,這將產(chǎn)生以下結(jié)果:
Length of |This is yiibai.com| is |26|
sizeof與strlen的用法區(qū)別
1. sizeof操作符的結(jié)果類型是size_t,它在頭文件中typedef為unsigned int類型。該類型保證能容納實現(xiàn)所建立的最大對象的字節(jié)大小。
2. sizeof是運算符(C++ 關(guān)鍵字),strlen是函數(shù)。
3. sizeof可以用類型做參數(shù),strlen只能用char*做參數(shù),且必須是以”\0”結(jié)尾的。sizeof還可以用函數(shù)做參數(shù),比如:
short f(); printf("%d\n", sizeof(f()));
輸出的結(jié)果是返回值的類型的大小, 即sizeof(short)=2。
4. 數(shù)組做sizeof的參數(shù)不退化,傳遞給strlen就退化為指針了。大部分編譯程序在編譯的時候就把sizeof計算過了,是類型或是變量的長度,這就是sizeof(x)可以用來定義數(shù)組維數(shù)的原因。
char str[20]="0123456789"; int a=strlen(str); //a=10; int b=sizeof(str); //b=20;
而strlen的結(jié)果要在運行的時候才能計算出來,是用來計算字符串的長度,不是類型占內(nèi)存的大小。
5. sizeof后如果是類型必須加括弧,如果是變量名可以不加括弧。這是因為sizeof是個操作符不是個函數(shù)。
6. 當(dāng)適用了于一個結(jié)構(gòu)類型時或變量, sizeof 返回實際的大小,當(dāng)適用一靜態(tài)地空間數(shù)組, sizeof 得到全部數(shù)組的尺寸。sizeof 操作符不能返回動態(tài)地被分派了的數(shù)組或外部的數(shù)組的尺寸。
7. 數(shù)組作為參數(shù)傳給函數(shù)時傳的是指針而不是數(shù)組,傳遞的是數(shù)組的首地址,如:
fun(char [8]) fun(char [])
都等價于 fun(char *)。
在C++里參數(shù)傳遞數(shù)組永遠都是傳遞指向數(shù)組首元素的指針,編譯器不知道數(shù)組的大小。如果想在函數(shù)內(nèi)知道數(shù)組的大小, 需要這樣做:
進入函數(shù)后用memcpy拷貝出來,長度由另一個形參傳進去
fun(unsiged char *p1, int len) { unsigned char* buf = new unsigned char[len+1] memcpy(buf, p1, len); }
sizeof對指針的話,結(jié)果是相應(yīng)的類型:
char* ss = "0123456789"; sizeof(ss)
結(jié)果是4 => ss是指向字符串常量的字符指針,sizeof 獲得的是一個指針的之所占的空間,應(yīng)該是長整型的,所以是4. sizeof(*ss) 結(jié)果 1, => *ss是第一個字符,其實就是獲得了字符串的第一位“0” 所占的內(nèi)存空間,是char類型的,占了1個字節(jié),strlen(ss)= 10 >>>> 如果要獲得這個字符串的長度,則一定要使用 strlen.
相關(guān)文章
C/C++利用棧和隊列實現(xiàn)停車場管理系統(tǒng)
數(shù)據(jù)結(jié)構(gòu)的課程設(shè)計一般都不是很好理解,今天小編為大家總結(jié)了一下c和c++版本的常見棧和隊列的的停車場管理程序,需要的小伙伴可以參考一下2022-06-06C++實現(xiàn)修改函數(shù)代碼HOOK的封裝方法
這篇文章主要介紹了C++實現(xiàn)修改函數(shù)代碼HOOK的封裝方法,有助于深入了解C++的HOOK原理,需要的朋友可以參考下2014-10-10