问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

c++ 引用的本质是不是指针

发布网友 发布时间:2022-04-10 10:46

我来回答

4个回答

懂视网 时间:2022-04-10 15:07

Note:

如果具有引用的数组被拷贝,其值不会解除引用。对于数组传值给函数也是如此。

Note:

如果对一个未定义的变量进行引用赋值、引用参数传递或引用返回,则会自动创建该变量。

Example #1 对未定义的变量使用引用

<?php
function foo(&$var) { }

foo($a); // $a is "created" and assigned to null

$b = array();
foo($b[‘b‘]);
var_dump(array_key_exists(‘b‘, $b)); // bool(true)

$c = new StdClass;
foo($c->d);
var_dump(property_exists($c, ‘d‘)); // bool(true)
?>

同样的语法可以用在函数中,它返回引用,以及用在 new 运算符中(PHP 4.0.4 以及以后版本):

<?php
$bar =& new fooclass();
$foo =& find_var($bar);
?>
自 PHP 5 起,new 自动返回引用,因此在此使用 =& 已经过时了并且会产生 E_STRICT 级别的消息。

Note:

不用 & 运算符导致对象生成了一个拷贝。如果在类中用 $this,它将作用于该类当前的实例。没有用 & 的赋值将拷贝这个实例(例如对象)并且 $this将作用于这个拷贝上,这并不总是想要的结果。由于性能和内存消耗的问题,通常只想工作在一个实例上面。

尽管可以用 @ 运算符来抑制构造函数中的任何错误信息,例如用 @new,但用 &new 语句时这不起效果。这是 Zend 引擎的一个限制并且会导致一个解析错误。

Warning

如果在一个函数内部给一个声明为 global 的变量赋于一个引用,该引用只在函数内部可见。可以通过使用 $GLOBALS 数组避免这一点。

Example #2 在函数内引用全局变量

<?php
$var1 = "Example variable";
$var2 = "";

function global_references($use_globals)
{
    global $var1, $var2;
    if (!$use_globals) {
        $var2 =& $var1; // visible only inside the function
    } else {
        $GLOBALS["var2"] =& $var1; // visible also in global context
    }
}

global_references(false);
echo "var2 is set to ‘$var2‘ "; // var2 is set to ‘‘
global_references(true);
echo "var2 is set to ‘$var2‘ "; // var2 is set to ‘Example variable‘
?>
把 global $var; 当成是 $var =& $GLOBALS[‘var‘]; 的简写。从而将其它引用赋给 $var 只改变了本地变量的引用。

Note:

如果在 foreach 语句中给一个具有引用的变量赋值,被引用的对象也被改变。

Example #3 引用与 foreach 语句

<?php
$ref = 0;
$row =& $ref;
foreach (array(1, 2, 3) as $row) {
    // do something
}
echo $ref; // 3 - last element of the iterated array
?>

引用做的第二件事是用引用传递变量。这是通过在函数内建立一个本地变量并且该变量在呼叫范围内引用了同一个内容来实现的。例如:

<?php
function foo(&$var)
{
    $var++;
}

$a=5;
foo($a);
?>
将使 $a 变成 6。这是因为在 foo 函数中变量 $var 指向了和 $a 指向的同一个内容。更多详细解释见引用传递。

引用做的第三件事是引用返回。

 数组引用的一个bug(后来仔细推敲,其实不是bug)

摘自:http://www.php.net/manual/zh/language.references.whatdo.php

It appears that references can have side-effects.  Below are two examples.  Both are simply copying one array to another.  In the second example, a reference is made to a value in the first array before the copy.  In the first example the value at index 0 points to two separate memory locations. In the second example, the value at index 0 points to the same memory location. 


I won‘t say this is a bug, because I don‘t know what the designed behavior of PHP is, but I don‘t think ANY developers would expect this behavior, so look out.

An example of where this could cause problems is if you do an array copy in a script and expect on type of behavior, but then later add a reference to a value in the array earlier in the script, and then find that the array copy behavior has unexpectedly changed.

  <?php
