我知道,指針包含的變量的地址,例如:這個C代碼錯了嗎?
int c = 5;
int *p;
p = &c;
printf("%d",*p); // Outputs 5.
但是,如果我想的地址發送給一個函數是什麼:
void function (int *p)
{
p++;
}
int c;
function (&c);
當函數被調用時的值&c
被分配給int *p
。我想確切的說明是:*p = &c;
,但我不明白這是什麼意思。
我知道,指針包含的變量的地址,例如:這個C代碼錯了嗎?
int c = 5;
int *p;
p = &c;
printf("%d",*p); // Outputs 5.
但是,如果我想的地址發送給一個函數是什麼:
void function (int *p)
{
p++;
}
int c;
function (&c);
當函數被調用時的值&c
被分配給int *p
。我想確切的說明是:*p = &c;
,但我不明白這是什麼意思。
我更喜歡寫int* p = &c;
,也就是說,指向int類型的指針被分配了c的地址。
指針符號可能會造成混淆,因爲你已經注意到了,因爲這兩個是相同的:
int *p = &c;
和
int *p;
p = &c;
希望這有助於!
編輯:混亂是因爲*
既用作解除引用運算符,也用於聲明指針。因此,當p
包含地址c
時,*p
將指針取消引用並返回值c
。但是當你說int *p = &c;
時,*
說「p是指向int的指針」,但是沒有進行任何解引用。
您確定p++;
是您的意思嗎?這會增加p
指向的位置,但不會遞增當前位置的值。如果你想增加價值(即使c
變成6),那麼你想要的是(*p)++;
。
如果你想要的功能,以增加c
時&c
調用,那麼這樣寫:
void function(int *p) { ++(*p); }
function(int *p)
意味着p
是函數的參數。因此,無論呼叫者給出的值如何,都將分配給p
(而不是*p
)。
p
的類型是int *
。也就是說,p
是一個指向int的指針。
如果p
是一個指向int的指針,那麼*p
是它指向的int。
c
是一個int。因此&c
是一個指向int的指針,它指向的int是c
。因此,如果p
是&c
,則*p
是c
。
隨着我的版本的功能,此代碼:
int c = 5;
function(&c);
是否與此相同的代碼:
int c = 5; // same as before
int *p; // parameter of the function
p = &c; // assign the caller's value to the parameter
++(*p); // body of the function, increments *p, which is the same as c.
這確實與此相同的代碼:
int c = 5;
++c;
非常感謝很多人,這正是我所要求的 – hamza 2009-12-15 17:30:19
我無法真正弄清楚你的問題,但function
看起來像我的錯誤,你的意思是我s,或許,
++(*p)
否則它是一個沒有操作。
嚴格地說,該函數中的'p ++'調用未定義的行爲(因爲遞增p會創建一個指向無效位置的指針)。實際上,在所有普通的C編譯器中,它什麼都不做。 – 2009-12-13 14:40:10
不,沒有未定義的行爲,因爲遞增的p永遠不會使它脫離函數並立即被丟棄。 – 2009-12-13 14:47:43
但是即使計算這樣一個指針也是未定義的行爲,不是嗎? – 2009-12-13 15:31:52
*p = &c;
指:
獲取其在
編譯時決定
鏈接時(感謝Mikeage)e.g,0x1234的作爲例子的c
在存儲器中的地址。類型爲int的指針,即*p
被分配給0x1234,這聽起來不合我的意思,我認爲你應該這樣做,p = &c
然後*p
將有值指向的地址c
。因此*p
將具有c
分配給的值(這被稱爲解引用-通過在指針變量之前放置*
然後您可以獲得該值)。
在你的函數中,你試圖增加p指向的值。
void function (int *p) { *p++; } // It would be called like this int c = 5; function(&c); // Now c would have 6!
關鍵的一點是要通過引用傳遞這是什麼參數&c
一樣。 如果省略引用傳遞這樣的:
void function (int p) { p++; } // And call it like this int c = 5; function(c); // c is still 5
現在c
仍然是5,但功能本身c
是6,但沒有副本傳遞迴了,因爲它是在本地棧內增加內函數本身。
迂腐,它只在編譯時部分確定;取決於所得到的對象的操作系統和/或共享文庫[我知道這不是一個短語],它可能是可重定位的。但你仍然得到一個+1爲使用提問者的正確水平的細節(我當然沒有......) – Mikeage 2009-12-13 13:35:17
@Mikeage:謝謝:)那麼,在編譯時發生在連接權之前? ;)你就在那裏......也許這個詞應該是'在鏈接時',而不是編譯時......感謝指出它! :) – t0mm13b 2009-12-13 13:43:50
實際上,在加載時間;有些情況下,它可以在運行時重新定位 – Mikeage 2009-12-15 09:29:19
其他人已回答你的問題。我將補充一點,閱讀指針聲明的有用方法是這樣的。假設我有以下聲明:
int i;
這真的很容易。這裏,i
是int
。現在,讓我們說我有這樣的:
int *pi;
在這裏,你可以說pi
是一個指向int
(這是正確的)。另一種看待它的方式是*pi
是int
,即當你的代碼中有*pi
時,*pi
將是int
類型。在瞭解之後,我認爲很容易看出++pi
或pi++
不會增加int
,因爲pi
是錯誤的類型。你想要(*pi)++
。括號是必需的,因爲在C中,運算符++
比一元運算符*
具有更高的優先級。既然你不使用任何增量的副作用,你也可以這樣做:++*p
。
當然,就像所有的指針一樣,pi
必須指出一些對上述有用的東西是有意義的。
不,它不會「增加p指向的位置」,它只是增加p。 – 2009-12-13 13:07:07
對不起,我的部分表達不好。由於'p'是一個指針,所以遞增它會調用指針算術,這會將指針有效指向的內存地址移動一個點(改變*位置*,而不是*位置處的值* - 這就是我的意思通過遞增位置,而不是遞增位置處的值)。 – Amber 2009-12-13 13:10:37