2012-10-13 93 views
0

我很困惑爲什麼這段代碼有效。我被告知指針是一個包含某物的地址的「膠囊」。所以swapnum函數應該期待這些「膠囊」之一,而不是int的實際地址。它是否創建了一個臨時指針並將其設置爲該地址?如果是這樣的話,那麼如果我通過引用如int * c = &a;swapnum (&c...傳遞指針,會發生什麼?爲什麼一個int的地址能夠被當作指向int的指針?

#include <stdio.h> 

void swapnum(int *i, int *j) { 
    int temp = *i; 
    *i = *j; 
    *j = temp; 
} 

int main(void) { 
    int a = 10; 
    int b = 20; 

    swapnum(&a, &b); 
    printf("A is %d and B is %d\n", a, b); 
    return 0; 
} 
+1

一個'int *'指向'int'。 '&c'將是'int **'類型或者指向'int'的指針。 – oldrinb

+0

謝謝大家!你所有的答案都有幫助,現在我完全明白了。 – CornSmith

回答

3

pointer只是地址的另一個詞。沒有什麼真正的魔力,它只是一個包含數字的變量,該數字就是它指向的內存地址。

在你的榜樣,內存可能是這樣的:

0x00001004 - 10   # a 
0x00001008 - 20   # b 
0x0000100C - 0x0001004 # i 
0x00001010 - 0x0001008 # j 
0x00001014 - 00   # temp 

ijint*這意味着它們含有包含integar的地址。代碼*i說:「返回i中地址處的任何值,並假定它是int

所以,如果你看一下你的swapnum,這裏發生了什麼:

int temp = *i; 
# take the value at 0x0001004 (10) and place it in 0x00001014 

*i = *j; 
# place the value at 0x0001008 (20) and place it in 0x00001004 

*j = temp; 
# place the value at 0x0001014 (10) and place it in 0x0001008 

後其內存看起來像這樣:

0x00001004 - 20   # a 
0x00001008 - 10   # b 
0x0000100C - 0x0001004 # i 
0x00001010 - 0x0001008 # j 
0x00001014 - 10   # temp 

你當然可以這樣做:

int* c = &a; 
swapnum(c, &b); 

你所做的只是得到a的地址,把它放在c,然後將它傳遞到swapnum,這需要一個地址。指針只是一個地址。

1

&item返回指向item的指針。

另外,在所有現代體系結構中,我知道指針只是項目的地址。

如果你犯了一個指針的指針,並把它傳遞給swapnum的兩件事情會發生:

  1. 你的編譯器會抱怨,因爲指針的類型是int * 的,不是int
  2. 你將交換指針的值。至少如果指針的大小與整數相同
+0

指針總是一個項目的地址,在任何架構上都是如此。這是一個「指針」的定義 –

+0

實際上,在8位和16位x86指針上稍微複雜一些。你有'近'和'遠'的指針,遠的包括段和地址,而近的只是地址。一個near和far指針可以指向相同的數據,同時具有不同的值。 – perh

+0

但是如果我通過引用將指針傳遞給期望指針的函數呢?我真的把一個指針傳給一個指針?在那種情況下,爲什麼我可以用'a-> data'像普通的函數那樣訪問內存,而不是'a-> pointer-> data'? – CornSmith

2

對象的地址指向對象的指針!實際上,這實際上就是指針,它們現在就是一個對象所處的地址。使用地址而不是對象的重點在於使用地址你有相同的對象。

0

C++是一種靜態類型語言。這意味着每個表達式都有一個已知編譯時間的特定類型。 C++標準告訴我們,如果表達式expr是內置類型T,那麼表達式& expr是T *類型(指向T的指針)。這一切......

1

main您使用的地址的&運營商傳遞到swapnumab地址。

指針實際上的值的地址。根本沒有「膠囊」! (也許,將它們想象成沒有膠囊的簡單地址更容易!)。

如果你做了int *c = &a你可以通過c到swapnum()而不是&a它會工作得很好。您無法通過&c,因爲您要通過int **,而該功能期望int *

1

&a是被評估爲內存中的a's地址的表達式。該值必須存儲在指針類型的變量中。例如:

int* i = &a; 

這裏,iint pointer類型的變量充當容器,膠囊劑,爲分配給它的值。然而,這個膠囊並不保留a價值本身;它保持了&a的價值。另外,作爲一個膠囊是一般變量的直接結果;不一定是因爲是pointer類型的變量。

現在,這種說法:

swapnum(&a, &b); 

不應對參數爲一些局部變量的一個非常正常的工作 - 一個正常傳遞按值函數調用。在這種情況下,實際發生的是將&a值(即a's地址)複製到局部變量i中,當然這需要被定義爲int pointer類型。

如果定義:

int * c = &a; 

,然後調用:

swapnum (&c... 

那就沒辦法了,因爲cint pointer類型的變量; &c,那麼,將是這樣一個變量的地址;因此,包含這個地址的局部變量類型i應該被定義爲這種類型值的容器;即它應該被定義爲指向地址的類型變量的指針int pointerint **

這樣的函數調用而不相應地改變函數肯定會導致編譯器時間錯誤。

相關問題