某悦的每日面试题打卡2 关于参数传递

1.形参和实参

形参(parameter):形参是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。

实参(argument):在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为实参。

注:实参和形参在数量上,类型上,顺序上应严格一致,否则会发生“类型不匹配”的错误。

2.形参和实参的区别

(1)形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。

(2)实参可以是常量、变量表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定值, 以便把这些值传送给形参。 因此应预先用赋值,输入等办法使实参获得确定值。

(3)在函数调用中发生的数据传递是单向的,即只能把实参的值传给形参,而不能把形参的值反向传给实参。因此在函数调用中,形参的值发生改变,而实参的值不会变化。

(4)当形参和实参不是指针类型时,在该函数运行时,形参和实参是不同的变量,他们在内存中位于不同的位置,形参将实参的内容复制一份,在该函数运行结束时形参被释放,而实参内容不会改变。

3.参数传递方式

(1)值传递:值传递是一个形参向函数所属的栈拷贝数据的过程。形参是实参的拷贝,被调函数对形参的任何操作都是作为局部变量进行的,不会影响主调函数的实参变量的值。从被调用函数的角度来说,值传递是单向的(实参到形参),参数的值只能传入,不能传出。当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用值传递。如果值传递的对象是类对象或是大的结构体对象,将耗费一定的时间和空间。

(2)指针传递:指针传递同样是一个形参向函数所属的栈拷贝数据的过程,但拷贝的数据是一个固定为4字节的地址,指针参数传递本质上是值传递,它所传递的是一个地址值。值传递过程中,被调函数的形参作为被调函数的局部变量处理,会在栈中开辟内存空间以存放由主调函数传递进来的实参值,从而形成了实参的一个副本(替身)。因为在指针传递中形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作,所以这种方式在函数内部的对形参的修改能导致外部实参的变化。

(3)引用传递:同样有上述的数据拷贝过程,但其是针对地址的,相当于为该数据所在的地址起了一个别名。引用传递过程中,被调函数的形式参数也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量(根据别名找到主调函数中的本体)。因此,被调函数对形参的任何操作都会影响主调函数中的实参变量。

注:形参带&符号的引用传递在C语言中是不可用的,只有C++中支持

从效率上讲,指针传递和引用传递比值传递效率高。一般主张使用引用传递,代码逻辑上更加紧凑、清晰。

4.指针参数传递和引用参数传递的区别 

(1)虽然他们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将应用不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量(地址),那就得使用指向指针的指针或者指针引用。

(2)从编译的角度来讲,程序在编译时分别将指针和引用添加到符号表上,符号表中记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值(与实参名字不同,地址相同)。符号表生成之后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值