1. 程式人生 > >sizeof和strlen的區別,陣列和指標的區別

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';		//執行時報錯
}


使用陣列時要特別注意,當陣列名作為引數傳遞給其他函式時,會變成指標的形式傳遞。