作者s3748679 (冷羽憶塵)
看板C_and_CPP
標題[心得] 函數&指標&參照&陣列
時間Tue Feb 9 20:23:22 2010
一段有意思的程式碼:
#include <iostream>
using namespace std;
int (&ex_f (int(&a)[5]) )[5] //ex_f函數
{
for (int i = 0; i<5; i++)
a[i] = a[i] - 1;
return a;
}
int main()
{
int a[] = {2, 4, 6, 8, 10};
const int a_size = sizeof(a)/sizeof(int);
//這是一個指向函數的參照-function_ref
int (&(&function_ref)(int(&)[5]))[5] = ex_f;
int (&x)[a_size] = function_ref(a);
for (int i = 0; i<a_size; i++)
cout << x[i] << endl;
system("pause");
return 0;
}
源由:
Programming版->Re: [問題] 關於function pointer 作者: adrianshum (Alien)
->
char *(*(*x)(void))[] 意義為何?
char *(*(*x)(void))[]:
意義:
x是指標,指向函數,參數為void,傳回值為指標,
指向一個(非動態)陣列,
陣列元素是指標,指向char型別的變數。
應用上問題:
1. 怎麼樣的函數才可以丟進這個指標變數?
2. 指向一個陣列? 可是陣列在宣告時有直接寫這樣('[]')的嗎? 我找不到。
結論:
經測試,宣告了這樣的指標x('char (*x)[]')是沒有相對應的實物供之指向,
也就是說型別'char (*)[]'是沒有意義的。
PS: 如果換成參照,連編譯階段都過不去。(採C++測試)
嘗試調整:
1. 把'[]'改成'[常數或常數表示式]'
2. 減少指標的複雜程度。
3. 真的拿出一個陣列來應用看看。
4. 使用參照來替代指標。
實際修改所遇到的問題:
Q1: 函數傳回值改成了int(&)[5],可是在函數內要怎麼樣才能拿到相同型別的變數呢?
方案1: 在函數內宣告一個int[5],然後處理後傳回。
結果: 行不通!
原因: 函數結束後,函數內的自動變數通通會報光光。
方案2: 用動態陣列,然後處理後把陣列塞回去!
結果: 行不通!
原因: 動態陣列的型別為'int*',怎麼用'*&'改都沒辦法變成
'int[5]'放回去。
方案3: 引入一個和傳回型別一樣的參數,然後處理後拿參數傳回。
結果: OK!
Ans: 方案3
Q2: 雖然話是這樣講,不過把這函數型別改成void不是比較好嗎?
Ans: 也是可以啦...不過起碼在使用的時候可以簡化些步驟,
並沒有想像中那麼沒用。
Q3: 宣告函數時,參數用'int a[5]' 和 'int(&a)[5]'在實際效果上有區別嗎?
Ans:
int(&a)[5]:
1. 其參照所指的是靜態陣列,而且其元素個數為5。
2. 不符上一點條件者,在編譯階段就會被擋下來。
int a[5]:
1. 其實宣告'int *a'、'int a[]'、'int a[6]'是一樣的。
2. 實際測試過,當你參數為int a[5]但丟入int a[4],編譯照樣通過。
結論:
在某些情況下選擇像'int(&a)[5]'形式是比較適合的! 例如說
當你要做一個開'五'星彩的函數並希望在編譯階段就檢查到陣列是
否有誤,那麼參數選擇使用'int(&a)[5]'將會符合你的需求。
最後的話:
這些是我的個人見解,有什麼錯誤的地方請多多包涵。
歡迎各位蒞臨指導
冷羽憶塵
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 218.164.84.127
→ twotwoone:好長... 02/09 20:58
推 justdemon:請問 int (&ex_f (int(&a)[5]) )[5] 中第一個 & 的意思? 02/09 21:25
→ justdemon:另外 int a[5] 和 int(&a)[5] 前者有宣告一塊記憶體 02/09 21:27
→ justdemon:後者只有取參照 一改就全改了 應該不太一樣吧? 02/09 21:28
int (&ex_f (int(&a)[5]) )[5]:
ex_f是個函數,參數為int(&a)[5],傳回值為一個參照,指向有5個元素的陣列,
型別為int。
int a[5]和int(&a)[5]的確不一樣。
※ 編輯: s3748679 來自: 218.164.84.127 (02/09 22:00)
推 justdemon:啊 我懂了 這裡指的是 argument 不是函式內的宣告 02/09 22:00
→ s3748679:嗯@@...雖然聽不懂你指的是甚麼((拖走.. 02/09 22:03
推 justdemon:可以這麼說 參照和指標 最大的不同 是一個有固定大小 02/09 22:05
→ justdemon:甚至就根本是同個東西rename 另外一個只是指向他 02/09 22:05
→ justdemon:也可以隨便指向別人 指向任意大小 02/09 22:05
→ s3748679:嗯~知道了。 02/09 22:25
※ 編輯: s3748679 來自: 218.164.84.127 (02/09 22:54)
※ 編輯: s3748679 來自: 218.164.91.51 (02/10 10:50)