[心得] 函數&指標&參照&陣列

看板C_and_CPP (C/C++)作者 (冷羽憶塵)時間16年前 (2010/02/09 20:23), 編輯推噓3(307)
留言10則, 3人參與, 最新討論串1/1
一段有意思的程式碼: #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

02/09 20:58, , 1F
好長...
02/09 20:58, 1F

02/09 21:25, , 2F
請問 int (&ex_f (int(&a)[5]) )[5] 中第一個 & 的意思?
02/09 21:25, 2F

02/09 21:27, , 3F
另外 int a[5] 和 int(&a)[5] 前者有宣告一塊記憶體
02/09 21:27, 3F

02/09 21:28, , 4F
後者只有取參照 一改就全改了 應該不太一樣吧?
02/09 21:28, 4F
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)

02/09 22:00, , 5F
啊 我懂了 這裡指的是 argument 不是函式內的宣告
02/09 22:00, 5F

02/09 22:03, , 6F
嗯@@...雖然聽不懂你指的是甚麼((拖走..
02/09 22:03, 6F

02/09 22:05, , 7F
可以這麼說 參照和指標 最大的不同 是一個有固定大小
02/09 22:05, 7F

02/09 22:05, , 8F
甚至就根本是同個東西rename 另外一個只是指向他
02/09 22:05, 8F

02/09 22:05, , 9F
也可以隨便指向別人 指向任意大小
02/09 22:05, 9F

02/09 22:25, , 10F
嗯~知道了。
02/09 22:25, 10F
※ 編輯: s3748679 來自: 218.164.84.127 (02/09 22:54) ※ 編輯: s3748679 來自: 218.164.91.51 (02/10 10:50)
文章代碼(AID): #1BSLEysd (C_and_CPP)
文章代碼(AID): #1BSLEysd (C_and_CPP)