由sizeof()引出的對陣列名和指標的新認識

營養不良的紅發表於2015-08-21

在C++中,陣列名和指標有很多類似的地方,甚至很多時候,陣列名與指標可以互相替換,我也一直以為兩者沒什麼值得注意的區別,直到看到了一道題,才發覺自己知識的匱乏。

void UpperCase(char str[]) // 將 str 中的小寫字母轉換成大寫字母 
{
	for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i )        
	if( 'a'<=str[i] && str[i]<='z' )            
	str[i] -= ('a'-'A' );
}  
char str[] = "aBcDe"; 
cout << "str字元長度為: " << sizeof(str)/sizeof(str[0]) << endl; 
UpperCase( str ); cout << str << endl; 

上面這段程式碼中兩個sizeof的用法有問題嗎?

有!函式內的sizeof有問題。根據語法,sizeof(陣列名)可以測得陣列的容量,所以函式外的sizeof(str)等於6,沒問題。但是當陣列名作為函式引數進行傳遞的時候,就會退化成一個指標,所以函式體裡str是一個指標,而指標是4個位元組,因此sizeof(str)等於4

可以看出,陣列名與指標還是有區別的,陣列名並不單純的是一個指標(陣列名和指標之間有一個不同之處,指標是一個變數,但陣列名不是變數)。這也是為什麼陣列名作為引數傳遞時,經常需要一個長度引數。

對於strlen來說,就沒有這麼多問題了,strlen本身就是一個函式(sizeof是操作符),strlen所作的僅僅是一個計數器的工作,它從記憶體的某個位置(可以是字串開頭,中間某個位置,甚至是某個不確定的記憶體區域)開始掃描,直到碰到第一個字串結束符'\0'為止,然後返回計數器值(長度不包含“\0”)

如果還有疑問,可以參考http://www.cnblogs.com/wuzhenbo/archive/2012/05/29/2523777.html

相關文章