2013-09-23 45 views
2
int *p; 
scanf("%d",&p); 
printf("%d\n",p); 

在我以前的理解中,「p」是一個地址,但現在看來p是一個簡單的變量。爲什麼這3行代碼是正確的?關於* p

我不明白爲什麼這3行代碼是正確的!

你能幫助我嗎?

+0

與您從輸入中讀取的值相同的值是以後打印的值嗎?對我來說,它是有效的,因爲當你閱讀時你可以輸入「內存地址」,但是當你打印時,它將打印存儲在該內存位置的任何值 – OscarG

+0

這就是C而不是C++(當然,它會編譯爲C++,但它是C子集,它是你想要引導的一部分) –

+3

他們編譯,這並不意味着他們是正確的 – P0W

回答

3

他們是不對的。他們只是似乎工作,因爲你問scanf來存儲一個整數和地址在哪裏存儲它是地址的指針p。你基本上把指針本身的存儲視爲一個整數的存儲。同樣,對於printf,您傳遞指針的地址(其中包含整數),並要求printf從那裏讀取它作爲整數。你甚至可以在第一線更改爲

float* p; 

,它仍然會似乎工作。最後,這是一個很好的例子,說明爲什麼你應該避免使用不是類型安全的C風格接口。

+0

非常感謝! – lirui

+0

@RayLee不客氣。由於你是新手,請允許我提醒你不要忘記[接受答案](http://meta.stackexchange.com/questions/5234)(如果你覺得其中一個回答對你有幫助, 。 –

1

如果我將通過你的語句解釋,那麼這將是

int *p; //Declaration of pointer variable p, which can hold the address of integer variable 
scanf("%d",&p); //Getting input, will be stored at address of pointer variable p 
printf("%d\n",p); //It will display the value stored at &p 
+2

正確,除了最後一行。它會傳遞一個指針作爲一個可變參數,其中一個整數是預期的,給出未定義的行爲。 –

1

上面的代碼是不是真的正確,它是建立在一個公平量的假設和C構造的頂部。

第一個假設是指針和int具有相同的大小,這將在大多數(我所知道的)64位平臺中打破。然後使用類型不安全的接口(可變參數函數參數)傳遞int*的地址,就好像它是int的地址一樣。在scanf內的代碼將假定它是書面方式向int和位上書寫......但類型不是int*和位模式可能或沒有意義,甚至在平臺上,其中sizeof(int) = sizeof(int*)

+0

非常感謝你! – lirui

4

這隻會在指針的大小與整數相同時纔會起作用,因爲您基本上將指針視爲整數。也就是說,如果int是32位整數,並且指針void*是32位地址。

應當書面方式:將實際使用p爲整數,而不是宣佈它作爲一個指針和治療它像一個整數的

int p; // not the lack of the * 
scanf("%d",&p); // this gives scanf the address of p 
printf("%d\n",p); // this uses p's value 

+1

使用'int * p = new int();也是正確的。 scanf(「%d」,p); printf(「%d \ n」,* p);刪除p;'。當然,管理內存只是一個噩夢的噩夢......我認爲重要的是要注意scanf和printf之間不同級別的間接尋址。 – 2013-09-23 17:41:57

1

該代碼根本不正確。

一些(錯誤)編譯器可能無法檢測到問題,因爲printfscanf都是可變參數函數......但是例如g ++會警告您傳遞的類型與格式字符串中指定的類型不匹配。

相關問題