說明:數組的數據類型是一種構造類型,而存儲數組的內存是一段連續的存儲區域。數組的數據類型決定了連續內存的訪問方式,它包括數組的三要素:起始地址、步長以及元素個數。
一.一維數組
1.形式:type 數組名[N],type為該一維數組中元素的類型(即步長),N表示該數組中的元素個數,而數組名則是數組元素的起始地址,例如:int arr[10];
2.數組的大小:sizeof(數組名)=元素類型所含字節數*元素個數;
3.初始化:
1 int arr1[10] = {1,2,3}; 2 //部分初始化(前三個元素) 3 int arr3[10] = {0}; 4 //數組清零
4.訪問:數組名是數組的唯一標識符,數組名具有兩重含義。
a.就作為數組名時,表示一種構造類型,此時可以用來打印數組的大小(包含的字節數),例如:
1 printf("%d",sizeof(數組名));
b.數組名用來訪問成員時,它表示的是首元素的地址,而對數組名取地址的時候,它表示的是整個數組的首地址,因此,以下代碼的輸出結果是不一樣的,這個非常重要!
1 int arr[8] = {1,2,3}; 2 printf("%p\t%p\n",arr,arr+1); 3 printf("%p\t%p\n",&arr,&arr+1);
程序輸出結果:
二.二維數組
1.形式:type name[M][N],二維數組其實也可以看成是一個一維數組(任何多維數組都可以看成是一個一維數組),只是數據成員的的類型由基本類型(如:int、char等)變成了構造類型:一維數組(多維數組)。例如int arr[3][4]可以看成是int[4] arr[3],這是一個一維數組,數組名為arr,數組成員的類型為int[4](一維數組),數組中的元素個數為3,其它多維數組也可按此方式理解。
2.二維數組在邏輯和內存上的理解:二維數組在邏輯上可以理解為二維的,例如int arr[3][4],可以想成其含有3行4列,共3*4個元素,當然也可按上述方式去理解,則理解為該二維數組中含有3個一維數組,其中每個一維數組中又含有四個int類型的元素,這兩種方式其實是一致的。但是計算機的內存是線性的,這意味着內存對數據的存儲方式都是一維線性的,因此,二維數組的訪問方式可以有以下兩種:
1 //方式一 2 for(int i = 0;i<3;i++) 3 { 4 for(int j = 0;j<4;j++) 5 printf("%d ",arr[i][j]); 6 } 7 //方式二 8 int *p = (int*)arr; 9 for(int i = 0;i<sizeof(arr)/sizeof(int);i++) 10 printf("%d ",*p++);
3.就像是一維數組一樣,二維數組名也代表其第一個元素的地址,只不過這里的第一個元素的類型變成了一個一維數組,如int arr[3][4],執行arr+1實際上相當於是在二維數組的行間跳轉,因為arr代表的是第一個元素(一維數組),因此執行加一操作時,加的是該一維數組的大小。而執行&arr+1時,就像上面提到的一樣,加的是整個數組的大小,因為&arr+1代表的是整個數組的起始地址。
1 int arr[3][4]; 2 printf("%p %p\n",arr,arr+1); 3 printf("%p %p\n",&arr,&arr+1);
程序運行結果:
4.二維數組的訪問方式,如對於int arr[3][4],arr[i][j]表示二維數組第i行第j列的元素(第i個一維數組里面的第j個元素),也可以這樣來訪問:*(*(arr+i)+j),同樣表示第i行第j列的元素。對於第二種方式,可以這樣理解:首先,arr是一個二維數組,arr+i表示指向二維數組的第i行,對其*一次則從arr這個二維數組的二維數組模式降到了這個二維數組的第i行(即降維,從二維降到了第i個一維數組),同樣的道理,對該一維數組加j再*,則又從一維數組模式降維到了單個元素模式,這就取出了該二維數組的第i行第j列的元素。二維數組的兩種訪問方式如下:
1 //方式1 2 for(int i = 0;i<3;i++) 3 { 4 for(int j = 0;j<4;j++) 5 printf("%d ",arr[i][j]); 6 } 7 //方式2 8 for(int i = 0;i<3;i++) 9 { 10 for(int j = 0;j<4;j++) 11 printf("%d ",*(*(arr+i)+j)); 12 }
三.多維數組
1.形式:type name[x][y][z],同樣的道理,也可以理解為是這樣一個一維數組:type [y][z] name[x],這里不再贅述。
四.拓展:申請一個堆上的動態二維數組,數組的行列采用輸入方式確定,並且將數組初始化為0
1.C++模式(輸入行和列以空格或回車鍵分隔)

1 #include <iostream> 2 using namespace std; 3 4 int **getDoubleArray(int row,int col) 5 { 6 int **p = new int*[row]; 7 for(int i = 0;i<row;i++) 8 p[i] = new int[col]; 9 return p; 10 //返回堆上的二維空間 11 } 12 13 int main() 14 { 15 int i = 0,j = 0; 16 int row ,col; 17 cin>>row>>col; 18 int **arr = getDoubleArray(row,col); 19 for(i = 0;i<row;i++) 20 for(j = 0;j < col;j++) 21 arr[i][j] = 0; 22 23 //這里可完成對二維數組的初始化的操作 24 25 //釋放申請的空間 26 for(i = 0;i<row;i++) 27 delete [] arr[i]; 28 delete [] arr; 29 return 0; 30 }
2.c語言模式(輸入行和列以空格或回車鍵分隔)

1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int **getarray(int rowl, int col) 5 { 6 int **p = (int**)malloc(rowl * sizeof(int*)); 7 for (int i = 0; i < rowl; i++) 8 p[i] = (int*)malloc(col*sizeof(int)); 9 return p; 10 } 11 12 int main() 13 { 14 int a, b; 15 scanf("%d %d",&a,&b); 16 int **p = getarray(a, b); 17 for (int i = 0; i < a; i++) 18 { 19 for (int j = 0; j < b; j++) 20 p[i][j] = 0; 21 } 22 for (int i = 0; i < a; i++) 23 { 24 for (int j = 0; j < b; j++) 25 printf("%d ",p[i][j]) ; 26 } 27 for(int i = 0;i<a;i++) 28 free (p[i]); 29 free (p); 30 return 0; 31 }
注意:返回堆上的二維空間還有其它方式,這里暫時以以上兩種為例。