scanf 為什麼要一定要加&
tags: 部落格文章
相信大家從一開始剛學程式的時候一定都踩過這個坑,沒有加&
導致程式錯誤,找半天還找不到那種的。
為什麼要加最主要的原因是,透過地址的傳遞才能夠修改變數。
& 是什麼意思
簡單說就是獲取位址的意思。
所謂的變數,其實可以理解成位址的別名,就比如說你在地圖上搜尋臺北車站
和搜尋 台灣台北市中正區北平西路3號100臺灣
可以找到同一棟建築物是一樣意思。
下面的代碼演示一下結果
int TaipeiStation;
cout << "台北車站的地址是:" << &TaipeiStation << endl;
利用地址修改變數
而其中位址這個型態,可以在宣告的時候加個 *
號來儲存。
int num;
//宣告的時候星號表示這個變數是一個指標
int* p = #
現在你可以透過別名 num 來修改記憶體中的數值
num = 10;
也可以透過地址來修改
// 使用的時候星號表示讀取地址中的數值
*p = 10;
透過函式修改變數
現在有了位址之後就可以把地址傳進函式了
void increase(int* num){
num++;
}
使用的話就像這個樣子
int num;
increase(&num);
現在謎底就揭曉拉,就是因為這個原因才導致一定要加上取址符號的
如果不打取址符號會發生什麼
其實 scanf 只要是傳遞位址進去就可以,並不是說一定必須,只是加上才是正確的寫法。如果不是傳遞位址的話,程式也會自動把數據轉換成位址。
傳遞整數
試著直接把一個整數傳入scanf
int i;
scanf("%d", i);
上面的情況會把i傳進去,對於scanf來說就是會試圖去讀取i這個位址有什麼東西,但是i沒有給初始值,沒有給初始值得話預設會是一個垃圾值,垃圾值可以當作一個亂數,產生的原因是上一個程式用完沒清掉的結果
嘗試對於亂數的位址存取是非法的,所以會報錯
Visual Studio 對於未初始的變數是不給使用的,這段在上面會直接報錯
傳遞整數位置
剛剛的錯誤在於位址是非法的位址,現在我們嘗試傳遞一個合法的地址進去就可以執行了
int p;
int i=(int)(&p);
cout << "[HEX:" << &p << "], [DEC:" << (int)&p << "]" << endl;
scanf("%d", i);
printf("%d\n", p);
printf("%d\n", *((int*)i));
i是一個 int
,會被隱式轉換成 int*
接著scanf就會對轉換出來的位址存取,如果是合法的位址那就不會有錯誤。