1. 程式人生 > 其它 >新手入門C語言第十一章:C陣列

新手入門C語言第十一章:C陣列

C 陣列

 

C 語言支援陣列資料結構,它可以儲存一個固定大小的相同型別元素的順序集合。陣列是用來儲存一系列資料,但它往往被認為是一系列相同型別的變數。

陣列的宣告並不是宣告一個個單獨的變數,比如 runoob0、runoob1、...、runoob99,而是宣告一個數組變數,比如 runoob,然後使用 runoob[0]、runoob[1]、...、runoob[99] 來代表一個個單獨的變數。

所有的陣列都是由連續的記憶體位置組成。最低的地址對應第一個元素,最高的地址對應最後一個元素。

 

 

陣列中的特定元素可以通過索引訪問,第一個索引值為 0。

 

 

宣告陣列

在 C 中要宣告一個數組,需要指定元素的型別和元素的數量,如下所示:

type arrayName [ arraySize ];

這叫做一維陣列。arraySize 必須是一個大於零的整數常量,type 可以是任意有效的 C 資料型別。例如,要宣告一個型別為 double 的包含 10 個元素的陣列 balance,宣告語句如下:

double balance[10];

現在 balance 是一個可用的陣列,可以容納 10 個型別為 double 的數字。

初始化陣列

在 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。以下是上面所討論的陣列的的圖形表示:

 

 

下圖是一個長度為 10 的陣列,第一個元素的索引值為 0,第九個元素 runoob 的索引值為 8:

訪問陣列元素

陣列元素可以通過陣列名稱加索引進行訪問。元素的索引是放在方括號內,跟在陣列名稱的後邊。例如:

double salary = balance[9];

上面的語句將把陣列中第 10 個元素的值賦給 salary 變數。下面的例項使用了上述的三個概念,即,宣告陣列、陣列賦值、訪問陣列:

例項

#include <stdio.h>
int main () 
{ 
   int n[ 10 ]; /* n 是一個包含 10 個整數的陣列 */
   int i,j;      

   /* 初始化陣列元素 */ 
   for ( i = 0; i < 10; i++ ) 
   { 
       n[ i ] = i + 100; /* 設定元素 i 為 i + 100 */ 
    } 
    /* 輸出陣列中每個元素的值 */ 
   for (j = 0; j < 10; j++ )
   {
        printf("Element[%d] = %d\n", j, n[j] );   
    }

    return 0;
 }

當上面的程式碼被編譯和執行時,它會產生下列結果:

Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109

C 中陣列詳解

在 C 中,陣列是非常重要的,我們需要了解更多有關陣列的細節。下面列出了 C 程式設計師必須清楚的一些與陣列相關的重要概念:

一、多維陣列:C 支援多維陣列。多維陣列最簡單的形式是二維陣列。

C 語言支援多維陣列。多維陣列宣告的一般形式如下:

type name[size1][size2]...[sizeN];

例如,下面的宣告建立了一個三維 5 . 10 . 4 整型陣列:

int threedim[5][10][4];

二維陣列

多維陣列最簡單的形式是二維陣列。一個二維陣列,在本質上,是一個一維陣列的列表。宣告一個 x 行 y 列的二維整型陣列,形式如下:

type arrayName [ x ][ y ];

其中,type 可以是任意有效的 C 資料型別,arrayName 是一個有效的 C 識別符號。一個二維陣列可以被認為是一個帶有 x 行和 y 列的表格。下面是一個二維陣列,包含 3 行和 4 列:

int x[3][4];

因此,陣列中的每個元素是使用形式為 a[ i , j ] 的元素名稱來標識的,其中 a 是陣列名稱,i 和 j 是唯一標識 a 中每個元素的下標。

初始化二維陣列

多維陣列可以通過在括號內為每行指定值來進行初始化。下面是一個帶有 3 行 4 列的陣列。

int a[3][4] = {  
 {0, 1, 2, 3} ,   /*  初始化索引號為 0 的行 */
 {4, 5, 6, 7} ,   /*  初始化索引號為 1 的行 */
 {8, 9, 10, 11}   /*  初始化索引號為 2 的行 */
};

