數組認知——整型數組

一維數組

1.通過鍵盤給數組的 每個元素賦值
通過以下的程序來講解數組名的一些個人理解

    int a[3];
    int i;
    int *p = a; //p == a

    for(i = 0; i < 3; i++)
    {
        scanf("%d",&a[i]);
        scanf("%d",a + i);//scanf("%d",&a[0]); a = a + 1;
      //scanf("%d",a++);//error
        scanf("%d",p++);
        scanf("%d",p + i);
        scanf("%d",&p[i]);
    }

這裏首先我先給出大家一個等式[ ] == * (),例如a[ i ] == * (a + i);第一個scanf我相信大家都是知道的,也是經常用的。第二個scanf理解的話可以通過我剛剛給大家說的那個等式來理解,&a[ i ] == &(* (a + i)),我們知道&與*互爲逆運算,所以互相抵消即爲a+i。也可以換個角度來理解,我們知道數組名是一個指針常量,表示的數組首元素的地址,a就是表示首元素的地址,即a = &a[0],同樣的a+i就表示的是第i+1個元素的地址(我是將a[0]表示成第一個元素的,所以a[i]我認爲是第i個元素),即a+i == &a[i]。
第三個scanf爲什麼就是錯誤的呢?我在上面也提到數組名是一個指針常量,而常量被保存在內存數據區的or段,我們知道這部分的數據只能讀,不能被修改,因此對數組名做自加操作是錯誤的。
第四個到第六個scanf,我們定義了一個指針變量p,並將a賦值給p,通過這個賦值語句我們得到p == a,因此 前幾個scanf出現a的地方,我們都可以換成p。此外,p++也可以被使用了,想想爲什麼?因爲p此時是一個局部的指針變量,保存在內存的棧空間,我們知道棧空間的數據是可以被修改的,所以我們寫p++是沒有問題的。
2.數組的地址
同樣的我們通過一個具體的程序來說明一些我的理解。

int a[3]={0};
printf("a = %p\n",a); //數組名:指針常量,數組首元素的地址
printf("&a = %p\n",&a); //&a代表數組的地址
printf("a+1=%p\n",a+1); //4個字節
printf("&a+1=%p\n",&a+1); //加數組長度:12個字節

雖然第一個和第二個打印的結果一樣,但兩者表示的含義卻不同,下面的兩個打印結果就表明了他倆的不同:步長不同。這裏數組是將首個元素的地址作爲整個數組的地址。
總結下:
&a:對數組名取地址等於數組的地址;
*(&a) = a:對一維數組的地址取值等於一維數組的首元素的地址。
請大家記住這兩句話,可以幫助大家理解下面的二維,三維數組。

二維數組

同樣的通過一個程序來談談我的理解。

int main()
{
    int a[2][2] = {1,2,3,4};

    int i;
    int j;

    for(i  = 0; i < 2; i++)
    {
        for(j = 0; j <  2; j++)
        {
        //scanf("%d",&a[i][j]);//[] == *()
        scanf("%d",(*(a + i) + j));
        }
    }

    for(i = 0; i < 2; i++)
    {
        for(j = 0; j < 2; j++)
        {
        printf("a[%d][%d] = %d\n",i,j,*(*(a + i) + j));
        }
    }

    return 0;
}

這是一個簡單的二維數組的通過鍵盤對數組元素賦值並將其輸出的程序。在理解這個程序之前談談我對多維數組名的一些個人理解,我是從數組的“單位”來理解的。
一維數組的單位是元素,因此數組名錶示的一維數組首元素的地址;
二維數組的單位是一維數組,因此二維數組名錶示的是:首個一維數組的地址;
三維數組的單位是二維數組,因此三維數組名錶示的是:首個二維數組的地址;
四維,五維等等更多維數的數組名都可以這樣理解。理解了數組名的含義再來理解 * ( * (a+i)+j)就相對簡單一些。不急,我們一層一層來理解:
a+i:a是二維數組名,表示的是首個一維數組的地址,那麼a+i 自然就表示的是第i+1個一維數組的地址;
* (a+i):在講一維數組的時候,我說過對一維數組的地址取值等於一維數組首元素的地址。因此,*(a+i)就表示的是:第i+1個一維數組的首元素的地址;
*(a + i) + j:第i+1個一維數組的第j+1個元素的地址;
* ( * (a + i) + j ):第i+1個一維數組的第j+1個元素的值。
總結下:
int a[3];
int aa[3];

&a:對一維數組名取地址等於一維數組的地址;
*(&a) = a:對一維數組的地址取值等於一維數組首元素的地址;
a:一維數組名,是個指針常量,表示的是一維數組首元素的地址;
aa:首個一維數組的地址;
*aa:對二維數組名取值,首個一維數組的首元素的地址;
**aa:對二維數組名取兩次值,首個一維數組的首個元素的值;
&aa:對二維數組名取地址,等於二維數組的地址;
*(&aa)==aa:對二維數組的地址取值等於二維數組首個一維數組的地址;
**(&aa) == *aa:對二維數組的地址取兩次值等於二維數組首個一維數組的首元素的地址;

三維數組

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

    int i;
    int j;
    int k;

    for(i = 0; i < 3; i++)
    {
        for(j = 0; j < 2; j++)
        {
            for(k = 0; k < 2; k++)
            {
                printf("a[%d][%d][%d] = %d\n",i,j,k,*(*(*(a + i) + j) + k));
            }
        }
    }

    return 0;
}

怎麼理解一個三維數組?
首先從三維數組的定義開始理解。int a[3][2][2],我們知道三維數組的單位是二維數組,那麼數組定義中第一個參數表示的就是第幾個二維數組,第二個參數表示的這個二維數組中第幾個一維數組,第三個參數表示的是一維數組中第幾個元素。
如a[1][1][1] 它表示的數是幾?答案是8。請訪客結合上述的解釋嘗試着理解。理解不了可以在評論中提出來。
那麼上述程序中的* (* (*(a+i)+j)+k)又該如何理解呢?
同樣的一層一層的理解:
a+i:第i+1個二維數組的地址;
*(a+i):第i+1個二維數組的首個一維數組的地址;
*(a+i)+j:第i+1個二維數組的第j+1個一維數組的地址;
* (*(a+i)+j):第i+1個二維數組的第j+1個一維數組的首元素的地址;
* (*(a+i)+j)+k:第i+1個二維數組的第j+1個一維數組的第k個元素的地址;
* (* (*(a+i)+j)+k):第i+1個二維數組的第j+1個一維數組的第k個元素的值;

至此,一維,二維,三維數組裏面一些比較難以理解的概念,我都詳細的解釋了一遍,希望對你們數組的學習有一定的幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章