1. 程式人生 > >C之數組(二十五)

C之數組(二十五)

C語言 數組

在 C 語言中,我們不可避免的要接觸到數組。我們就來看看數組是什麽玩意,其實數組就是相同類型的變量的有序集合。下面這張圖更加形象的表示出數組的含義

技術分享圖片

數組在一片連續的內存空間中存儲元素,數組元素的個數是可以顯示或隱式指定的。比如: int a[5] = {1, 2}; int b[] = {1, 2};那麽問題來了,數組 a 中其余沒指定的三個數是多少呢?數組 b 到底包含了多少個元素呢?我們下來做個實驗看看是怎樣的,代碼如下

#include <stdio.h>

int main()
{
    int a[5] = {1, 2};
    int b[] = {1, 2};
    
    printf("a[2] = %d\n", a[2]);
    printf("a[3] = %d\n", a[3]);
    printf("a[4] = %d\n", a[4]);
    
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(b) = %d\n", sizeof(b));
    printf("count for a: %d\n", sizeof(a)/sizeof(int));
    printf("count for b: %d\n", sizeof(b)/sizeof(int));
    
    return 0;
}

編譯後結果如下

技術分享圖片

那麽我們看到編譯器默認指定數組後面沒指明的元素全都為0,而隱式指定的數組的大小就是它們所包含的元素的個數。

那麽接下來我們來看看數組地址與數組名的關系。數組名代表數組首元素的地址,數組的地址需要用取地址符 & 才能得到;數組首元素的地址與數組的地址值相同,但是數組首元素的地址與數組的地址是兩個不同的概念。我們來做個實驗,可以更加清晰的理解這段所說的概念,代碼如下

#include <stdio.h>

int main()
{
    int a[5] = { 0 };

    printf("a = %p\n", a);
    printf("&a = %p\n", &a);
    printf("&a[0] = %p\n", &a[0]);
    
    return 0;
}

編譯結果如下

技術分享圖片

我們看到三個地址相同。數組名代表首元素的首地址,在這塊,第一個和第三個就是相同的意義。但是第二個和他們所代表的意義不相同。舉個例子來說,舉行人大時,每個人代表他們各自的省份,在這時他一個人就可以代表他們的省份的意見。但你能說他和他的省份是一個概念嘛,顯然是不一樣的,只是在特定環境下僅僅相同罷了。

接下來我們介紹個有趣的,數組名其實可以看做一個常量指針。數組名“指向”的是內存中數組首元素的起始位置,但數組名不包含數組的長度信息;在表達式中數組名只能作為右值使用,只有在以下兩種場合中數組名不能看做是常量指針:a> 數組名作為 sizeof 操作符的參數;b> 數組名作為 & 運算符的參數

。下來我們再做個示例代碼分析下,代碼如下

#include <stdio.h>

int main()
{
    int a[5] = {0};
    int b[2];
    int* p = NULL;
    
    p = a;
    
    printf("a = %p\n", a);
    printf("p = %p\n", p);
    printf("&p = %p\n", &p);
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(p) = %d\n", sizeof(p));
   
    printf("\n");

    p = b;
    
    printf("b = %p\n", b);
    printf("p = %p\n", p);
    printf("&p = %p\n", &p);
    printf("sizeof(b) = %d\n", sizeof(b));
    printf("sizeof(p) = %d\n", sizeof(p));
    
    b = a;
  
    return 0;
}

我們在第9行將數組名 a 賦值給指針 p,這是沒錯的,因為數組名可以看做是數組首元素的首地址。我們接著通過打印 a 和 p 的地址應該是相同的,但是指針也是變量,它自身也有地址,所以第13行打印出來的應該和前兩個地址不相同。接下來打印數組 a 的大小應該是20,指針 p 的大小應該是 4。顯示指定的數組 a 和 隱式指定的數組 b 的情況應該是相同的。但第27行是兩個數組名進行賦值操作,這肯定會出錯。從另一個角度看,我們前面說了數組名可以看做是一個常量指針,那麽我們將常量指針賦值給另一個常量指針肯定會出錯啊。接下來我們看看編譯結果

技術分享圖片

編譯報錯,我們註釋掉第27行,再次編譯

技術分享圖片

我們看到結果和我們分析的是一致的。通過對數組的學習,總結如下:1、數組是一片連續的內存空間;2、數組的地址和數組首元素的地址意義不同;3、數組名在大多數情況下被當成常量指針處理,單數數組名並不是指針,不能將其等同於指針。


歡迎大家一起來學習 C 語言,可以加我QQ:243343083

C之數組(二十五)