2012-09-27 182 views
0

我所遇到出外代碼:指針運算和地址

#include <stdio.h> 

int main(void) 
{ 
int a[5] = { 1, 2, 3, 4, 5}; 
int *ptr = (int*)(&a + 1); 
int *ptr2 = (int*) &a; 
ptr2 +=1 ; 
printf("%d %d %d \n", *(a + 1),*(ptr - 1) ,*ptr2); 
return 0; 
} 

指針算法確實對我來說,除了這行:

int *ptr = (int*)(&a + 1); 

它是不確定的行爲? 爲什麼我們得到5取消引用*(ptr - 1)

+2

'int a [5] = {1,2,3,4,5,6};'是一件很糟糕的事! – jn1kk

+0

@jsn我的壞!這只是問題中的5個元素,我在複製代碼之前做了一些奇怪的測試,我會改變它:)但問題依然存在。 – user1471

回答

2

試一試吧!

int a[5] = {1, 2, 3, 4, 5}; 
printf("%#x, %#x, %#x, %#x\n", a, &a, a+1, &a+1); 

0xbfa4038c, 0xbfa4038c, 0xbfa40390, 0xbfa403a0 

那麼,這告訴我們什麼?

0xbfa4038c == 0xbfa4038c這意味着a == &a。這是數組中第一個元素的地址或a[0]

我們知道,int的大小是4,並且知道*(a+1) == a[1](所述陣列中的第二個元素),並且這是通過證明:

0xbfa4038c + 0x4 = 0xbfa40390這意味着a + one int = address of the next element

因此如果我們看到&a+1 == 0xbfa403a0,這意味着我們將((0xa0-0x8c)/4) = 5個元素放入數組中。你知道a[5]是無效的,所以這意味着我們通過了數組的末尾。

所以如果你拿:

int *ptr = (int*)(&a + 1); //one passed last element in the array 
printf("%d",*(ptr - 1));//back up one, or last element in the array and deference 

這就是爲什麼你5

+0

+1 Got it!我仍然困惑了一下!a和&a給出地址,但給兩者加1會給我們不同的結果。 &a + 1增加了5個整數,因爲(a)的大小是5 * sizeof(int),但爲什麼不是+ 1? – user1471

+1

+1正在根據TYPE添加一個地址。嘗試[此鏈接](http://stackoverflow.com/questions/2989370/why-do-a1-and-a1-give-different-results-when-a-is-an-int-array)作爲答案你的問題(不是選定的答案,更多的選票更清晰) – Mike

3

a的大小是「5 int s」。所以&a + 1指的是第一個存儲單元過去的全都是a,因爲指針算術是以大小爲a爲單位完成的。

+1

int * ptr =(int *)(&a [0] + 1); //數組的第二個元素a –

+0

@RichardChambers是?不知道這是否意味着作爲一個反對論點......這是因爲'+ 1'適用於'&a [0]'的結果,並且其類型是普通的'int'。 – unwind

+0

@unwind我認爲他發佈這個作爲OP的修復。 – jn1kk

0

T類型的n個元素的數組,然後第一個元素的地址的類型是「指向T」; the address of the whole array具有類型'指向T類型的n個元素的數組的指針';

int *ptr = (int*)(&a + 1); //&a-> address whole array, size=20 bytes, 
     //ptr=&a+1: next element =adress of a +20 bytes. 
     //ptr - 1 = address of a +16 = address of last a's element = address of 5