函数何时值传递,何时指针,何时引用传递总结
编程中定义函数,一般三种传递方法,看是简单。想灵活合理选择,还须要大量的编程经验和技巧。
故在这里特意总结一下这三种传递的方法。
根本差别: 函数值传递不改变变量值,假设想改变变量值,须要返回值,然后用变量接收一下这个返回值。
而指针传递和引用传递都能够在函数内改变变量值。不须要通过返回值的形式改变。
应用场合: 当想通过这个函数。改变好几个变量的值,多个变量都通过函数返回值来改变变量值方式费时费力。所以这样的场合就比較适合使用指针和引用。
指针传递须要开内存。假设忘记释放的话,可能导致内存泄露。
浪费大量内存。
所以引用传递更好一些。
[p] 引用传递的性质象指针传递,书写形式象值传递,
理由:假设仅仅须要借用一下别名,就不是必需用指针,.[/p]void changeVar(int &myVar,int newValue); // 引用传递
这个函数第一个输入的參数不是一个指针,它是那个将被传递给这个函数的原始变量的一个别名。
在changeVar()函数里对这个參数变量进行的不论什么操作都将反映在changeVar()函数外的那个原始变量身上。这意味着changeVar()函数与原来的一样。
void changeVar(int myVar,int newValue){ //值传递。没有返回值,起不到改变变量的作用
myVar=newValue;
}
这使得这个函数更easy被调用----仅仅须要提供一个变量名;
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来返回。须要通过參数把改动后的值拉出来供我使用,非常当然的就想到了用指针,可是值就是传不出来。使我对原有的大脑中指针的思维产生混沌感。今天一上午才把函数传递又走了一遍。才明确当中道理(道行还是非常浅),如今整理例如以下:
我之前写的方法部分代码,相信好多人都是这么写的: [cpp] view plain copy- 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),为什么没有获得到呢?
概念
首先从概念上来说一下这几种函数传參方式及差别: 1、值传递:形參是实參的拷贝,改变函数形參的值并不会影响外部实參的值,这是最经常使用的一种传參方法。也是最简单的一种传參方法,仅仅须要传递參数,返回值那是return考虑的; 2、指针传递:指针传递參数从本质上来说也是值传递。它传递的是一个地址。【值传递过程中,被调函数的形參作为被调函数的局部变量来处理。即在函数内的栈中开辟内存空间以存放由主调函数放进来的实參的值。从而成了实參的一个副本(记住这个,函数内參数的是实參的副本)】。因为指针传递的是外部实參的地址,当被调函数的形參值发生改变时。自然外部实參值也发生改变。3、引用传递:被调函数的形參尽管也作为局部变量在栈中开辟了内存空间,可是栈中存放的是由主调函数放进的实參变量的地址。被调函数对形參的不论什么操作都被处理成间接寻址。即通过栈中存放的地址訪问主调函数中实參变量(实參和形參通过引用,合二为一,说白点就是:一个人,有两个名字那种;后面想会具体说)。因此。形參的不论什么修改都会直接影响到实參。
实例
先从简单的样例開始:- 值传递:样例略过。
- 指针传递:
- 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 *a = &x;//用于指针传递,a有自己独立的内存地址,存储的内容是x的地址,*a是存x的值。
输出结果:
传入值的各变量的初始状态(地址状态):
从上图关系能够知道:a(b)是一个指向外部实參地址的指针,*a(*b)是指针的内容,假设改变了*a(*b)也必定导致外部实參的改变。
交换后:
*a=2,*b=1;
这种结果是因为a或者b指针指向x或者y的地址的缘故。因此因为*a,*b值得交换导致外部实參发生变化。
思考一下。以下的操作是否能实现值得变化?
简单測试代码:
[cpp] view
plain copy
- 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";
还有一种成功传递參数的指针调用方法----指针的指针: [cpp] view plain copy
- void my_malloc(void** p, int size)
- {
- *p = malloc(sizeof(int)*size);
- }
- int main()
- {
- int *a;
- my_malloc(&a , 10);
- return 1;
- }
3、引用传递: [cpp] view plain copy
- 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;
- }
[cpp] view plain copy
- swapref(x, y);
总结: 本文重点还是在參数传指针方面,指针确实令人头疼。今天遇到了。会出错,弄明确以后,等过段时间,又忘了。又遇到错误。再来看,这样不断重复,希望能不断的提升。对指针的认识不断的加深!
- 函数何时值传递,何时指针,何时引用传递总结
- C/C++函数形参传实参时值传递、指针传递、引用传递的区别
- 在为函数传参时, 何时用引用,何时用指针呢?
- 引用作为函数与指针及值传递的差别
- 问题:向函数中传递指针和传递指针的引用的区别
- C++之函数参数的值传递、指针传递以及引用传递的区别和联系
- C++中值传递、指针传递、引用传递的总结
- 向函数中传递指针和传递指针的引用的区别
- 总结1->sizeof-默认值参数的函数-static-指针和引用概念-const-CAS
- 向函数中传递指针和传递指针的引用的区别
- 【转】C++函数——指针和引用类型的参数传递
- c++中函数参数传递(值传递、指针传递,引用传递)进一步认识
- 二级指针作为函数参数传递初始化的一点总结
- C++中值传递、指针传递、引用传递的总结
- 图解C/C++中函数参数的值传递、指针传递与引用传递
- C++:向函数传递对象(对象、对象指针、对象引用)
- 一道考察函数参数传递、值传递、指针传递(地址传递)、引用传递
- 图解C/C++中函数参数的值传递、指针传递与引用传递
- 函数参数传递、值传递、指针传递(地址传递)、引用传递
- C++ 常量指针或者常量引用作为函数参数传递的原因