1. 程式人生 > >(C/C++學習心得)7.陣列及其訪問方式

(C/C++學習心得)7.陣列及其訪問方式

說明:陣列的資料型別是一種構造型別,而儲存陣列的記憶體是一段連續的儲存區域。陣列的資料型別決定了連續記憶體的訪問方式,它包括陣列的三要素:起始地址、步長以及元素個數。

一.一維陣列

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捕獲

二.二維陣列

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);

程式執行結果:

32獲

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 }
檢視程式碼

注意:返回堆上的二維空間還有其它方式,這裡暫時以以上兩種為例。