C語言中數組名和指針的區別 及 sizeof用法

  1. #i nclude <iostream.h>   
  2. int  main( int  argc,  char * argv[])   
  3. {   
  4. char  str[10];   
  5.   char  *pStr = str;   
  6.  cout <<  sizeof (str) << endl;   
  7.  cout <<  sizeof (pStr) << endl;   
  8.   return  0;   

 實際情況是:第6行輸出10,第7行輸出4;

 

先給出三個結論:

  (1)數組名的內涵在於其指代實體是一種數據結構,這種數據結構就是數組;

  (2)數組名的外延在於其可以轉換爲指向其指代實體的指針,而且是一個指針常量;

  (3)指向數組的指針則是另外一種變量類型(在WIN32平臺下,長度爲4),僅僅意味着數組的存放地址!

 

1、數組名指代一種數據結構:數組

  現在可以解釋爲什麼第1個程序第6行的輸出爲10的問題,根據結論1,數組名str的內涵爲一種數據結構,即一個長度爲10的char型數組,所以sizeof(str)的結果爲這個數據結構佔據的內存大小:10字節。

  1. int  intArray[10];   
  2. cout <<  sizeof (intArray) ;

第2行的輸出結果爲40(整型數組佔據的內存空間大小)。

 

2、數組名可作爲指針常量

  根據結論2,數組名可以轉換爲指向其指代實體的指針,所以程序1中的第5行數組名直接賦值給指針,程序2第7行直接將數組名作爲指針形參都可成立。

 

下面的程序成立嗎?

C++代碼
  1. int  intArray[10];   
  2. intArray++;

讀者可以編譯之,發現編譯出錯。原因在於,雖然數組名可以轉換爲指向其指代實體的指針,但是它只能被看作一個指針常量,不能被修改。

 

而指針,不管是指向結構體、數組還是基本數據類型的指針,都不包含原始數據結構的內涵,在WIN32平臺下,sizeof操作的結果都是4。
順 便糾正一下許多程序員的另一個誤解。許多程序員以爲sizeof是一個函數,而實際上,它是一個操作符,不過其使用方式看起來的確太像一個函數了。語句 sizeof(int)就可以說明sizeof的確不是一個函數,因爲函數接納形參(一個變量),世界上沒有一個C/C++函數接納一個數據類型(如 int)爲"形參"。

 

3、數據名可能失去其數據結構內涵

到這裏似乎數組名魔幻問題已經宣告圓滿解決,但是平靜的湖面上卻再次掀起波浪。請看下面一段程序:

C++代碼
  1. #i nclude <iostream.h>   
  2. void  arrayTest( char  str[])   
  3. {   
  4.  cout <<  sizeof (str) << endl;   
  5. }   
  6. int  main( int  argc,  char * argv[])   
  7. {   
  8.   char  str1[10] =  "I Love U" ;   
  9.  arrayTest(str1);   
  10.   return  0;   
  11. }  


  程序的輸出結果爲4。不可能吧?

  一個可怕的數字,前面已經提到其爲指針的長度!

  結論1指出,數據名內涵爲數組這種數據結構,在arrayTest函數體內,str是數組名,那爲什麼sizeof的結果卻是指針的長度?這是因爲:

  (1)數組名作爲函數形參時,在函數體內,其失去了本身的內涵,僅僅只是一個指針;

  (2)很遺憾,在失去其內涵的同時,它還失去了其常量特性,可以作自增、自減等操作,可以被修改。

  所以,數據名作爲函數形參時,其全面淪落爲一個普通指針!它的貴族身份被剝奪,成了一個地地道道的只擁有4個字節的平民。

 

 

一、sizeof的概念 

  sizeof是C語言的一種單目操作符,如C語言的其他操作符++、--等。它並不是函數。sizeof操作符以字節形式給出了其操作數的存儲大小。操作數可以是一個表達式或括在括號內的類型名。操作數的存儲大小由操作數的類型決定。

 

二、sizeof的使用方法 
  1、用於數據類型 
sizeof使用形式:sizeof(type) 
數據類型必須用括號括住 。如sizeof(int)。 
2、用於變量 
sizeof使用形式:sizeof(var_name)或sizeof var_name  
變量名可以不用括號括住。如sizeof (var_name),sizeof var_name等都是正確形式。帶括號的用法更普遍,大多數程序員採用這種形式。 

三。sizeof用法總結
VC中,sizeof有着許多的用法,而且很容易引起一些錯誤。下面根據sizeof後面的參數對sizeof的用法做個總結。
A. 參數爲數據類型或者爲一般變量。例如sizeof(int),sizeof(long)等等。這種情況要注意的是不同系統系統或者不同編譯器得到的結果可能是不同的 。例如int類型在16位系統中佔2個字節,在32位系統中佔4個字節。
B. 參數爲數組或指針。下面舉例說明.
int a[50]; //sizeof(a)=4*50=200; 求數組所佔的空間大小
#int* a= “hello world”,應該是12(要注意)
int *a=new int[50];// sizeof(a)=4; a爲一個指針,sizeof(a)是求指針
//的大小,在32位系統中,當然是佔4個字節。
C. 參數爲結構或類。Sizeof應用在類和結構的處理情況是相同的。但有兩點需要注意,第一、結構或者類中的靜態成員不對結構或者類的大小產生影響,因爲靜態變量的存儲位置與結構或者類的實例地址無關
第二、沒有成員變量的結構或類的大小爲1,因爲必須保證結構或類的每一 個實例在內存中都有唯一的地址。
下面舉例說明,
Class Test{int a;static double c};//sizeof(Test)=4.
Test *s;//sizeof(s)=4,s爲一個指針。
Class test1{ };//sizeof(test1)=1;
D. 參數爲其他。下面舉例說明。
int func(char s[5]);
{
cout<<sizeof(s)<<endl;
//數的參數在傳遞的時候系統處理爲一個指針,所
//以sizeof(s)實際上爲求指針的大小。
return 1;
}
sizeof(func(“1234”))=4//因爲func的返回類型爲int,所以相當於
//求sizeof(int). 還要注意的是“1234”而不是“12345”)
以上爲sizeof的基本用法,在實際的使用中要注意分析VC的分配變量的分配策略,這樣的話可以避免一些錯誤。


示例
char str[20]="0123456789"; int a=strlen(str); //a=10; >>>> strlen 計算字符串的長度,以結束符 0x00 爲字符串結束。
int b=sizeof(str); //而b=20; >>>> sizeof 計算的則是分配的數組 str[20] 所佔的內存空間的大小,不受裏面存儲的內容改變。

上面是對靜態數組處理的結果,如果是對指針,結果就不一樣了
char* ss = "0123456789";
sizeof(ss) 結果 4 ===》ss是指向字符串常量的字符指針,sizeof 獲得的是一個指針的之所佔的空間,
應該是長整型的 ,所以是4

sizeof(*ss) 結果 1 ===》*ss是第一個字符 其實就是獲得了字符串的第一位'0' 所佔的內存空間,
是char類型的, 佔了 1 位

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章