內部巢狀的括號是可選的,下面的初始化與上面是等同的:

int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

訪問二維陣列元素

二維陣列中的元素是通過使用下標(即陣列的行索引和列索引)來訪問的。例如:

int val = a[2][3];

上面的語句將獲取陣列中第 3 行第 4 個元素。您可以通過上面的示意圖來進行驗證。讓我們來看看下面的程式,我們將使用巢狀迴圈來處理二維陣列:

例項

#include <stdio.h>
int main () 
{
   /* 一個帶有 5 行 2 列的陣列 */ 
   int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};   
   int i, j;     

   /* 輸出陣列中每個元素的值 */
   for ( i = 0; i < 5; i++ )
   {
       for ( j = 0; j < 2; j++ ) 
       {
           printf("a[%d][%d] = %d\n", i,j, a[i][j] );       
        } 
    } 
    return 0; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

a[0][0] = 0
a[0][1] = 0
a[1][0] = 1
a[1][1] = 2
a[2][0] = 2
a[2][1] = 4
a[3][0] = 3
a[3][1] = 6
a[4][0] = 4
a[4][1] = 8

如上所述,您可以建立任意維度的陣列,但是一般情況下,我們建立的陣列是一維陣列和二維陣列。

二、傳遞陣列給函式:

您可以通過指定不帶索引的陣列名稱來給函式傳遞一個指向陣列的指標。

如果您想要在函式中傳遞一個一維陣列作為引數,您必須以下面三種方式來宣告函式形式引數,這三種宣告方式的結果是一樣的,因為每種方式都會告訴編譯器將要接收一個整型指標。同樣地,您也可以傳遞一個多維陣列作為形式引數。

方式 1

形式引數是一個指標(您可以在下一章中學習到有關指標的知識):

void myFunction(int *param)
 {
 .
 . 
 .
 }

方式 2

形式引數是一個已定義大小的陣列:

void myFunction(int param[10])
{ 
. 
. 
. 
}

方式 3

形式引數是一個未定義大小的陣列:

void myFunction(int param[]) 
{
.
.
.
}

現在,讓我們來看下面這個函式,它把陣列作為引數,同時還傳遞了另一個引數,根據所傳的引數,會返回陣列中各元素的平均值:

例項

double getAverage(int arr[], int size) 
{
   int i;   
   double avg;   
   double sum;
    
   for (i = 0; i < size; ++i) 
   { 
      sum += arr[i];   
    } 
   avg = sum / size;  
  
   return avg; 
}

現在,讓我們呼叫上面的函式,如下所示:

例項

#include <stdio.h> 

/* 函式宣告 */
double getAverage(int arr[], int size);  
int main () 
{ 
    /* 帶有 5 個元素的整型陣列 */ 
    int balance[5] = {1000, 2, 3, 17, 50};    
    double avg;    
  
    /* 傳遞一個指向陣列的指標作為引數 */ 
    avg = getAverage( balance, 5 ) ; 
     
    /* 輸出返回值 */
    printf( "平均值是: %f ", avg );    
    
    return 0;
 } 