// Example one
$arr1 = array(1);
echo " before: ";
echo "$arr1[0] == {$arr1[0]} ";
$arr2 = $arr1;
$arr2[0]++;
echo " after: ";
echo "$arr1[0] == {$arr1[0]} ";
echo "$arr2[0] == {$arr2[0]} ";

输出:

before:
$arr1[0] == 1

after:
$arr1[0] == 1
$arr2[0] == 2

// Example two

$arr3=array(1);
$a=&$arr3[0];
echo" before: ";
echo"$a == $a ";
echo"$arr3[0] == {$arr3[0]} ";
$arr4=$arr3;
$arr4[0]++;
echo" after: ";
echo"$a == $a ";
echo"$arr3[0] == {$arr3[0]} ";
echo"$arr4[0] == {$arr4[0]} ";

输出: 

before:
$a == 1
$arr3[0] == 1

after:
$a == 2
$arr3[0] == 2
$arr4[0] == 2

?>

    分析说明:

    对于“Example two”,刚开始还以为是个bug,其实仔细推敲,非也,分析如下,

在赋值(拷贝) 

$arr4=$arr3; 

之前,还有个对$arr3的第一个元素建立引用的过程,即

$a=&$arr3[0];

所以在后来的赋值拷贝( $arr4=$arr3; ),会把这个引用一并拷贝过去,所以说

$a、$arr3[0]、$arr4[0] 三者其实是引用关系,指向同一个地方。 

mysql引用并不是指针

标签:any   link   处理   back   rate   原因   工作   外部   对象   

热心网友 时间:2022-04-10 12:15

不是,但是引用的本质和指针一样都是传递地址,区别是编译器会安排函数在使用时候采用不同的内存机制和寻址方式。

举例

void func(int & r,int *p)
{
 r++;
 (*p)++;
}

void main()
{
    int a,b;
    a=1;
    b=10;
    func(a,&b);
    cout<<"a="<<a<<";b="<<b<<"\n";
}

先看输出结果

引用传递后,外部变量实参a转为形参r,b转为p,其中r作为引用,在函数内不分配内存直接使用传递进来的地址,并当做原变量本身使用,因此我们说r是a的别名,即直接寻址;而p为指针,在进入函数后在栈上必须分配内存空间,用来保存传递进来的地址,之后以指针方式间接寻址以操作数据。

要进一步了解必须进入编程的量子世界去理解,下面是反汇编后的编译器编译的汇编代码,让我们看看其本质吧。

调用

lea eax,[b]-将变量b的地址值存入寄存器eax
push eax-寄存器eax入栈
同理,将变量a的地址入栈,随后调用func,0CE11D8H为func函数的跳转指令所在地址。

可见,由于a是以引用形式传递,所以取的是a的地址而不是a的值,而b是显式取地址,所以取的也是b的地址,可以看出在调用函数前,指针和引用都是将地址压栈,因此从调用角度看,引用的区别是隐含取地址,而指针的是显式取地址。

函数内

函数开头一段指令是每个函数都有的,其作用就是保存执行函数体之前的所有CPU寄存器状态到栈内,包括基地址、栈指针等,以便完成函数之后弹栈获得原先状态继续执行后续指令。此时传递的a和b的地址被压在这部分数据下面,这个要记住,因为最后函数结束时会执行ret指令弹栈,是否需要返回看需要,这些工作编译器会安排好。

r++部分(引用)
0026294E  mov         eax,dword ptr [r] 
此处的r实际为a的地址存在栈内的地址值(不是传入的a的地址),作为双字指针取出其所指地址中的值,存入寄存器eax,这个值才是a的地址。

00262951  mov         ecx,dword ptr [eax] 
将寄存器eax的值再次以指针方式取出其指向的地址中的值,也就是eax内存储的是a的地址,作为指针取出其值就是a的值,也就是1,存入寄存器ecx。

