PHP-CPP Php::ByVal和Php::ByRef详解

理解Php::ByRefPhp::ByVal之前我们先来补充几个知识点(关于C语言):

指针:指针的基本概念 在计算机中,所有的数据都是存放在存储器中的。 一般把存储器中的一个字节称为一个内存单元, 不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符量占1个单元等, 在第二章中已有详细的介绍。为了正确地访问这些内存单元, 必须为每个内存单元编上号。 根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址。 既然根据内存单元的编号或地址就可以找到所需的内存单元,所以通常也把这个地址称为指针。 

下面这一张图很好的解释了这个指针:

32.png

参数调用:传值:传值调用是指方法在调用参数时,不是对原参数进行操作,而是创建参数的拷贝并对进行操作,这种调用有利于保护数据。简单理解代码:

int i=1;
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 和 j
int &ri=i; //新建int型的引用ri,并将其初始化为变量i的一个别名
j=10; //修改j变量的内容为10
ri=j; //相当于i=j 你修改ri实际就是修改i。因为你修改的ri实际是修改的i的内存当中的指针。
//因为ri存储的是i变量在内存当中的地址

上述代码就是对引用的定义以及解释总结一下:

1:声明一个引用时,必须同时对它进行初始化,使它指向一个已经存在的对象。

2:一旦一个引用被初始化后,就不能改为指向其它对象(也就是说,一个引用从它诞生之时起,就必须确定是哪个变量的别名,而且始终只能作为这个变量的别名不能另作他用):

3:引用也可以作为形参,作为形参时候,情况稍有不同,这是因为,形参的初始化不在类型说明时候进行,而是在执行主调函数的调用表达式时 ,才为形参分配内存空间,同时用实参来初始化形参。这样引用类型的形参就通过形实结合,成为实参的一个别名,对形参的任何操作也就会直接作用于实参。


浅拷贝:在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存。


深拷贝:增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误。


理解完上述的情况,我们来说一下Php:ByVal和Php:ByRef。


Php:ByVal:可以理解为传值,传入具体的数值。传入的变量,在函数体内修改不会影响函数体外的定义。

例如下面的代码片段

int i=10;
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。注意引用调用形参的时候,形参变量名前面要加“&”。这是一个硬性规定,没有什么解释的。是编程语言的书写格式。


PHP-CPP Php::ByVal和Php::ByRef详解


本站如无特别说明即为原创,转而告知:(http://iwonmo.com/archives/1319.html)

标签: php-cpp, phpcpp, Php::ByVal, Php::ByRef

添加新评论