之前发过一次微博,今天又遇到这个问题,并且再次犯错,于是决定再加深一下。

就举php.net里的一个例子吧

  1. $a = array('abe','ben','cam');
  2. foreach ($a as $k=>&$n){
  3. $n = strtoupper($n);
  4. }
  5. print_r($a);
  6. foreach ($a as $k=>$n){ // notice NO reference here!
  7. echo "$n\n";
  8. }
  9. print_r($a);

输出的结果是:

  1. Array
  2. (
  3. [0] => ABE
  4. [1] => BEN
  5. [2] => CAM
  6. )
  7. ABE
  8. BEN
  9. BEN
  10. Array
  11. (
  12. [0] => ABE
  13. [1] => BEN
  14. [2] => BEN
  15. )
  1.  

可以看到第一次foreach()循环以后是正常的,第二次循环以后$a[2]从变成了'BEN',和$a[1]一样。

初看很纳闷,但是如果在第二个foreach()里print_r($a),就很容易明白了,结果如下:

  1. Array
  2. (
  3. [0] => ABE
  4. [1] => BEN
  5. [2] => ABE
  6. )
  7.  
  8. Array
  9. (
  10. [0] => ABE
  11. [1] => BEN
  12. [2] => BEN
  13. )
  14.  
  15. Array
  16. (
  17. [0] => ABE
  18. [1] => BEN
  19. [2] => BEN
  20. )

由于第一个foreach()是用指针指向数组元素,所以循环结束后变量$n依然指向数组$a的最后一个元素,也就是$a[2]。

第二个foreach()里,第一次循环就将$a[0]的值'ABE'赋给$n,第二次又将$a[1]的值'BEN'赋给$n,其实这两次修改的都是$a[2]这个元素,第三次等于没有变化,所以$a[2]无辜地被修改了三次,导致最后的结果。

由此可见,如果foreach()中用指针指向数组元素,循环结束后最好销毁指针,以免后面再次用到重名的变量导致数组的值被无辜修改。

PS:之前的微博如下:

foreach() 中用指针指向数组元素,循环结束后最好销毁指针的更多相关文章

  1. [C++程序设计]指向数组元素的指针

    如果先使p指向数组a的首元素(即p=a),则: (1) p++(或p+=1).使p指向下一元素,即a[1]. 如果用*p,得到下一个元素a[1]的值. (2) *p++.由于++和*同优先级,结合方向 ...

  2. 【PAT】1008. 数组元素循环右移问题 (20)

    1008. 数组元素循环右移问题 (20) 一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0A1……AN- ...

  3. C语言学习笔记 (007) - 数组指针和通过指针引用数组元素的方法总结

    1.数组指针:即指向数组的指针 那么, 如何声明一个数组指针呢? ]; /*括号是必须写的,不然就是指针数组:10是数组的大小*/ 拓展:有指针类型元素的数组称为指针数组. 2.通过指针引用数组元素的 ...

  4. c语言——数组指针和通过指针引用数组元素的方法总结

    1.数组指针:即指向数组的指针 那么, 如何声明一个数组指针呢?int (* p)[10]; /*括号是必须写的,不然就是指针数组:10是数组的大小*/1拓展:有指针类型元素的数组称为指针数组. 2. ...

  5. PAT自测_打印沙漏、素数对猜想、数组元素循环右移、数字加倍重排、机器洗牌

    -自测1. 打印沙漏() 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇数个符号 ...

  6. PAT乙级 1008. 数组元素循环右移问题 (20)

    1008. 数组元素循环右移问题 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 一个数组A中存有N(N>0)个整数,在不允 ...

  7. PAT乙级真题1008. 数组元素循环右移问题 (20)

    原题: 1008. 数组元素循环右移问题 (20) 时间限制400 ms内存限制65536 kB 一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M&g ...

  8. PAT-乙级-1008. 数组元素循环右移问题 (20)

    1008. 数组元素循环右移问题 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 一个数组A中存有N(N>0)个整数,在不允 ...

  9. PTA自测-3 数组元素循环右移问题

    自测-3 数组元素循环右移问题  一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M≥0)个位置,即将A中的数据由(A0A1···A​N-1​​)变换为 ...

随机推荐

  1. hadoop 3.x 配置历史服务器

    修改$HADOOP_HOME/etc/hadoop/mapred-site.xml,加入以下配置(修改主机名为你自己的主机或IP,尽量不要使用中文注释) <!--history address- ...

  2. 看看是不是你想要的:pycharm永久激活!!!

    pycharm是很强大的开发工具,但是每次注册着实让人头疼.网络上很多注册码.注册服务器等等.但都只是一年或者不能用:为次有如下解决方案.亲测有效!!! 如果想让pycharm永久被激活,比如截止日到 ...

  3. gcc/g++ 的参数总结(二)

    gcc 参数总结 如果是 c++,直接将 gcc 改为 g++ 即可. 1. gcc 编译流程 预处理,Pre-Processing:gcc -E test.c -o test.i //.i文件 编译 ...

  4. VS2017 安装过程

    2017 安装过程 工欲善其事必先利其器 Visual Studio 2017 正式版官方下载地址:https://www.visualstudio.com/downloads/ 安装vs2017的时 ...

  5. visio(2013)绘图工具的使用

    1. 链接线 ⇒ 直线 visio2010中如何使画出来的连接线为直线 [设计面板] ⇒ 在最右端将[链接线]设置为直线: 2. 连接线交叉而不产生交叉桥(弯曲) visio2013画图时两条直线交叉 ...

  6. STL序列式容器之list

    一,list容器基本概念 1.list容器基本知识 list容器的底部数据结构为双向链表,可以高效的进行插入和删除元素. list因为底层数据结构是双向链表,因此不支持下标操作和.at()函数的操作. ...

  7. mysql中常见的存储引擎和索引类型

    存储引擎 1.      定义 存储引擎说白了就是如何存储数据.如何为存储的数据建立索引和如何更新.查询数据等技术的实现方法.因为在关系数据库中数据的存储是以表的形式存储的,所以存储引擎也可以称为表类 ...

  8. 简明Python3教程 16.标准库

    简介 python标准库作为python标准安装的一部分,其自身包含数量庞大的实用模块, 因此熟悉python标准库非常重要,因为很多问题都能利用python标准库快速解决. 下面我们将研究标准库中的 ...

  9. 形态学-扩大-C代码

    直接在代码,难.他们明白: void MorhpolotyDilate_ChenLee(unsigned char* pBinImg, int imgW, int imgH, Tpoint* mask ...

  10. WPF: WrapPanel 容器的数据绑定(动态生成控件、遍历)

    原文:WPF: WrapPanel 容器的数据绑定(动态生成控件.遍历) 问题:        有一些CheckBox需要作为选项添加到页面上,但是数目不定.而为了方便排版,我选择用WrapPanel ...