在百度知道上碰到一段关于php的引用符&的代码,对于初学都来说还是很考验理解分析能力的,把代码和自己的分析贴上来作一个备份,也与大家共勉。

代码片段:

 $arr =array(1,2,3,4);
foreach ($arr as $k =>&$v) {}
foreach ($arr as $k=>$v) {}
print_r($arr);

输出结果:

Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 3
)

为什么是 1,2,3,3 而不是 1,2,3,4 呢? 如果你再多加几个值到数组中测试,会发现数组的最后一个值的结果总是等倒数第二个值。

这就是第一个 foreach 中的 引用符& 在作怪。

要理解结果为什么是 1,2,3,3,就得先理解 & 的作用。

& 是php中的引用,一个简单的例子:

 $a = 1;
$b = $a; $b = 10;
echo $a;

正常的数值赋值是传值,改变 $b 的值并 $a 不受影响,而如果使用 引用& :

 $a = 1;
$b = &$a; $b = 10;
echo $a;

改变 $b 的值发现 $a 的值也被改变了。

上面例子是 引用& 的最简单演示,再看下面这段代码:

 $a = 1;
$b = 2;
$c = &$a;
$c = &$b; $c = 10;
echo $a;
echo $b;

先后让 $c 引用 $a 和 $b,最终 $c 只会引用到 $b,道理很简单,一个变量中只能保存一个值。

道理虽然简单,但却是理解上面最开始的两个 foreach 循环的关键,现在再回过头来看看代码,先只看第一次 foreach 循环:

foreach ($arr as $k =>&$v) {}

每次循环其实都是在给 $k 赋值,变量只有一个,所以当循环结束,$k 会有一个最终值即数组的最后一个值,因为使用了引用,所以其实 $k 变量是数组的最后一个值的引用。

现在再来看第二个循环:

foreach ($arr as $k=>$v) {}

如果没有第一个循环,那这里就是一个普通的 foreach 循环,循环过程不会对数组中的值形成实质的影响,但因为有了第一次循环,结果就不一样了,通过上面的分析已经知道了 $k 是数组中最后一个值的引用,所以这次循环其实是在不断地用数组的值对数组的最后一个值进行赋值,如果在每次循环时都把数组的值输出出来,将会看得更清楚:

foreach ($arr as $k=>$v) { print_r($arr); }

唯一可能的疑问是:既然是用数组的值对最后一个值赋值,那不应该刚好是不变么?因为值的数量没变,顺序也没变,从前往后赋值,假如数组的值是 1,2,3 赋值后的结果不还是 1,2,3 么?为什么最后一个值就变了呢?有此疑问是因为忽略了最后一个值一直在被修改,当循环执行到倒数第二次时,最后一个值被修改成了数组倒数第二个的值,再继续循环就是把自己的值赋给自己,那当然是不会有任何变化的,所以不论数组中的值是什么,两次循环之后,最终数组的最后两个值一定是相等的。

