首先在C語言中,指針的值就是地址,不過這個地址不是它自己的地址,而是綁定變數的地址。

int val = 0;
int* p = val;
// int* p2_ = val; wrong synatax
int* p2 = (int* )val;

所以要初始化一個指針,你得給一個另外的地址。指針p = val地址,即int* p = val。此時val的值應該是 0x010FFBEC(假設在內存中這個地址存儲val)。如果說你硬要把0給p2,你就需要告訴編譯器,0是一個地址,同時你還要顯式的轉換將int 轉換為int,即int* p2 =(int*)val,當然我不建議你這麼做。

記住一點:在不考慮隱式轉換/顯式轉換/自定義數據類型的情況下,只有相同的數據類型才能賦值。要初始化一個指針,你就必須給地址。要給地址,對於一個非指針變數,你要取地址,對於一個指針變數,可以直接賦值。

當然了,你可以這麼理解:所有的變數都是有地址屬性,只不過大部分都是隱式表現的(所以要取地址),指針變數則是顯式表現的。


首先要理解類型,不要逃避類型系統,把未知的類型跟已知的混淆。

指針這一類型,不是像整數、字元這樣的「自然類型」,所以初學者總是理解不了。

指針是計算機程序中獨有的類型,它的值告訴CPU,CPU應該往內存的什麼位置去尋找變數。

所以內存地址就是指針的值,但整數是數字而不是內存地址。

理解了類型再去理解強制轉換,強制轉換相當於是否定計算機所認為的類型,重新解釋它。告訴計算機「我不要你覺得,我要我覺得。」

所以題主所說的不是整數「變成」了內存地址,而是你硬說它是地址。就像是指鹿為馬,但計算機傻,只能乖乖聽人話,所以它也只能把鹿當馬騎。


我這個寫的有問題,我是把指針當成了指針變數的同義詞或者縮寫來討論的。如果按照「指針即地址」,那麼指針與地址是絕對同義詞,指針變數則是存儲一個指針的變數。大家見笑了

************(分割線)*********

這個問題問得好,估計受這麼一句話;困惑,

「指針即地址」,然後你以為「指針」與「地址」一樣了,困惑在為什麼還要「變」。

其實吧,「指針」這個東東應該來說是存了一個地址,而不是「指針本身就是地址」。

int *point;

把point這個玩意看成一個變數,假設佔了4個Byte,這個point這個東東在這4個Byte裡面存了一個數,假設這個數是一個32位整形,這個數才是真正的「地址」。

所以啊,「指針即地址」稍微改一下,「指針裡面存的東西才是地址」。

point就是指針(可能存一個32位整數),*point才是這個地址存的東東,加上*是把point裡面存的32位整數拿出來,並找到這個地址吧。(大概是,我也不太會。)

所以啊,假設有個地址是

int *point;

1111111111......1111111111(32個1),

想把這個地址用一個指針變數存起來,

point 裡面放 11111111……11111111(32個1),

就把point那4個位元組的內存空間用32個1填充啦。(當然是假設32個1,可能會變,我也不懂。)

如果你在1111111……111111這個位置放了個整數5,那麼

int a = *point ;

就是把point那4個位元組裡面存的32個1拿出來,找到這個地址並把這地址存放的int類型的值賦值給a。

如果是

*point = 6;

就是把point指向的32位地址存儲的數據改成6。

這麼說來,回答上面問題的話,應該是用一個指針(變數)來記錄地址,這個記錄著一個地址的變數叫「指針變數」。

不知道樓主明白吧,當然我也可能錯了,書籍不在身邊,可以看《C和指針》,我看過覺得最清楚明白講指針的書。哈哈哈。

各位大哥,有錯誤一定告訴我啊,我也是新手。


簡單的說,主要是為了幫助程序員減少出錯。如果編譯器不檢查數值類型而是直接把一個int數值轉換為地址並且不加警告,那麼很可能因為程序員的一個粗心(把一個數值錯誤的賦值給了一個地址)產生災難性的後果而且幾乎無法發現。如果象現在這樣必須顯式的調用強制類型轉換語句再賦值,意味著程序員對這樣的轉換作了確認,最大可能避免了此類粗心錯誤。


因為不能把int類型的變數直接賦值給指針。

C標準沒有規定int到指針類型的隱式轉換,儘管有的編譯器可能實現了這一點,但應該會拋出一個warning。同樣的,不同指針類型之間也不能互相隱式轉化,除了void*等特例。

當你寫出(int*)0x1234這樣的代碼時,你並沒有對0x1234這片地址中存儲的對象進行任何操作。這裡的0x1234隻不過是一個十六進位的整數字面量而已。


C語言中所有數據都具有兩個屬性,一個是值,另外一個是類型。即使值相同如果類型不一致也是不同的數據。

有一道題: 小區內有一隻狗叫Oscar,有一隻貓也叫Oscar,大晚上有人喊:「Oscar」,請問他找誰?

// Oscar:「找我幹嘛?」

地址是一個整型數據,而指針具有「指向對象類型的指針」的類型。(因此即使指針的值相等,不同類型的指針也不是一種數據,就像同是整型的 short 1 和 int 1)

「本身就有類型的數據又作為其他類型數據的值使用」,這句話可能帶來了一定的困擾。確實從人類的感知習慣和基本類型的處理方法層面很難理解,但是指針是符號層面的內容。把上句話分解成兩個數據操作,「對指針的值的操作」和「對指針本身的操作」,然後對應兩個符號: * 和指針所指向對象的類型。

還有一道題: 小區內有一隻狗叫Oscar,有一隻貓叫奧斯卡,大晚上有人喊:「奧s卡」,請問他找誰?


地址不等同於指針..指針保存的是地址..


看了一圈,好像沒有說到點上的,我簡單說一下,題主可能誤解強制類型轉換了。

int *p = (int*)0x1234;

0x1234對於編譯器來說,是一個int。

當你做了(int*)0x1234這個操作時,相當於告訴編譯器0x1234是一個存放int類型數據的地址,這時才能賦值給p,編譯器才能確保這個操作是正確的。

如果你這樣寫

int *p = 0x1234;

編譯器可能會有警告,甚至是錯誤,因為它不能確保你是不是真的要將0x1234解釋為存放int類型數據的地址(隱式轉換)。

本例的強制類型轉換是對被轉換數據的重新解釋。

(經評論區提醒修改,在此強調,並非所有強制類型轉換都是對數據的重新解釋,還有諸如整數浮點數之間的值轉換等)

留個例子:

unsigned char cArray[4] = {0x01, 0x02, 0x03, 0x04};

int *a = (int*)cArray;

試想一下

*a == ?

題主用%08x輸出*a看看,你會理解強制轉換的含義。


沒有明白題目在問什麼。

地址和指針的值不是一回事嗎?


你自己測試下

#include&

int main()//原答案寫 void main()不標準……直接改過來了,以免引起不必要的誤導……

{

char a=12;

char b[2];

char *p=a;//char *p=a;你試試直接這樣寫…不帶行不行吧?

std::cout&std::cout&

std::cout&

std::cout&

//加一行:

std::cout&

return 0; //這個 return 0 對應 「int main()」……從此都不要省略啦!

}

//注意 {}內的 代碼全部需要 縮進,知乎不好排版……你自己要注意縮進。

然後 請你 把 結果 帖 上來吧……?!

那時 俺 再 給你 講!


我的理解就是,變數是你家,地址是你家門牌號,指針是寫著你家門牌號的紙條


推薦閱讀:
相关文章