sizeof和strlen的區別,陣列和指標的區別
sizeof和strlen的區別:
1.sizeof是個關鍵字,因此,sizeof後面是變數名時可以不加括號,而strlen是個函式,必須加括號
2.sizeof是判斷引數所佔的記憶體大小,引數可以是型別,函式,而strlen有點像計數器,從某個記憶體地址開始計數,碰到"\0"時結束計數,引數只能是char *
3.sizeof編譯時確定,strlen時執行時確定
4.在呼叫函式中,陣列名作為形參的,會被編譯器當成指向陣列首地址的指標,因此作為sizeof的引數時等價於計算指標的大小,作為strlen()的引數時意義未改變
--測試sizeof關鍵字特性
#include <iostream> using namespace std; void main(void) { int a; char c[10]; char *p; cout<<<span style="color:#ff0000;">sizeof a</span><<endl; cout<<sizeof c<<endl; cout<<sizeof p<<endl; }
測試結果
--測函式作為sizeof引數
#include <iostream> using namespace std; int fun_int(); char fun_char(); float fun_float(); double fun_double(); char *fun_cp(); double *fun_cd(); void *fun_cvoid(); void fun_void(); void main(void) { cout<<sizeof(fun_int())<<endl; //等價於sizeof(int) cout<<sizeof(fun_char())<<endl; //等價於sizeof(char) cout<<sizeof(fun_float())<<endl; //等價於sizeof(float) cout<<sizeof(fun_double())<<endl; //等價於sizeof(double) cout<<sizeof(fun_cp())<<endl; //等價於sizeof(指標) cout<<sizeof(fun_cd())<<endl; //等價於sizeof(指標) cout<<sizeof(fun_cvoid())<<endl; //等價於sizeof(指標) cout<<sizeof(fun_void())<<endl; //編譯器錯誤 }
由編譯結果可知,當函式作為sizeof的引數時,實際上是用函式的返回值作為sizeof的引數,因此函式必須有返回值
--不用庫函式實現strlen()函式
size_t mystrlen(const char *str)
{
size_t i = 0;
while(str[i]!='\0')
i++;
return i;
}
--測試陣列作為引數傳遞時sizeof和strlen()不同的表現
執行結果:#include <iostream> using namespace std; void fun(char *str) { cout<<endl<<"fun"<<endl; cout<<"sizeof(str)="<<sizeof(str)<<endl; cout<<"strlen(str)"<<strlen(str)<<endl; } void main(void) { char str[10]; cout<<"sizeof(str)="<<sizeof(str)<<endl; cout<<"strlen(str)"<<strlen(str)<<endl; fun(str); }
結果中顯示,當陣列作為引數傳遞給函式時,sizeof 計算出來的值是指標的值,而不再是指標所指向的記憶體空間大小的值。但是是不是有點奇怪?str明明是10個位元組,strlen(str)怎麼就變成15個位元組了?
通過除錯檢視記憶體:
結果顯而易見了,因為沒有初始化陣列,因此陣列內部為亂碼,當執行strlen(str)時,strlen()從地址0x0019FF34開始計數,一直計數到0x0019FF40,讀取到00('\0')時才結束,因此算出了大小15個位元組,由此可見
初始化特別重要,可以避免不必要的錯誤!
前面的介紹中有提到陣列和指標作為引數時對sizeof和strlen()的影響,但是還不夠全面,由於strlen的引數只能是char *型別,因此測試的數字也只能是char []的陣列,下面詳細介紹陣列和指標的區別:
陣列和指標的區別:
1.定義時,當等號右邊為字串時,陣列是是分配在非常量區,指標指向的字串被分配在在常量區(只讀),因此陣列可通過下標更改其值,指標不可更改!
2.佔用的空間大小不同,陣列佔用所申請的記憶體大小,指標為4個位元組(假定計算機的定址大小為32位)
#include <iostream>
using namespace std;
void main(void)
{
static char sc[]="hello";
static char *sp="hello";
char c[] = "hello";
char *p="hello";
sc[0]='a'; //可更改
sp[0]='a'; //執行時報錯
c[0]='a'; //可更改
p[0]='a'; //執行時報錯
}
使用陣列時要特別注意,當陣列名作為引數傳遞給其他函式時,會變成指標的形式傳遞。