零基礎學C語言——數組

這是一個C語言系列文章,如果是初學者的話,建議先行閱讀之前的文章。筆者也會按照章節順序發佈。

我們討論過函數,其中涉及到了一些數組和指針,本篇詳細說明數組。

數組定義

數組是一種集合結構,與數學種談到的集合類似,用來存放同類型數據。在C語言中,數組是定長的,即數組有其最大長度限制,超過限制的訪問會導致程序崩潰或異常行為。

定義一個數組的一般形式如下:

數據類型 數組名[數組長度];

其中,數據類型不僅包含了之前文章中介紹的幾種 ,還包含後續文章將會介紹的自定義類型、結構體類型等,數組長度為整數,數組名的命名規則與 的命名規則一致。

下面看幾種數組定義的例子:

int i_array[100]; //定義整型數組,名為i_array,數組長度為100,即可以容納100個整數char c_array[100]; //定義字符型數組,名為c_array,數組長度為100,即可容納100個字符 

數組的聲明與 和 的聲明作用是一樣的,是為了告訴編譯器,這個數組在本文件或者其他源文件中有定義,避免當前文件編譯因找不到定義而報錯。

數據類型 數組名[數組長度];

看似與數組定義一樣,是的,的確可以寫成一樣的,但數組長度可以省略:

int i_array[100];和int i_array[];

這裡需要注意,如果省寫數組長度,那麼在使用sizeof計算i_array長度時編譯器會報錯

數組初始化

在定義變量時,我們可以定義並賦初值,數組亦然,但是數組有幾種定義並初始化的寫法:

1.定義並給出全部初始值

int a[3] = {1, 2, 3};或int a[] = {1, 2, 3}; 

即初值用{}包裹,且每個元素間用逗號隔開。

對於同時給定初始值的定義,我們是可以省略數組長度的,因為編譯器會根據初始值內容判斷數組長度。

2.定義並給出部分初始值

int a[3] = {1, 2};

此時數組長度不可省寫,否則將被認為數組只有兩個元素。數組a的前兩個元素分別是1和2,第三個元素數值未知。

3.定義字符數組

字符數組的定義賦初值寫法與其他基礎類型的定義有所不同

char s[6] = "hello";char s[] = "hello";

上面這兩者是等價的,即定義了一個數組長度為6的字符數組。

細心的讀者可能會發現,hello只有五個字符,為什麼會是6個元素長度呢?

這是因為雙引號內的字符串(也是字符數組)都隱含的在最後包含了一個'\\0'字符來表示字符串結束。因此這類字符串的長度都是雙引號內字符個數總和加1。如果使用sizeof運算符計算s的長度,返回的數值就是6。

對於字符型數組(不管是char還是unsigned char)有一種特殊的初始化寫法——定義並將數組元素值都清零

char s[100] = {0};unsigned char us[100] = {0};

此時,數組長度不可省略,且這裡不只是初始化數組的第一個元素,而是將數組全部元素值設置成0。

這樣的寫法僅限於清零,如果換用別的數值,則會變成部分初始化。

數組元素

其實,數組本質上也是一片連續的內存空間,與我們在變量一篇中停車場例子很像。

零基礎學C語言——數組

事實上,數組的每一個元素單元就是一個變量

我們再次以停車位使用為例來看下數組元素是如何被使用的。這裡,我們假設舉例鏡頭最近的停車位位置記為0,並向遠處依次加一,且假定這一排有10個停車位。

那麼這樣一排停車位轉換到C語言上,可以如下定義:

int parking_area[10];

之所以定義為整型,是因為每一種車型都可以用一個獨特的整數來代替其名字,即車名與整數做了一個映射關係。

此時,一輛寶馬駛入第1個車位,我們假定寶馬對應整數為1000,那麼代碼可以寫成:

parking_area[0] = 1000; //上面提到過第一個車位的位置為0

這裡,我們用到了 。

本篇文章中,數組元素的訪問都是通過下標來進行的,關於指針訪問元素留待後續指針文章中討論。

數組的下標個數與數組長度相等,且下標數值從0開始依次加1,即上例中的下標為0~9。

這時又來了一輛奔馳(對應整數記為1001),停入了第二個車位,那麼代碼如下:

parking_area[1] = 1001;

如果,寶馬開走了(假設無車停放記為0),那麼代碼可以寫成:

parking_area[0] = 0;

一個可編譯運行的例子

#include int main(void){    char a[10] = {0};    int i;    for (i = 0; i < sizeof(a); ++i) {        printf("%d\\n", a[i]);    }    return 0;}

大家可以 一下例子,這裡是將定義數組a並將其所有元素全部清0。然後使用數組下標配合循環語句完成數組元素的遍歷訪問。關於循環的內容,將在後續文章中給出。

多維數組

上面討論的內容涉及到的例子都是一維數組——即每個數組元素都是一個數值而非數組

下面,我們就來介紹複雜一些數組形式,我們以二維數組為例進行演示。

int a[2][3];

這裡我們就定義了一個二維數組a,它類似一個2行3列的表格或者矩陣。

對於這個二維數組,定義同時初始化可以使用如下方式:

int a[2][3] = {{1, 2, 3}, {4, 5, 6}};或int a[][3] = {{1, 2, 3}, {4, 5, 6}};

可以看到,其最外層數組包含了兩個元素,這兩個元素又分別是兩個相同長度的一維數組。

同時,在定義同時初始化的情況下,第一維的數組長度可以省略,編譯器將以初值中的元素個數自動填充。

int a[2][3];或int a[][3];

即可以省寫一維數組長度部分。

對於

二維數組的元素訪問,可以用如下形式:

a[0][1] = 10; //第1行第2列元素賦值10a[1][2] = 99; //第2行第3列元素賦值99

對於更高維度的數組,在日常生產環境下是不多見的,其一般形式如下:

數據類型 數組名[m][n]...;或數據類型 數組名[m][n]... = {{{...},...},...};

特徵就是:

  1. 是幾維數組,數組名後的方括號就有幾個
  2. 是幾維數組,初值中就要嵌套幾層{}數組
  3. 是幾維數組,訪問其元素時數組下標運算符([])就要有幾個
  4. 對於二維及其以上維度的數組,在定義同時初始化時,只有第一維度的數組長度可以省略
  5. 對於二維及其以上維度的數組,聲明時只有第一維度的數組長度可以省略


喜歡的讀者可以關注碼哥,也可以在下方留言評論,如果有不清楚的地方也可以私信碼哥,我會第一時間回覆。


分享到:


相關文章: