深入浅出之数组
數組:一個固定大小的相同類型元素的順序集合。
1. 聲明數組
在 C++ 中要聲明一個數組,需要指定元素的類型和元素的數量,如下所示:
一維數組 type arrayName [ arraySize ]; 二維數組 type arrayName [ arraySize ][ arraySize ] ; 三維數組 type arrayName [ arraySize ][ arraySize ][ arraySize ] ;2. 初始化數組
在 C++ 中,您可以逐個初始化數組,也可以使用一個初始化語句,如下所示:
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};大括號 { } 之間的值的數目不能大于我們在數組聲明時在方括號 [ ] 中指定的元素數目。
如果您省略掉了數組的大小,數組的大小則為初始化時元素的個數。因此,如果:
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};您將創建一個數組,它與前一個實例中所創建的數組是完全相同的。下面是一個為數組中某個元素賦值的實例:
balance[4] = 50.0;上述的語句把數組中第五個元素的值賦為 50.0。所有的數組都是以 0 作為它們第一個元素的索引,也被稱為基索引,數組的最后一個索引是數組的總大小減去 1。以下是上面所討論的數組的的圖形表示:
一個二維數組可以被認為是一個帶有 x 行和 y 列的表格。下面是一個二維數組,包含 3 行和 4 列:
因此,數組中的每個元素是使用形式為 a[ i , j ] 的元素名稱來標識的,其中 a 是數組名稱,i 和 j 是唯一標識 a 中每個元素的下標。
3. 訪問數組元素
數組元素可以通過數組名稱加索引進行訪問。元素的索引是放在方括號內,跟在數組名稱的后邊。例如:
double salary = balance[9];?4. 指針與數組關系
詳見《深入淺出之指針》
5. 一數組作為函數形參
有如下幾種方式:
方式 1
形式參數是一個指針:
void myFunction(int *param) { . . . }本質是指針傳遞
方式 2
形式參數是一個已定義大小的數組:
void myFunction(int param[10]) { . . . }本質是值傳遞
方式 3
形式參數是一個已定義大小的數組:
void myFunction(int param[], int size) { . . . }本質是指針傳遞
方式 4
形式參數是一個未定義大小的數組:
void myFunction(int param[]) { . . . }本質是指針傳遞
本質上是以下三種形式的演變
void func(const int*); void func(const int[]); void func(const int[10])//這里的維度表示我們期望數組含有多少元素,實際不一定多維數組名作函數參數?
多維數組元素可以作為函數參數,這點與一維數組的情況類似。
可以用多維數組名作為函數的形參和實參,在被調用函數中對形參數組定義時可以指定每一維的大小,也可以省略第一維的大小說明,如:
int array[3][10]
或
int array[ ][10]
二者都是等價且合法的。但是不能把第二維以及其他高維的大小說明省略。如下定義是不合法的:int array[ ][ ] int array[3][ ]
多維數組使用技巧,可以將多維數組轉變為一維數組方式簡化
比如對于數組 int p[m][n],可以定義為int p[m*n]方式
?6. 數組作為函數返回值
C++ 不允許返回一個完整的數組作為函數的參數。但是,您可以通過指定不帶索引的數組名來返回一個指向數組的指針。
如果您想要從函數返回一個一維數組,您必須聲明一個返回指針的函數,如下:
int * myFunction() { . . . }
另外,C++ 不支持在函數外返回局部變量的地址,除非定義局部變量為?static?變量。
#include <iostream> #include <cstdlib> #include <ctime>using namespace std;// 要生成和返回隨機數的函數 int * getRandom( ) {static int r[10];// 設置種子srand( (unsigned)time( NULL ) );for (int i = 0; i < 10; ++i){r[i] = rand();cout << r[i] << endl;}return r; }// 要調用上面定義函數的主函數 int main () {// 一個指向整數的指針int *p;p = getRandom();for ( int i = 0; i < 10; i++ ){cout << "*(p + " << i << ") : ";cout << *(p + i) << endl;}return 0; }7. 數組的引用?
7.1、數組的引用
切入:可以將一個變量定義成數組的引用(這個變量和數組的類型要相同)
形式:
| 1 2 3 | int?odd[5] = {1, 3, 5, 7, 9}; int?(&arr)[5] = odd;????????//中括號內的數一定要和所引用的數組的維度一樣 cout << arr[3] << endl;?????//等價于odd[3] |
解讀:注意上面代碼中的形式,因為arr引用了數組odd,故arr變成了數組的別名。
7.2、作為形參
難點:對應形參/實參的寫法、怎么運用該形參
寫法:
1 #include <iostream>2 #include <vector>3 #include <cctype>4 #include <string>5 #include <iterator>6 #include <initializer_list>7 8 using namespace std; 9 10 void print(int (&arr)[5]) 11 { 12 for (auto i : arr) 13 cout << i << endl; 14 } 15 16 int main() 17 { 18 int odd[5] = {1, 3, 5, 7, 9}; 19 print(odd); 20 return 0; 21 }運用:把該形參名視為所綁定的數組的名字使用即可。
優點:節省內存消耗,不用拷貝一份數組,直接使用原數組(甚至可以修改原數組)。
助記:我們不妨以string對象的引用來輔助記憶,因為string就像是一個字符數組,只是它沒有確定的容量。
1 #include <iostream>2 #include <vector>3 #include <cctype>4 #include <string>5 #include <iterator>6 #include <initializer_list>7 8 using namespace std; 9 10 //void print(int (&arr)[5]) 11 void print(string &arr) //相比數組,只是少了一個[維度] 12 { 13 for (auto i : arr) 14 cout << i << endl; 15 } 16 17 int main() 18 { 19 // int odd[5] = {1, 3, 5, 7, 9}; 20 string ss = "hello world"; 21 // print(odd); 22 print(ss); 23 return 0; 24 }7.3、作為返回類型
難點:對應返回類型的寫法、怎么使用該返回的引用
知識:因為數組不能被拷貝,所以函數不能返回數組,但可以返回數組的引用(和數組的指針)
寫法:
1 /* 題目:編寫一個函數的聲明,使其返回包含10個string對象的數組的引用 */ 2 //不用類型別名3 string (&func(形參))[10]; 4 //類型別名 5 using arrS = string[10];6 arrS& func(形參);7 //尾置返回類型 8 auto func(形參) -> string(&)[10];9 //decltype關鍵字 10 string ss[10]; 11 decltype(ss) &func(形參);運用:返回一個數組的引用怎么用?
1 #include <iostream>2 #include <vector>3 #include <cctype>4 #include <string>5 #include <iterator>6 #include <initializer_list>7 8 using namespace std; 9 10 int odd[] = {1, 3, 5, 7, 9}; 11 int even[] = {0, 2, 4, 6, 8}; 12 13 //int (&func(int i))[5] 14 //auto func(int i) -> int(&)[5] 15 decltype(odd) &func(int i) 16 { 17 return (i % 2) ? odd : even; 18 } 19 20 int main() 21 { 22 cout << func(3)[1] << endl; //輸出3 23 return 0; 24 }助記:既然返回的數組的引用,而它又只是一個名字(不帶維度),我們把它視為所引用的數組(在該函數內返回的那個數組)的別名即可。
補充:返回的是數組的引用,那么函數里也應該返回的是數組!
助記:
1 int &func(int a, int b)2 {3 return a > b ? a : b;4 } 5 //函數調用結束后,返回b的引用,返回引用的優點在于不用拷貝一個值返回 6 7 int main()8 { 9 int x = 3, y = 4; 10 int ans = func(x, y); //ans = 4 11 return 0; 12 }參考:
?
?
?
總結
- 上一篇: 深入浅出之函数的参数传递方式
- 下一篇: 深入浅出之命名空间