天天看點

數組 基礎知識

數組的概念

數組是相同類型的變量的有序集合

int a[];
           

數組示意圖:數組包含5個int類型的資料

數組 基礎知識

數組的大小

數組在一片連續的記憶體空間中存儲元素。

數組元素的個數可以顯式或隐式指定。

數組 基礎知識

對于a,a[2]a[3]a[4]都為0;對于b,元素個數為2。

在定義數組并初始化的時候,給數組的前幾位初始化設定相應的值之後,如果沒有給後幾位初始化,系統将自動将後面的數組元素值初始化設定為0。

可以利用此來設定一個全0數組:int a[5] = {0};将第一個元素初始化為0,後面的自動初始化為0。

初始化比指派更高效,是以可以盡量采用初始化。

數組位址與數組名

數組名代表數組首元素的位址

數組的位址需要用取位址符&才能得到

數組首元素的位址值與數組的位址值相同,但是意義不同。

數組首元素的位址與數組的位址是兩個不同的概念

數組名的盲點:

數組名可以看做一個常量指針,不能作左值,數組名“指向”的是記憶體中數組首元素的起始位置,在表達式中數組名隻能作為右值使用。

隻有在下列場合中數組名不能看做常量指針:

  • 數組名作為sizeof操作符的參數,sizeof(a)表示a整個數組的位元組數。
  • 數組名作為&運算符的參數,表示整個數組的位址。

舉例,下面的錯誤做法:

數組 基礎知識

這樣的做法是錯誤的,常量指針數組名不能作左值。編譯直接報錯。

例程分析:

#include <stdio.h>

// another file
// char* p = "Hello World!";

extern char p[];

int main()
{
    printf("%s\n", p);

    return ;
}
           

定義為指針,聲明為數組。程式輸出的結果是亂碼,不是“Hello World!”。在其他檔案定義p指針時,編譯器為p配置設定一個4位元組的空間,存入了“Hello World!”字元串的首位址,在extern聲明的時候,聲明為數組,這樣編譯器把字元串的首位址轉變為數組的各個元素的内容,存放在數組p中。這樣列印出來的就是字元串的位址,而不是字元串的内容。

由上面的程式可以看出,雖然數組名可以看作一個常量指針,但是編譯器對指針和數組的處理是不同的。以printf(“%s\n”, p);這句話為例,當p為指針的時候,編譯器會尋址,列印出以p的内容為位址的記憶體中的内容。但是當p為數組的時候,隻會直接列印出p數組的内容。

由此可見,編譯器處理指針時,會做一次尋址,處理數組時,不會尋址。

把上面的程式改為:

printf("%s\n", (char *)(*((unsigned int *)p)));

這樣列印出來的就是“Hello World!”。

首先,将p數組轉變為一個指向unsigned int類型的指針,p數組有4位元組unsigned int類型也是4位元組,把p由指向數組首位址的指針,轉變為指向整個存放字元串位址的記憶體的指針。然後加星号*,得到p指針指向的記憶體的内容,也就是字元串的位址,再把該内容轉變為指向字元的指針類型,最後得到指向字元串的指針,列印出字元串的内容。

但是最好的修改方式,就是定義為指針,同樣也要聲明為指針。

數組小結

數組是一片連續的記憶體空間

數組的位址和數組首元素的位址意義不同

數組名在大多數情況下被當成常量指針處理

數組名其實并不是指針,在外部聲明時不能混淆