[問題] #define function 傳 array

作者: kkroy (☆㊣↖煞氣ㄟ阿喂↘ξ★)   2017-12-29 18:47:02
請問各位大大,我定義一個 #define function 如下:
#define func(tmp) do{ \
int* bitmap = (int*)tmp; \
for(int i=0; i<3; i++) bitmap[i]+=2; \
}while(0)
宣告一個 struct:
struct AAA{
int bitmap[3]={0,1,2};
};
這時候,我搞不懂如果我在 main 裡 呼叫 func(),因為只是做程式碼替換,
不做型別檢查,所以以下兩種呼叫,執行結果都正確,但是想不通為什麼!?
Case1: 我認為正確的呼叫方式!
int main() {
AAA obj;
for(int i=0; i<3; i++)
cout<< obj.bitmap[i] <<endl;
cout <<endl;
func(obj.bitmap);
for(int i=0; i<3; i++)
cout<< obj.bitmap[i] <<endl;
cout <<endl;
}
執行結果:
0
1
2
2
3
4
沒啥問題!~
Case2: 我認為錯誤的呼叫方式:
int main() {
AAA obj;
for(int i=0; i<3; i++)
cout<< obj.bitmap[i] <<endl;
cout <<endl;
// 再取址一次
func(&obj.bitmap);
for(int i=0; i<3; i++)
cout<< obj.bitmap[i] <<endl;
cout <<endl;
}
怎麼結果還是:
0
1
2
2
3
4
沒錯耶!?????
結果顯示跑出來的結果竟然都正確? 為什麼?
把 #define 換回傳統 function call / function return:
void func(int* tmp){
int* bitmap = (int*)tmp;
for(int i=0; i<3; i++) bitmap[i]+=2;
}
這樣就符合期待了,只有 Case 1 能正確運作,Case 2 在compile階段就換判錯。
請問有誰知道是怎回事嗎?
感恩!~
作者: Killercat (殺人貓™)   2017-12-29 18:53:00
手邊沒編譯器 不過你可以用gcc -E選項展開macro看看
作者: soso7885 (YOHO)   2017-12-29 18:54:00
兩個都是傳array第一位元位址進去
作者: kkroy (☆㊣↖煞氣ㄟ阿喂↘ξ★)   2017-12-29 18:57:00
可是 case 2 取址兩次了不是嗎?
作者: LPH66 (-6.2598534e+18f)   2017-12-29 19:05:00
位址一樣型別不一樣, 但你的 macro 版裡用了指標轉型把這個差別給蓋掉了你有仔細看函式版的錯誤訊息就會知道 &obj.bitmap 的型別是int(*)[3], 即「指向一個長度為 3 的 int 陣列的指標」
作者: kkroy (☆㊣↖煞氣ㄟ阿喂↘ξ★)   2017-12-29 23:34:00
可是 case2,不是取第一個bitmap array位置的位置嗎?應該是double pointer ,我的理解是 int** 的型態吧?
作者: loveflames (咕啾咕啾魔法陣)   2017-12-30 00:08:00
case 2傳int陣列的位址,經過轉型,就得到指向int的指標case 1是int陣列轉型成int指標
作者: kkroy (☆㊣↖煞氣ㄟ阿喂↘ξ★)   2017-12-30 08:42:00
了解! 感謝兩位L大的解答~
作者: loveflames (咕啾咕啾魔法陣)   2017-12-30 09:25:00
陣列可以退化成指標,說穿就是這個

Links booklink

Contact Us: admin [ a t ] ucptt.com