編程中定義函數,一般三種傳遞方法,看是簡單,想靈活合理選擇,還需要大量的編程經驗和技巧。 故在這裏特意總結一下這三種傳遞的方法。
根本區別: 函數值傳遞不改變變量值,如果想改變變量值,需要返回值,然後用變量接收一下這個返回值。 而指針傳遞和引用傳遞都可以在函數內改變變量值,不需要通過返回值的形式改變。
引用傳遞的性質象指針傳遞,書寫形式象值傳遞,
理由:如果只需要借用一下別名,就沒必要用指針,.
void changeVar(int &myVar,int newValue); // 引用傳遞
這個函數第一個輸入的參數不是一個指針,它是那個將被傳遞給這個函數的原始變量的一個別名。在changeVar()函數裏對這個參數變量進行的任何操作都將反映在changeVar()函數外的那個原始變量身上。這意味着changeVar()函數與原來的一樣。
void changeVar(int myVar,int newValue){ //值傳遞,沒有返回值,起不到改變變量的作用
myVar=newValue;
}
這使得這個函數更容易被調用----只需要提供一個變量名;
int main(){
int myNum=20;
changeVar(myNum,90); // 引用和值傳遞寫法一樣, 可見引用傳遞簡單,這也是c++新增加的功能,表現了c++的強大
}
這比值傳參語法上更簡單了。
以“引用傳遞”方式把參數值傳遞給一個函數是C++的新增功能,這可以讓函數的調用語法更加簡單清晰。
提示:1.在定義函數時,還可以讓它以“引用傳遞”方式而不是以“值傳遞”方式返回: int &myFuntion();
2.除了可以改變有關變量的值,“引用傳遞”方式的另一個好處是它的開銷相對要小一些:因爲不需要在函數裏創建臨時變量來容納那些值,程序的內存佔用量當然會小一些。
3.如果想獲得“引用傳遞”方式帶來的性能改善,但不想改變某個變量的值,可以把相應的輸入參數定義爲一個常量:
void myFunc(const int &myNum);
通過這樣定義的函數,可以把具體的參數直接傳遞給它:myFunc(7);
int script_orientation(VOID *dic, unsigned char *im, int w, int h,
RECT roi, int &script_id, // NOLINT
int &orient_id, // NOLINT
float &conf) { // NOLINT
函數調用
const char* model_file = "model.txt";
void* model = CNN_Init(model_file);
cv::Mat image = cv::imread(path, 0);
int script_id, orient_id;
script_orientation(model, image.data, image.cols, image.rows, roi,
script_id, orient_id, confidence);
這裏需要script_id, orient_id 兩個返回值, 所以這兩個定義爲應用較好。 調用時就不需要再去定義變量接收 這兩個 script_id,
orient_id 兩個返回值下面寫一個函數,從函數中把我需要的兩個值傳出來,由於傳出來的值比較多,所以不考慮用return來返回,需要通過參數把修改後的值拉出來供我使用,很當然的就想到了用指針,但是值就是傳不出來;使我對原有的大腦中指針的思維產生混沌感,今天一上午才把函數傳遞又走了一遍,才明白其中道理(道行還是很淺),現在整理如下:
- BOOL GetStartEndBoxes(BOOL bRow, const SwCrsrShell& rShell, SwTableBox *pStt, SwTableBox *pEnd)
- {
- SwSelBoxes aBoxes;
- ... ...
- pStt = aBoxes[0];
- pEnd = aBoxes[aBoxes.Count() - 1];
- return TRUE;
- }
- 調用:
- 。。。 。。。 SwTableBox *pStt=0;
- SwTableBox *pEnd=0;
- if ( !GetStartEndBoxes(bRow, *this, pStt, pEnd) )
- return FALSE;
傳遞一個指針到調用函數,希望獲得更新後的值(pStt, pEnd),爲什麼沒有獲得到呢?
概念
實例
- 值傳遞:例子略過。
- 指針傳遞:
- void swap(int *a,int *b)
- {
- int temp;
- temp=*a;
- *a=*b;
- *b=temp;
- cout<<"a=" <<a<<" ,"<<"b="<<b<<endl;
- cout<<"*a=" <<*a<<" ,"<<"*b="<<*b<<endl;
- cout<<"&a=" <<&a<<" ,"<<"&b="<<&b<<endl;
- }
- int main(){
- int x=1;
- int y=2;
- cout<<"x=" <<x<<" ,"<<"y="<<y<<endl;
- cout<<"&x=" <<&x<<" ,"<<"&y="<<&y<<endl;
- swap(&x,&y);
- }
- swap(&x,&y);
- int change(char* name){
- cout<<"*******CHANGE--BEFORE******"<<endl;
- cout<<"name=" <<name<<endl;
- cout<<"*name=" <<&name<<endl;
- name="alter";
- cout<<"*******CHANGE--AFTER********"<<endl;
- cout<<"name=" <<name<<endl;
- cout<<"*name=" <<&name<<endl;
- return 1;
- }
- int main()
- {
- char *str = "this is a test";
- cout<<"******MAIN--BEFORE*****"<<endl;
- cout<<"str=" <<str<<endl;
- cout<<"*str=" <<&str<<endl;
- change(str);
- cout<<"*****MAIN--AFTER*****"<<endl;
- cout<<"str=" <<str<<endl;
- cout<<"*str=" <<&str<<endl;
- return 1;
- }
- name="alter";
- void my_malloc(void** p, int size)
- {
- *p = malloc(sizeof(int)*size);
- }
- int main()
- {
- int *a;
- my_malloc(&a , 10);
- return 1;
- }
- void swapref(int &a,int &b)
- {
- cout << "******************before swapref:******************"<<endl;
- cout<<"a=" <<a<<" ,"<<"b="<<b<<endl;
- cout<<"&a=" <<&a<<" ,"<<"&b="<<&b<<endl;
- int temp;
- temp=a;
- a=b;
- b=temp;
- cout << "******************after swapref:******************"<<endl;
- cout<<"a=" <<a<<" ,"<<"b="<<b<<endl;
- cout<<"&a=" <<&a<<" ,"<<"&b="<<&b<<endl;
- }
- int main(){
- int x=1;
- int y=2;
- cout<<"******MAIN--BEFORE*****"<<endl;
- cout<<"x=" <<x<<" ,"<<"y="<<y<<endl;
- cout<<"&x=" <<&x<<" ,"<<"&y="<<&y<<endl;
- //swap(&x,&y);
- swapref(x, y);
- cout<<"*****MAIN--AFTER*****"<<endl;
- cout<<"x=" <<x<<" ,"<<"y="<<y<<endl;
- cout<<"&x=" <<&x<<" ,"<<"&y="<<&y<<endl;
- }
- swapref(x, y);