您好,登錄后才能下訂單哦!
一:一維數(shù)組 int a[5];
a:就是數(shù)組名。a做左值時表示整個數(shù)組的所有空間(10×4=40字節(jié)),又因為C語言規(guī)定數(shù)組操作時要獨立單個操作,不能整體操作數(shù)組,所以a不能做左值;a做右值表示數(shù)組首元素(數(shù)組的第0個元素,也就是a[0])的首地址(首地址就是起始地址,就是4個字節(jié)中最開始第一個字節(jié)的地址)。a做右值等同于&a[0];
a[0]:表示數(shù)組的首元素,也就是數(shù)組的第0個元素。做左值時表示數(shù)組第0個元素對應的內(nèi)存空間(連續(xù)4字節(jié));做右值時表示數(shù)組第0個元素的值(也就是數(shù)組第0個元素對應的內(nèi)存空間中存儲的那個數(shù))
&a:就是數(shù)組名a取地址,字面意思來看就應該是數(shù)組的地址。&a不能做左值(&a實質(zhì)是一個常量,不是變量因此不能賦值,所以自然不能做左值。);&a做右值時表示整個數(shù)組的首地址。
&a[0]:字面意思就是數(shù)組第0個元素的首地址(搞清楚[]和&的優(yōu)先級,[]的優(yōu)先級要高于&,所以a先和[]結(jié)合再取地址)。做左值時表示數(shù)組首元素對應的內(nèi)存空間,做右值時表示數(shù)組首元素的值(也就是數(shù)組首元素對應的內(nèi)存空間中存儲的那個數(shù)值)。做右值時&a[0]等同于a。
總結(jié):
1:&a和a做右值時的區(qū)別:&a是整個數(shù)組的首地址,而a是數(shù)組首元素的首地址。
這兩個在數(shù)字上是相等的,但是意義不相同。意義不相同會導致他們在參與運算的時候有不同的表現(xiàn)。
2:a和&a[0]做右值時意義和數(shù)值完全相同,完全可以互相替代。
3:&a是常量,不能做左值。
4:a做左值代表整個數(shù)組所有空間,所以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; }
/******運行結(jié)果
p1 = 0xbfbcda54
p2 = 0xbfbcda5c
p1 = 0xbfbcd99c
(p1+1) = 0xbfbcd9a0
p2 = 0xbfbcd99c
(p2+1) = 0xbfbcd9b0
*******************/
/*********分析:*****
1:p1 p2定義的時候被沒有進行初始化,所以屬于野指針。
2:p1 = a ,a數(shù)組名做右值表示首元素首地址,而數(shù)組a是int類型,所以首元素首地址中存放的也是int類型的數(shù)所以類型匹配。也就是說p1是指向int類型的數(shù)的指針
3:p1+1=p1+4 p1指向的數(shù)組的首元素首地址,相當于p1指向了數(shù)組內(nèi)部,所以p1+1其實就是p1+sizeof(數(shù)組類型)
4:p2 = &a p2的定義是int(*p2)[5]可以理解為是一個指向int [5]類型的指針,所以p2是一個指向數(shù)組的指針。
而&a是數(shù)組名取地址,表示的就是數(shù)組的地址(表示這個地址存放的就是一個數(shù)組類型),所以p2和&a的類型匹配。
5:p2 + 1 = p2 + 20 因為p2在定義的時候就被定義為指向一個int [5]類型的地址,所以
p2+1 = p2+sizeof(int [5]);
6:指針+1實際上就是指針+siezof(指針類型),這個其實是在定義的時候就已經(jīng)確定了,因為在初始化的時候
指針指向的類型一定要和指針定義時候的類型匹配。
例如
char a[5];
int *p; //p是一個指向int類型的指針
p = a ;則類型就不匹配,編譯不通過。但是假如這樣可以成功初始化,那么指針再運算的時候它的指向就會出錯
比如開始p = a 的地址是0xb2000000,那么p+1 則為0xb2000004,而0xb2000004實際上是a[3]而不是a[1]這樣就
無法進行運算了,所以指針類型的匹配主要是為了能夠進行運算。
*******************************************/
二:二維數(shù)組
#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; }
/**********運行結(jié)果************
a = 0xbfeaebc8
&a[0] = 0xbfeaebc8
p2 = 0xbfeaebc8
p2 + 1 = 0xbfeaebdc
*(p2 + 1)+1 = 0xbfeaebe0
**************************/
/************分析*****
1:p2是int* [5] 類型是一個指向int [5]的指針,
2:數(shù)組名做右值表示的是數(shù)組的首元素首地址,二維數(shù)組的數(shù)組名表示的是第一維的地址,類型也是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]。
*/
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。