C++:一維數組和二維數組


 

 一維數組:int a[c],其中a是數組名稱,c是數組維度,數組維度必須是常量表達式!例如:

1 int c=3;
2 int a[c];//錯誤!由於c不是常量表達式,所以該定義非法。若將c定義為const int,即c成為一個常量表達式,則可正常編譯。

 

  數組的初始化:

int a[3]={1,2};//正確!等價於a[3]={1,2,0}
int b[3]={1,2,3,4};//錯誤!初始值過多。
int c[]={1,2};//正確!等價於c[2]={1,2}
string d[3]={"hi","bye"};//正確!等價於d[3]={“"hi","bye",”“}

//字符數組的特殊性:一定要注意字符串字面值得結尾處還有一個空字符!
char e[]={"C++"};//自動在字符串結束出添加空字符! char e[3]={"C++"}//錯誤!沒有空間可存放空字符!

//不允許拷貝和賦值
int f[]={1,2};
int g[]=f;//錯誤!不允許用一個數組初始化另一個數組。
g=f;//錯誤,不能把一個數組賦值給另一個數組。

 

  數組元素的訪問可以通過數組名+下標號訪問,此處應注意的問題是數組的下標是否在合理范圍之內(這是有程序員負責檢查的),當下標越界的時候,會引起一種嚴重的程序故障:緩沖區溢出(buffer overflow)。

  在用到數組名的地方,編譯器會自動地將其替換成一個指向數組首元素的指針。從一個指針加上或減去一個整數,結果仍然是指針,新指針指向的元素與原來的指針相比前進或后退了該整數個位置!

   資料:

  數組名的本質是代表數組對象的變量名,是一個左值,是一個不能被改變的左值。但是由於在程序中不保存數組的大小,所以通過數組名只能訪問數組的左值,不能訪問數組的右值。由於這個原因,數組名在作為右值使用的時候被賦予另外一個新的意義——指向數組第一個元素的指針,這就是    array-to-pointer   轉換規則。  數組名在程序中作為左值使用的情況屈指可數——在大部分情況下數組名都是作為右值使用的,這時它是一個指針,一個指向數組第一個元素的指針,一個指向不能再被改變的指針——因此是一個指針常量。 那么數組名在什么情況下作為左值使用的呢?根據標准的規定,只有當數組名作為sizeof、&運算符的操作數的時候,它是一個左值,類型為數組類型;除此之外的所有情況,數組名都是一個右值,被編譯器自動轉換為指針類型,這種情況下我們就說數組名是一個指針,並且是一個指針常量。  單純地說數組名是一個指針是片面的。我們通常說數組名是一個指針是建立在一個前提的基礎之上的,那就是:數組名作為右值使用的時候。  對於數組名總結如下:  在作為左值使用的時候,數組名表示數組對象,是數組類型。在作為右值使用的時候,數組名是一個指針,是指針類型,不再是數組類型。數組名到底是數組還是指針取決於其上下文環境。
  PS:左值指的是能夠出現在等號左邊及右邊的變量(表達式),右值則指的是只能出現在等號右邊的變量(表達式)。左值就是在程序中能夠尋址的東西,右值就是沒法取到它的地址的東西(不完全准確)。

二維數組:c++中實際上並沒有多維數組,通常所說的多維數組本質上是數組的數組!!! 例如,int a[2][3]={{1,2,3},{4,5,6}}表示一個大小為2的數組,每個元素是含有3個整數的數組。

  首先強調一下指針的概念(C++指針詳解),不能簡單把指針看成地址,不要忽略掉數據類型。也就是說一個指針包含兩方面,一個是地址,一個是數據類型。指針是變量,這個變量的值是個地址。變量的類型是指向一個數據類型。可能有兩個指針的值一樣但是他們其實是不一樣的,因為他們指向的數據類型不一樣,此時使用取內容符號*取得的東西就會不一樣了。例如:對於二維數組int a[2][3]={1,2,3,4,5,6},a是一個指針,a[0]也是一個指針,並且這兩個指針的值是一樣的,但是它們的數據類型不同!所以對它們用*取內容所得結果也不一樣,*a[0]是一個整數:1。因為a[0]就是指向的類型就是整數,占4個字節。使用*a[0]以后,系統會從a[0]開始往后取4個字節。然后把這4個字節的內容轉化為一個整數也就是我們的a[0][0]了;*a是一個地址。因為a指向的是一個大小為3的整數數組:{1,2,3},*a表示的就是a[0]。此外還有指針的運算問題注意*(p+n)恆等與p[n]! a+1還是個指針,指向的數據類型也不變,不過他的值變成a+sizeof(a所指向的數據類型),也就是到了a這個指針的值往后跳一個它所指數據類型這么大小的那個內存地址。而a[0]+1則表示a[0]指向的值得下一個整數!

例子:

int a[2][3]={0,1,2,3,4,5};
cout<<sizeof(a)<<std::endl;
cout<<*a<<endl;//輸出結果等於a[0]的地址,即{0,1,2}的地址。
cout<<**a<<endl;//輸出0
cout<<a[0]<<endl;//輸出a[0][0]的地址。
cout<<*a[0]<<endl;//輸出0
cout<<*a[1]<<endl;//輸出3
cout<<**(a+1)<<endl;//輸出3
cout<<*(a[0]+1)<<endl;//輸出1
 

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM