征服C指標(講那麼複雜,中國人永遠都別想超越美國人)
阿新 • • 發佈:2019-01-08
征服C指標(講那麼複雜,中國人永遠都別想超越美國人)
一段永久掉坑的程式碼
#include <stdio.h>
void one_set(int num)
{
num = 11;
}
void two_set(int *num) //掉坑一,蒙圈
{
*num = 11; //掉坑二,淚奔
}
int main(void)
{
int one = 1;
int two = 2;
one_set(one);
two_set(&two); //掉坑三,又掉坑,沒得救啦
printf("one = %d; two = %d\n", one, two);
return 1;
}
儲存為demo.c 執行gcc -g demo.c -o demo然後執行./demo 輸出結果是
one = 1; two = 11
結果沒有錯誤,為什麼掉坑
掉坑一:形參到底表示什麼意思?two_set函式樣子跟one_set一樣,能看出區別嗎?
大神說:不是有星號嗎?看得出來是傳入記憶體地址,不想跟傻逼聊天了!
我回復:那為啥你寫的程式碼,不寫成 void two_set(int* num) 更好
掉坑二:這賦值語句是啥?num就是普通數字,前面加個星號,是搞笑的嗎?
大神說:指標的意思呀,num的指標指向11,用屁股想想都明白!
我回復:那為啥你寫的程式碼,不寫成 *addr = 11; 更好
掉坑三:我去,我就喜歡實參傳入two,你就偏偏寫成&two,氣死人!
大神說:&這個符號,不懂就去學唄
我回復:我就偏偏不學,我要換另一種寫法
與大神對話後,我換了另一種寫法
#include <stdio.h>
void one_set(int num)
{
num = 11;
}
void two_set (int* addr) //掉坑一,蒙圈
{
*addr = 11; //掉坑二,淚奔
}
int main(void)
{
int one = 1;
int two = 2;
int* twoAddr = &two;
int threeAddr[] = {1,2,3};
one_set(one);
two_set(twoAddr); //掉坑三,又掉坑,沒得救啦
two_set(threeAddr);
printf("one = %d; two = %d\n", one, two);
printf("three[0] = %d; three[1] = %d\n", threeAddr[0], threeAddr[1]);
return 1;
}
儲存為demo.c 執行gcc -g demo.c -o demo然後執行./demo 輸出結果是
one = 1; two = 11
three[0] = 11; three[1] = 2
解釋為什麼這樣子寫
- 變數加上Addr表示是地址的意思,two_set函式內容表達的意思特別清晰,即傳入地址指向數字11。
- 書本表示陣列,喜歡用arr[] = {1,2,3}。通過該程式碼threeAddr對比,發現書本上arr其實是地址的意思。
- 另外驚訝發現,two_set函式居然可以用於int和int陣列,測試結果可以改變threeAddr陣列第一個元素為11。
- 得出來結論:threeAddr陣列是有連續3個地址,第一個地址是threeAddr,指向數字1。從而明白了記憶體結構。
*threeAddr | threeAddr [0] | 1 |
---|---|---|
*(threeAddr+1) | threeAddr [1] | 2 |
*(threeAddr+2) | threeAddr [2] | 3 |