一、 形参和实参的区别
实参(argument):
在调用时传递给函数的参数。 实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。 因此应预先用赋值,函数调用时使形参获得确定值。实参不能作用于被调用函数中,即传值后在被调用函数中不能使用。
形参(parameter):
由于它不是实际存在变量,所以又称虚拟变量。是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数.在调用函数时,实参将赋值(传值、引用、传指针)给形参。注意实参的个数和类型应与形参一一对应(默认形参对应的实参可缺省),并且实参必须要有确定的值。形参的作用域为对应函数,函数调用结束返回后释放。
二、 实参和形参3中的结合方式
1、无实参调用方式
a、 实参和形参都没有 (无参函数)。
形式:函数返回数据类型 函数名(形参表位置);
此时形参表的位置可以为空,也可填上保留字void,但是无论怎样两边的括号不可以省略。例如:int show();void show(void);。
b、 无或有部分实参,但有形参(必须有默认形参,自右到左即默认形参右的边形参都要有默认值)
形式:函数返回数据类型 函数名(有初始化的形参表);
无实参但有形参,此时必须是有默认形参。例如:int sum(int a=1,int b=2){return a+b;}int main(){int c=sum();}
c、 实参和形参正常一一匹配
形式:函数返回数据类型 函数名(有初始化的形参表);
无实参但有形参,此时必须是有默认形参。例如:int sum(int a,int b){return a+b;}int main(){int c=sum(1,2);}
2、传值调用方式
实参值通过栈从实参表从右向左一一传递给形参,调用时函数中的形参值的任何修改都会影响带实参,函数调用中发生的数据传送是单向的。形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。在函数调用处调用各形参类的构造函数,函数返回主函数前析构函数。
注意:若函数具有默认形参,默认值的形参必须从右至左连续定义,即在一个具有默认值的形参的右边不能有未指定默认值的形参;在函数调用时,如果省略了每个实参,则直到最右端的实参都要省略(省略的实参与之对应的形参都要有默认值)。
3、地址传递方式
a、指针方式
如果以指针作为函数的形参,在调用时实参将值传递给形参,也就是实参和形参指针变量指向同一内存地址,所以被调用函数中通过形参对数据值的改变同时也会影响到实参所指向的数据值,实现参数双向传递的目的,并且此时没有给形参另外分配内存(浅拷贝)。不调用各形参类的构造函数、拷贝构造和拷贝赋值函数。
注意:数组也属于指针(指针常量)。
b、引用方式
与指针方式所述基本相同,但又有引用的特性。引用封锁了对地址的可修改性,只能修改引用所指向变量的值,是的间接访问操作更安全。不调用各形参类的构造函数、拷贝构造和拷贝赋值函数
注意:
1、指针可以有整型数强制类型转换得到,但引用不可以由强制类型转换。
2、关于const修饰的点击另外一篇博客https://blog.csdn.net/qq_43148810/article/details/83218314
3、非常建议使用引用方式(pass by reference)或者常引用(pass by reference const)。
三、 哪些情况实参与形参类型不匹配时仍然不会出错
1、基本数据类型传值调用方式会进行隐式的强制转换,转到形参,按形参类型处理,不会按实参类型处理。虽然编译器不会出错,但是很多时候回警告,并且要注意类型之间的转化。
2、基本数据类型传地址调用方式不能进行隐式的强制转换,此时数据类型不匹配会编译器会报错。同样类型的数组或指针变量的形参和实参可以相互匹配。
3、其他数据类型的实参和形参不匹配时一般都会报错(例如struct等)。
4、类的构造函数的出现默认形参,可使得该类的隐式类型转换。
如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810