理解Php::ByRef和Php::ByVal之前我们先来补充几个知识点(关于C语言):
指针:指针的基本概念 在计算机中,所有的数据都是存放在存储器中的。 一般把存储器中的一个字节称为一个内存单元, 不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符量占1个单元等, 在第二章中已有详细的介绍。为了正确地访问这些内存单元, 必须为每个内存单元编上号。 根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址。 既然根据内存单元的编号或地址就可以找到所需的内存单元,所以通常也把这个地址称为指针。
下面这一张图很好的解释了这个指针:
32.png
参数调用:①传值:传值调用是指方法在调用参数时,不是对原参数进行操作,而是创建参数的拷贝并对进行操作,这种调用有利于保护数据。简单理解代码:
int m(int a){ return a; }
调用:
int c=m(i);
上述代码相当于一个简单的赋值语句,这种函数调用参数的方法实际就是传值。这里传入的是实际的数值:1。
参数调用:②引用:传值调用是指引函数传递参数的一种方式,使用引用调用,可以在子函数中对形参所做的更改对主函数中的实参有效。:
int i=1; //变量 也叫做实参int m(int a){ //int a 这里的a就是形参 return a; //返回形参}
int c=m(i);
上述代码只是简单的解释一下形参 实参。下面这段代码是百度里面的一段解释引用的解释。
int i,j; //定义两个变量 i 和 jint &ri=i; //新建int型的引用ri,并将其初始化为变量i的一个别名j=10; //修改j变量的内容为10ri=j; //相当于i=j 你修改ri实际就是修改i。因为你修改的ri实际是修改的i的内存当中的指针。//因为ri存储的是i变量在内存当中的地址
上述代码就是对引用的定义以及解释总结一下:
1:声明一个引用时,必须同时对它进行初始化,使它指向一个已经存在的对象。
2:一旦一个引用被初始化后,就不能改为指向其它对象(也就是说,一个引用从它诞生之时起,就必须确定是哪个变量的别名,而且始终只能作为这个变量的别名不能另作他用):
3:引用也可以作为形参,作为形参时候,情况稍有不同,这是因为,形参的初始化不在类型说明时候进行,而是在执行主调函数的调用表达式时 ,才为形参分配内存空间,同时用实参来初始化形参。这样引用类型的形参就通过形实结合,成为实参的一个别名,对形参的任何操作也就会直接作用于实参。
浅拷贝:在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存。
深拷贝:增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误。
理解完上述的情况,我们来说一下Php:ByVal和Php:ByRef。
Php:ByVal:可以理解为传值,传入具体的数值。传入的变量,在函数体内修改不会影响函数体外的定义。
例如下面的代码片段
int m(int a){ return a++; } m(i);printf(i);
运行上述代码,实际i变量还是为10。你虽然在函数体内更改了它的传入参数。但是你并没有更改外部的定义。所以还是10。
Php:ByRef:可以理解为引用(网上还有叫:传地。千篇一律),而它的方式跟浅拷贝类似。就是你传入的变量,实际传入的不是具体的值,而是传入的这个变量在内存中的地址,由于这种特性所以你不能直接调用的时候填入具体的值,而必须填写变量。
例如下面的代码片段
/* 传入具体的值 */m("www.iwonmo.com"); //错误 注:在Php:ByVal就是正确的,因为Php:ByVal是传值调用。可以传入变量,或者具体值/* 传入变量 */char *i="www.iwonmo.com"; m(i);//正确
再看下面这段代码:
int i=10;int m(int &a){ return a++; } m(i);printf(i);
这个时候打印的应该就是11。注意引用调用形参的时候,形参变量名前面要加“&”。这是一个硬性规定,没有什么解释的。是编程语言的书写格式。
作者:王And木
链接:https://www.jianshu.com/p/f7ecf4eac8ad
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
共同学习,写下你的评论
评论加载中...
作者其他优质文章