1.1 指標陣列和陣列指標的記憶體布局
指標陣列:乙個陣列,陣列元素都是指標,陣列佔多少位元組由陣列本身決定。它是:儲存指標的陣列的簡稱。
陣列指標:乙個指標,它指向乙個陣列。在 32 位系統下,指標永遠佔 4 個位元組,至於它指向的陣列佔多少位元組,我們並不知道。它是:指向陣列的指標的簡稱。
/*指標陣列*/
int*p1[10]
;/*陣列指標*/
int(
*p2)[10
];
解釋:運算子 [ ] 的優先順序高於 * 。對於 p1 ,首先和 [ ] 結合,構成乙個陣列定義,陣列名為 p1 ,int * 修飾的是陣列裡面的內容,即為陣列的每個元素。這是乙個包含 10 個指向 int 型別資料的指標,即指標陣列。
對於 p2 ,() 運算子的優先順序高於 [ ] 。* 號和 p2 構成乙個指標定義,指標變數名為 p2 ,int 修飾的是陣列的內容,即陣列的每個元素。注意,陣列在這裡並沒有名字,是個匿名陣列。p2 是乙個指標,指向乙個包含 10 個 int 型別資料的陣列,即陣列指標。可參考下圖加深理解:
#include
intmain
(void);
int*parr[4]
;/*陣列,儲存4個int型別指標變數*/
int(
*ptr)[4
];/*指標,指向含4個元素的一維陣列*/
/*指標陣列測試*/
for(
int i =
0; i <
4; i++
)printf
("指標陣列測試:%d \r\n"
,*parr[2]
);/*陣列指標測試*/
ptr =
&arr;
/*指標變數賦值*/
printf
("陣列指標測試:%d \r\n",(
*ptr)[2
]);getchar()
;return0;
}
測試結果:
我們可以這樣理解:指標陣列是存放一堆指標變數的,使用的時候需要依次去賦值(單獨給每個指標變數賦值),而陣列指標是乙個指標,只需一次初始化即可。陣列指標在記憶體中只佔乙個指標的儲存空間,指標陣列是多個指標變數,以陣列的形式存放在記憶體中,占有多個指標的儲存空間。
1.2 a 與 &a 的區別
void
test
(void);
char
(*p1)[5
]=&a;char
(*p2)[5
]= a;
printf
("陣列指標測試:%c \r\n",(
*p1)[2
]);printf
("陣列指標測試:%c \r\n",(
*p1+1)
[2])
;printf
("陣列指標測試:%c \r\n",(
*p2)[2
]);printf
("陣列指標測試:%c \r\n",(
*p2 +1)
[2])
;}
對於 char(*p2)[5] = a; 編譯時提示資訊如下:
因為在 c 語言中,賦值號(=)兩邊的資料型別必須是相同的,如果不同,就需要強制轉換,&a 是整個陣列的首位址,與左邊指向整個陣列的指標是匹配的,而 a 僅是陣列元素首個元素的位址,即指向單個字元的指標,與左邊指向整個陣列的指標不匹配,進而編譯器提示警告。但是因為 &a 與 a 的數值是一樣的,只是表示的意義不同,所以程式能夠正確執行。但是最好不要這樣使用,盡量規範化。
結構體:
struct test
*p;
根據記憶體對齊原則,我們知道這個結構體大小為:20 位元組。
假設:p 的值為 0x100000;
則:
/*偏移整個結構體的大小*/
(1)p +
0x01
=0x100000
+sizeof
(test)
*0x01
=0x100014
/*p強制轉換成了無符號長整型,數值一旦被轉換,其型別就變了*/
(2)(
unsigned
long
)p +
0x01
=0x100001
/*p強制轉換為無符號整型指標*/
(3)(
unsigned
int*
)p +
0x01
=0x100000
+sizeof
(int)*
0x01
=0x100004
測試程式:
void
ptest
(void);
/*(&a + 1)偏移陣列a長度:4 *sizeof(int)的長度*/
int*ptr1 =
(int*)
(&a +1)
;/*a + 1為陣列a中的第二個元素(即2)*/
int*ptr2 =
(int*)
((int)a +1)
;printf
("ptr1[-1] ---*ptr2 is %x %x \r\n "
, ptr1[-1
],*ptr2)
;}
測試結果:
ptr1 :將 &a + 1 的值強制轉換成 int * 型別,賦值給 int * 型別的變數 ptr1 ,則 ptr1 是指到下乙個陣列 a 的 int 型別的資料,所以 ptr1[-1] 等價於 *(ptr1 - 1),即 ptr1 從新指的位址往後退了 4 byte。故其值為:0x04。
ptr2 :(int)a + 1的值是元素 a[0] 第二個位元組的位址,然後把這個位址強制轉換成 int * 賦值給 ptr2 ,即 *ptr2 的值是元素 a[0] 的第二個位元組開始連續 4 個 byte 的內容。
記憶體布局如下圖:
具體這 4 個位元組裡面儲存的具體數值是多少,就跟儲存的大小端有關係。如上圖所示:因為輸出的結果為:02 00 00 00,可知是小端;如果是大端,則應該輸出:00 01 00 00。
C語言再學習16 指標 陣列(一)
前言 p 乙個 int 型別的模子在記憶體上得到 4 個位元組的空間,然後把這個 4 個位元組大小的空間命名為 p,同時限定這 4 個位元組的空間裡面只能儲存某個記憶體位址,即使存入其他任何資料,都將被當作位址處理,而且這個記憶體位址開始的連續 4 個位元組上只能儲存某個 int 型別的資料。理解 ...
C語言再學習20 指標 陣列(五)
1.1 二維陣列 除了函式,陣列裡可以存放任何資料。char a 3 4 a 1 2 如下圖 實際上,記憶體是線性的,類似於尺子,最小單位為 byte 比如 記憶體位址 0x0000ff00 是指記憶體零位址開始偏移 0x0000ff00 個 byte。實際上二維陣列記憶體的存放如下圖 註解 1 a...
C語言基礎(四)指標 陣列
2016.7.25 任何型別的一維 二維 三維指標占用空間大小相同4個位元組 32位作業系統 8個位元組 64位 指標與陣列 陣列 表示一段連續的記憶體空間,用來儲存多個相同型別的值。1.陣列名的值是陣列首元素的位址 即陣列名是指向陣列首元素的指標 int array 5 printf array ...