C語言之數組名的含義

一:一維數組 int a[5];
數組

a:就是數組名。a作左值時表示整個數組的全部空間(10×4=40字節),又由於C語言規定數組操做時要獨立單個操做,不能總體操做數組,因此a不能作左值;a作右值表示數組首元素(數組的第0個元素,也就是a[0])的首地址(首地址就是起始地址,就是4個字節中最開始第一個字節的地址)。a作右值等同於&a[0];ide

a[0]:表示數組的首元素,也就是數組的第0個元素。作左值時表示數組第0個元素對應的內存空間(連續4字節);作右值時表示數組第0個元素的值(也就是數組第0個元素對應的內存空間中存儲的那個數)spa

&a:就是數組名a取地址,字面意思來看就應該是數組的地址。&a不能作左值(&a實質是一個常量,不是變量所以不能賦值,因此天然不能作左值。);&a作右值時表示整個數組的首地址。指針

&a[0]:字面意思就是數組第0個元素的首地址(搞清楚[]和&的優先級,[]的優先級要高於&,因此a先和[]結合再取地址)。作左值時表示數組首元素對應的內存空間,作右值時表示數組首元素的值(也就是數組首元素對應的內存空間中存儲的那個數值)。作右值時&a[0]等同於a。內存

總結:it

    1:&a和a作右值時的區別:&a是整個數組的首地址,而a是數組首元素的首地址。io

這兩個在數字上是相等的,可是意義不相同。意義不相同會致使他們在參與運算的時候有不一樣的表現。編譯

    2:a和&a[0]作右值時意義和數值徹底相同,徹底能夠互相替代。class

    3:&a是常量,不能作左值。變量

    4:a作左值表明整個數組全部空間,因此a不能作左值。

#include<stdio.h>
int main (void)
{
    int a[5]={1,2,3,4,5};
    int *p1;
    int (*p2)[5];
    printf("p1 = %p \n",p1);
    printf("p2 = %p \n",p2);
    p1 = a;
    p2 = &a;
    printf("p1 = %p \n",p1);
    printf("(p1+1) = %p \n",(p1+1));
    printf("p2 = %p \n",p2);
    printf("(p2+1) = %p \n",(p2+1));
    return 0;
}

/******運行結果

p1 = 0xbfbcda54

p2 = 0xbfbcda5c

p1 = 0xbfbcd99c

(p1+1) = 0xbfbcd9a0

p2 = 0xbfbcd99c

(p2+1) = 0xbfbcd9b0

*******************/

/*********分析:*****

1:p1 p2定義的時候被沒有進行初始化,因此屬於野指針。

2:p1 = a ,a數組名作右值表示首元素首地址,而數組a是int類型,因此首元素首地址中存放的也是int類型的數因此類型匹配。也就是說p1是指向int類型的數的指針

3:p1+1=p1+4 p1指向的數組的首元素首地址,至關於p1指向了數組內部,因此p1+1其實就是p1+sizeof(數組類型)

4:p2 = &a p2的定義是int(*p2)[5]能夠理解爲是一個指向int [5]類型的指針,因此p2是一個指向數組的指針

而&a是數組名取地址,表示的就是數組的地址(表示這個地址存放的就是一個數組類型),因此p2和&a的類型匹配。

5:p2 + 1 = p2 + 20   由於p2在定義的時候就被定義爲指向一個int [5]類型的地址,因此

p2+1 = p2+sizeof(int [5]);

6:指針+1實際上就是指針+siezof(指針類型),這個實際上是在定義的時候就已經肯定了,由於在初始化的時候

指針指向的類型必定要和指針定義時候的類型匹配。

例如

char a[5];

int *p;        //p是一個指向int類型的指針

p = a ;則類型就不匹配,編譯不經過。可是假如這樣能夠成功初始化,那麼指針再運算的時候它的指向就會出錯

好比開始p = a 的地址是0xb2000000,那麼p+1 則爲0xb2000004,而0xb2000004其實是a[3]而不是a[1]這樣就

沒法進行運算了,因此指針類型的匹配主要是爲了可以進行運算。

*******************************************/


二:二維數組

#include<stdio.h>
int main(void)
{
    int a[2][5];
    int *p1;
    int (*p2)[5];
    int b = 5;
    //p1 = a;  //編譯報錯,類型不匹配
    p2 = a;  //編譯不報錯,類型匹配
    printf("a = %p \n",a);
    printf("&a[0] = %p \n",&a[0]);
    printf("p2 = %p \n",p2);
    printf("p2 + 1 = %p \n", p2+1);  //這裏進行p2 + 1,p2的值並不變
    printf("p2 = %p \n",p2);
    printf("*(p2 + 1)+1 = %p \n", *(p2 + 1)+1);
    return 0;
}

/**********運行結果************

a = 0xbfeaebc8

&a[0] = 0xbfeaebc8

p2 = 0xbfeaebc8

p2 + 1 = 0xbfeaebdc

*(p2 + 1)+1 = 0xbfeaebe0

**************************/

/************分析*****

1:p2是int* [5] 類型是一個指向int [5]的指針,

2:數組名作右值表示的是數組的首元素首地址,二維數組的數組名錶示的是第一維的地址,類型也是int [5]

因此和p2的類型匹配

3:p2+1 = p2 +20 緣由也就是p2指向的是int [][5],因此p2 + 1實際上+是指向了a[1][]也就是第一維的第二個元素。

4:*(p2 + 1)+1 =(p1+1)+4 ,指向是的a[1][1] 也就是說*(*(p+i)+j)等於a[i][j]。


*/

相關文章
相關標籤/搜索