面试 - PHP引用传递的问题,为什么是这样
怪我咯
怪我咯 2017-04-10 15:54:27
[PHP讨论组]

1)为什么 $a 结果是hello 而不是 undefined?

$a = "hello";
$b =& $a;
unset($b);
$b = "world";
var_dump($a); // hello

2)为什么 $a 结果是 1 而不是 2?

$a = 1;
$x =& $a;
$b = $a++;
var_dump($b); // 1

怪我咯
怪我咯

走同样的路,发现不同的人生

全部回复(6)
巴扎黑

1.参考php文档对unset的定义

如果在函数中 unset() 一个通过引用传递的变量,则只是局部变量被销毁,而在调用环境中的变量将保持调用 unset() 之前一样的值。 php unset

所以unset $b对$a无影响

2.参考php文档对递增递减运算符的定义

$a++ 后加 返回 $a,然后将 $a 的值加一。 php递增/递减运算符

$a++先返回1赋值给$b,所以$b为1

天蓬老师

1,b是a的快捷方式,马甲。快捷方式删除了不受影响。
2,$a++是表示语句执完才+1。你想得到2的结果改成$b = ++$a;或var_dump($a);即可

PHPz
  • $b是对$a的引用,它们是两个不同的变量指向同一块物理地址。当执行unset($b)时,只是注销$b这个变量的指引而非注销物理地址中的值,所以这个时候$a依旧是原值hello.

  • 这个问题你要理解$a++++$a的区别。

//$a++相当于
$b = $a;
$a += 1;

//++$a相当于
$a += 1;
$b = $a;

因此,$a++是先赋值后自增,所以$b的值为1

怪我咯

unset()函数只是unset掉$b对于$a的引用。
因此$a自己指向的空间依然会保留下来,只是对于$b的引用计数和is_ref标记被删除了。
因此$a并不符合垃圾回收机制回收的对象。
关于PHP的引用机制可以从引用计数基本知识中获取答案。

PHP中文网

第一个是因为, unset() 一个通过引用传递的变量,只是局部变量被销毁,而在调用环境中的变量将保持调用 unset() 之前一样的值。

第二个是运算优先级的问题, ++在前先自增后计算表达式, ++在后先计算表达式后自增

PHP中文网

首先说一下PHP中变量的理解:变量可以看做一个盒子,而变量名相当于这个盒子的标签,应用传递只是相当于给同一个盒子贴了两个标签,值传递是重新制作了一个一模一样的盒子!
局部变量名是存放在栈内存中的,unset()函数只是将一个变量的指向地址和变量实际存放位置断开,即把盒子标签撕掉!所以unset($b)只是将$b和实际存放位置的联系给断开了,那么$b在栈内存中的空间就会被回收掉,但是这个盒子上还有$a这个标签,所以是不会被垃圾回收机制给回收的!所以你输出$a肯定依然还是能被找到(寻址正确)的,但是现在你输出$b的话就应该是找不到的了!
至于第二个为什么不是2,其他人的回答已经很清楚了!这个是前置运算符++$a和后置运算符$a++的区别!
++$a:先自增再执行对$a的一切操作
$a++:操作了$a后再自增

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号