00262953  add         ecx,1 
这个不用讲了吧,exc+1,就是执行r++,就是a++的关键操作。

00262956  mov         edx,dword ptr [r] 
再次取a的地址存入edx寄存器

00262959  mov         dword ptr [edx],ecx
将ecx的运算结果写入a的地址中。

(*p)++(指针)

指令几乎一模一样,可以看出,在函数内,r++和(*p)++是等价的,这意味着,r和p不同。r是实参a的别名,可以将r看做a本身来看待,或者说r代表了a的地址,好比a穿越时空来到函数内部可以被直接访问到,只是换了个名字而已,而如果(*p)等价于引用,则意味着p保存着b的地址。所以从源代码角度看,p是个局部指针变量保存传入的地址值,而r就是实参a本身。

热心网友 时间:2022-04-10 13:33

是用匿名的常量指针来实现的

热心网友 时间:2022-04-10 15:08

不是, 引用和指针还是有很大差别的
引用你可以理解为原变量的小名字,所以小名和原名都是表示的是同一个东西
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
小篇幅造句 易车如何发布二手车 转让卖车信息流程 《易车》群聊消息关闭方法 易车消息夜间勿扰方法步骤 易车如何开启消息夜间勿扰 易车 开启@消息推送 ...当入射角是 时,反射角是 。我们能从各个方向看到本身不发光的物体... 发泄的近义词和反义词是什么_发泄是什么意思? 我的世界手游 我的世界手机版怎么做末地传送门? 我的世界手游 末地传送门怎么做? 安全评价师的报考科目有什么 谁给几个好看的桌面壁纸啊?大一点啊,最好酷炫一点的,谢谢了。 AD桌面怎么去图标阴影 如何将服务器上的已创建好的快捷方式发送到域中所有成员计算机桌面上? 洗面奶好用还是洁面乳 干性皮肤是用洁面乳好还是洗面奶好 为什么我的右键不能设置桌面壁纸了? 长痘用洗面奶好还是洁面乳好? 活动目录安装完成后,怎么添加一个用户,桌面壁纸统一,组策略? 油性皮肤冬天用洗面奶还是洁面乳?那种比较好? 配置AD DS之后电脑无法显示桌面 AD软件推送 是用洗面奶洗脸好还是用洁面乳好? Win 2008 R2 AD组策略-统一域用户桌面背景要点 油性干燥皮肤,用洗面奶好还是洁面乳好?去角质多久用一次? AD域中如何设置固定的桌面,就是所有的域用户都设置为统一的桌面背景 洗脸使用洗面奶好 还是洁面乳好 如何实现AD组策略实现统一桌面和屏保 vivo那款手机信号好? vivox70信号好吗 皮革上喷漆的字怎么去掉?皮包之类的,有花纹的 高考英语要提前15分钟进入考场,那是不是英语考试时间是两个小时十五分钟呢? 2015年天津高考 英语 多长时间 天津高考英语不算听力要考多长时间 天津英语高考有口语吗 2022年天津英语高考听力时间 天津高考英语满分怎么是130? 天津高考英语答题时间安排?最好全面,如选择题、完形填空、阅读理解、阅读表达。请帮帮忙吧,谢谢了。 天津的高考英语阅读所度大概多少,几分钟一篇 西游记第十九回、二十回的主要内容,表现了主要人物的什么感情性格? 《西游记》的19回到22回写了哪些人物? 在西游记第18.19回中,你如何评价猪八戒 猪八戒人物形象分析,考试要用。 西游记随便十个回合概括、约300字、谢谢、要每回合的主要人物性格分析、谢谢 关于C语言指针的问题,指针的指针。 个人所得税税收筹划的方法有哪些 个人如何筹划个人所得税? C++ Mysql 建立连接时 错误的指针 请问富士S5600得手动对焦怎样用啊? 富士s4200相机怎么手动对焦 请教富士S2000HD的手动对焦如何操作?我按说明书上操作不对焦.