c指針與數組

C primer plus P266,指針和多維數組,zippo1_yql20170628.c程序,主要代碼如下

int a=1;

long long b=2;

int zippo[4][2] = { {2,4}, {6,8}, {1,3}, {5, 7} };

int (*pz)[2];

printf(" zippo = %p, zippo + 1 = %p
",

zippo, zippo + 1);

printf("zippo[0] = %p, zippo[0] + 1 = %p
",

zippo[0], zippo[0] + 1);

printf(" *zippo = %p, *zippo + 1 = %p
",

*zippo, *zippo + 1);

printf("zippo[0][0] = %d
", zippo[0][0]);

printf(" *zippo[0] = %d
", *zippo[0]);

printf(" **zippo = %d
", **zippo);

printf(" zippo[2][1] = %d
", zippo[2][1]);

printf("*(*(zippo+2) + 1) = %d
", *(*(zippo+2) + 1));

printf("&zippo[0][0]=%p
",&zippo[0][0]);

printf("&zippo[0][1]=%p
",&zippo[0][1]);

printf("&zippo[1][0]=%p
",&zippo[1][0]);

printf(" &zippo = %p, &zippo + 1 = %p
",

&zippo, &zippo + 1);

printf("&zippo[0] = %p, &zippo[0] + 1 = %p
",

&zippo[0], &zippo[0] + 1);

printf("&zippo[1] = %p, &zippo[1] + 1 = %p
",

&zippo[1], &zippo[1] + 1);

printf("&a=%p, &a+1 = %p,&b=%p, &b+1=%p
",

&a,&a+1,&b,&b+1);

printf("&pz = %p, &pz + 1 = %p
",

&pz, &pz + 1);

運行結果如下:

zippo = 0061fee0, zippo + 1 = 0061fee8

zippo[0] = 0061fee0, zippo[0] + 1 = 0061fee4

*zippo = 0061fee0, *zippo + 1 = 0061fee4

zippo[0][0] = 2

*zippo[0] = 2

**zippo = 2

zippo[2][1] = 3

*(*(zippo+2) + 1) = 3

&zippo[0][0]=0061fee0

&zippo[0][1]=0061fee4

&zippo[1][0]=0061fee8

&zippo = 0061fee0, &zippo + 1 = 0061ff00

&zippo[0] = 0061fee0, &zippo[0] + 1 = 0061fee8

&zippo[1] = 0061fee8, &zippo[1] + 1 = 0061fef0

&a=0061ff0c, &a+1 = 0061ff10,&b=0061ff00, &b+1=0061ff08

&pz=0061fedc, &pz+1=0061fee0

對輸出進行解釋:

int a[100];&a 獲取數組自己本身的地址(的指針),a獲取數組第一個元素的地址(的指針),兩者的差別是"類型", 這兩個的類型不同, 前者是int(*)[100], 後者是int*。&a是數組的地址,a是數組第一個元素的地址,就好比有一排房屋,a第一個房間的地址,&a是這排房屋的起始地址,都是在同一個地方。

&zippo不是取zippo這個變數的地址,要消除前邊學習變數概念的錯誤類比影響,int a,則&a是內存中存儲變數a的地址。zippo是個數組,&zippo並不是說在內存中某個地方有個指針變數名字為zippo,指向zippo這個數組。zippo本身就是一種數據類型,&zippo就是取zippo這個數組的地址,而數組這種數據類型地址與普通變數一樣,都是存儲數據的這段內存的起始地址,既&zippo[0][0]。zippo占居4*8=32個位元組(本系統上int佔4位元組)。而新建一個指向數組的指針pz,則&pz的地址即指針變數的地址,而不再是&zippo[0][0]。

&zippo+1,zippo是一個佔32位元組內存的數組,&zippo值是&zippo[0][0],&zippo即取整個數組的地址,&zippo將產生一個指向一個數組的指針(類比int a;&a產生一個指向int的指針,&a+1結果是a地址加4位元組,b是long long類型,佔8位元組,&b+1是b地址加8位元組,最後一行輸出驗證此結論),故&zippo+1即&zippo加整個數組的長度,32個位元組,故&zippo + 1 = 0061ff10。指向zippo數組後一個地址。而zippo+1是增加8個位元組,2個int長度,因為zippo是指向數組首元素的指針,即指向子數組zipp[0],而&zippo是指向數組zippo。

因為數組定義,zippo的值是其首元素的地址,zippo的首元素為zippo[0],一個含2個元素的數組。zippo[0]數組的地址即&zippo[0][0]。

對於二維數組zippo,zippo=&zippo,zippo[0]=&zippo[0],zippo[1]=&zippo[1]

輸出第1、3行解釋,準確來說,*zippo不是取zippo的值,而是對zippo間接訪問,即zippo[0]子數組,因*zippo的值不是一個確切值而是一個數組,而zippo[0]數組的值即其首元素地址,是一個指向zippo[0][0]的指針,指向的對象大小為4位元組,故*zippo+1=zippo[0]+1,加了4位元組。而zippo指向8位元組的對象,zippo+1加了8位元組。


推薦閱讀:

百年積木品牌樂高的轉型之路,從標新立異回歸積木創新
這些科學家沒有時間機器,卻是離未來最近的人
你見過最酷的設計是什麼?
為什麼科技是樹?
霍金在科學界到底是什麼水平?

TAG:C編程語言 | 編程語言 | 編程 | 科技 | C指針 |