php中引用&的一个小实例的更多相关文章

  1. 《挑战30天C++入门极限》 对C++中引用的补充说明(实例)

        对C++中引用的补充说明(实例) #include <iostream>    #include <string>    using namespace std;    ...

  2. Jmeter Web 性能测试入门 (四):一个小实例带你学会 Jmeter 脚本编写

    测试场景: 模拟并发100个user,在TesterHome 站内搜索VV00CC 添加线程组 添加HTTP信息头管理器 添加HTTP Sampler 填写HTTP Sampler中的信息 添加监听器 ...

  3. JavaScript进阶(二)在一个JS文件中引用另一个JS文件

    在一个JS文件中引用另一个JS文件       转载地址:http://blog.csdn.net/zndxlxm/article/details/7875787 方法一 在调用文件的顶部加入下例代码 ...

  4. 在一个jsp页面中引用另一个jsp文件的路径的问题

    为了提高代码的重用性,经常需要在一个jsp页面中引用另一个jsp文件的代码.关于引用时的路径的问题.下面只介绍动态引用的,我觉得静态引用的应该也一样. 相对路径: 一.在同一个文件夹下,a.jsp中引 ...

  5. VB.NET开发中遇到的一个小问题

    在修改公司用vb.net的写的代码时,遇到一个小问题 页面上有一个button, ID是btnNext, 在属性页中,它的click事件对应的是cmdNext, 我像在c#中一样,在属性页中双击cmd ...

  6. 关于JNI程序中引用另外一个lib

    我最近在写一个j2se的程序,我用的是开源的org.amse.ys.zip包里的代码,这部分代码是在FBReaderJ里抽取的,但是其中包含了一些native的方法,需要用的zlib库,而FBRead ...

  7. vue-router的一个小实例

    非2.0的 vue2.0还有vue-router2.0的改变还是挺大的 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用.vue的单页面应用是基于 ...

  8. 在一个JS文件中引用另一个JS文件

    方法一,在调用文件的顶部加入下例代码: document.write(”<script language=javascript src=’/js/import.js’></scrip ...

  9. 如何在maven项目中引用领一个项目

    1 有两个项目 maven01  和maven 02,想在maven 02中引用maven01的方法,该如何操作呢 maven01中Factory类中的方法 public class Factory ...

随机推荐

  1. stl_各容器的总结

    一.stl容器总结: 1.以下的操作是在一千万的数据下操作.copy 都是在足够的空间下进行的copy, 测量方式: std::clock_t start = std::clock(); //待测代码 ...

  2. linux下fdisk分区管理、文件系统管理、挂载文件系统等

    分区管理工具有:fdisk, parted, sfdisk fdisk:对于一块硬盘来讲,最多只能管理15分区: # fdisk -l [-u] [device...]  查看硬盘设备分区信息 # f ...

  3. ui-router多视图+嵌套视图+传参综合练习

    ui-router多视图:页面上存在的多个ui-view,它们以名字区分: 嵌套视图:一个ui-view的一个状态下对应了一个html,这个html里面又有一个ui-view. 视图之间传参:用ui. ...

  4. vue视频学习笔记03

    video 3 git page:任何仓库 master分支,都可以发布(git page)-------------------------------------双向过滤器:Vue.filter( ...

  5. 关于java和c++中的i++

    看到一个题目,大概是i=i++之类. 乍一看很简单,都知道i++的先参与计算再自增, 所以i不变. 但是仔细一想, 如果i不变, 那么在赋值之后, 自增的i, 增加的是谁呢? 逻辑顺序是怎样的呢? / ...

  6. Memcached for windows x64 x32 安装

    Memcached for windows 一.安装Memcached 1.下载 Memcached32位:http://s3.amazonaws.com/downloads.northscale.c ...

  7. Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦

    个人博客 对于技术人员来说,拥有自己的个人博客应该是一件令人向往的事情,可以记录和分享自己的观点,想到这件事就觉得有意思,但是刚开始写博客的时候脑海中是没有搭建个人博客这一想法的,因为刚起步的时候连我 ...

  8. 微信小程序,前端大梦想(七)

    微信小程序之数据缓存实例-备忘录 数据缓存在移动端的使用是非常重要的,既可以减少用户的流量支出又可以提高程序的访问速度和用户体验.每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStora ...

  9. GTD:让大脑用来思考,而不是用来记事!

    前段时间听刘润大师分享了一套GTD时间管理方法理论,感觉非常受用!现拿来跟大家分享下,这套方法是刘润老师践行20多年总结提炼的精华,经亲自实践确实行之有效. 俗话说:工欲善其事,必先利其器!人生也是如 ...

  10. xml注释快捷键

    eclipse中编辑Java或C/C++文件时,注释的快捷键均为 "CTRL + / ",编辑xml文件时,该快捷键无效. eclipse XML 注释:CTRL + SHIFT ...