double getAverage(int arr[], int size) 
{
   int i;   
   double avg;   
   double sum=0;    

   for (i = 0; i < size; ++i)
   { 
      sum += arr[i];  
   } 
      avg = sum / size;    
   return avg; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

平均值是: 214.400000

您可以看到,就函式而言,陣列的長度是無關緊要的,因為 C 不會對形式引數執行邊界檢查。

三、從函式返回陣列:C 允許從函式返回陣列。

C 語言不允許返回一個完整的陣列作為函式的引數。但是,您可以通過指定不帶索引的陣列名來返回一個指向陣列的指標。我們將在下一章中講解有關指標的知識,您可以先跳過本章,等了解了 C 指標的概念之後,再來學習本章的內容。

如果您想要從函式返回一個一維陣列,您必須宣告一個返回指標的函式,如下:

int * myFunction()
{
.
.
. 
}

另外,C 不支援在函式外返回區域性變數的地址,除非定義區域性變數為 static 變數。

現在,讓我們來看下面的函式,它會生成 10 個隨機數,並使用陣列來返回它們,具體如下:

例項

#include <stdio.h>
#include <stdlib.h> 
#include <time.h> 

/* 要生成和返回隨機數的函式 */
int * getRandom( )
{ 
   static int r[10];  
   int i;  
   
   /* 設定種子 */
   srand( (unsigned)time( NULL ) );   
   for ( i = 0; i < 10; ++i) 
   { 
      r[i] = rand();      
      printf( "r[%d] = %d\n", i, r[i]);    
    } 

    return r; 
} 

/* 要呼叫上面定義函式的主函式 */
int main ()
{
   /* 一個指向整數的指標 */
   int *p;    
   int i; 
     
   p = getRandom();    
   for ( i = 0; i < 10; i++ )
   { 
        printf( "*(p + %d) : %d\n", i, *(p + i));   
   } 

   return 0; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

r[0] = 313959809
r[1] = 1759055877
r[2] = 1113101911
r[3] = 2133832223
r[4] = 2073354073
r[5] = 167288147
r[6] = 1827471542
r[7] = 834791014
r[8] = 1901409888
r[9] = 1990469526
*(p + 0) : 313959809
*(p + 1) : 1759055877
*(p + 2) : 1113101911
*(p + 3) : 2133832223
*(p + 4) : 2073354073
*(p + 5) : 167288147
*(p + 6) : 1827471542
*(p + 7) : 834791014
*(p + 8) : 1901409888
*(p + 9) : 1990469526

四、指向陣列的指標:您可以通過指定不帶索引的陣列名稱來生成一個指向陣列中第一個元素的指標。

您可以先跳過本章,等了解了 C 指標的概念之後,再來學習本章的內容。

如果您對 C 語言中指標的概念有所瞭解,那麼就可以開始本章的學習。陣列名是一個指向陣列中第一個元素的常量指標。因此,在下面的宣告中:

double balance[50];

balance 是一個指向 &balance[0] 的指標,即陣列 balance 的第一個元素的地址。因此,下面的程式片段把 p 賦值為 balance 的第一個元素的地址:

double *p;
double balance[10];

p = balance;

使用陣列名作為常量指標是合法的,反之亦然。因此,*(balance + 4) 是一種訪問 balance[4] 資料的合法方式。

一旦您把第一個元素的地址儲存在 p 中,您就可以使用 *p、*(p+1)、*(p+2) 等來訪問陣列元素。下面的例項演示了上面討論到的這些概念:

例項

#include <stdio.h>
int main () 
{ 
    /* 帶有 5 個元素的整型陣列 */ 
    double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};   
    double *p;  
    int i;     

    p = balance;      

    /* 輸出陣列中每個元素的值 */ 
    printf( "使用指標的陣列值\n");   
    for ( i = 0; i < 5; i++ ) 
    { 
         printf("*(p + %d) : %f\n",  i, *(p + i) );    
     } 

    printf( "使用 balance 作為地址的陣列值\n");   
    for ( i = 0; i < 5; i++ )
    { 
        printf("*(balance + %d) : %f\n",  i, *(balance + i) );   
    } 

    return 0; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

使用指標的陣列值
*(p + 0) : 1000.000000
*(p + 1) : 2.000000
*(p + 2) : 3.400000
*(p + 3) : 17.000000
*(p + 4) : 50.000000
使用 balance 作為地址的陣列值
*(balance + 0) : 1000.000000
*(balance + 1) : 2.000000
*(balance + 2) : 3.400000
*(balance + 3) : 17.000000
*(balance + 4) : 50.000000

在上面的例項中,p 是一個指向 double 型的指標,這意味著它可以儲存一個 double 型別的變數。一旦我們有了 p 中的地址,*p 將給出儲存在 p 中相應地址的值,正如上面例項中所演示的。

搜尋

複製