当前位置: 首页 > wzjs >正文

南京 公司网站制作网页设计网站

南京 公司网站制作,网页设计网站,有没有男女做那个的网站,嘉兴网站广优化公司文章目录 环境问题分析解决方法考一考总结何时使用&循环里修改元素值函数内修改参数值多个变量指向同一个内存地址函数返回引用 环境 PHP 8.4.5Windows 11 专业版 问题 看下面的PHP代码: $arr1 [1, 2, 3];foreach($arr1 as &$v) { // 这里加上&&am…

文章目录

  • 环境
  • 问题
  • 分析
  • 解决方法
  • 考一考
  • 总结
  • 何时使用&
    • 循环里修改元素值
    • 函数内修改参数值
    • 多个变量指向同一个内存地址
    • 函数返回引用

环境

  • PHP 8.4.5
  • Windows 11 专业版

问题

看下面的PHP代码:

$arr1 = [1, 2, 3];foreach($arr1 as &$v) { // 这里加上&,是为了修改原数组的值$v++;
}// 其它代码......foreach($arr1 as $v) {echo $v;
}

代码分析:

  1. 初始化数组 arr1
  2. 遍历数组,给每个元素加1。这里 &$v 中的 & 表示引用,也就是说, $v 指向的是实际的数组元素,这是因为需要修改数组元素的值,如果不加 & ,则是复制了一份(对 $v 的修改不影响数组)
  3. 遍历数组,打印每个元素的值

看起来简单直观,期望的输出结果是 234

然而,实际输出结果却是 233

分析

和很多其它语言一样,PHP在循环结束后,并不会自动清除循环变量。

比如:在Java语言里:

        for (; i <= 10; i++) {......}System.out.println("i = " + i);

在循环结束后,允许访问变量 i ,此时其值为 11

Delphi (Object Pascal)语言也类似:

    for i := 1 to 10 dobegin......end;writeln('i = ', i);

在循环结束后,允许访问变量 i ,此时其值为 11 ,不过编译器会给出一个警告。

回到PHP,在上面的代码里,第一个循环里用的是 &$v ,在循环结束后,数组变成了 2, 3, 4 。注意,此时 $v 指向数组最后一个元素(其值为 4 )。

在第二个循环里,每次迭代时会给 $v 赋值,但是别忘了, $v 指向的是数组最后一个元素,所以,给 $v 赋值,就会覆盖数组的最后一个元素。

  • 在第一次迭代时,数组变成了 2, 3, 2 (把第一个元素值赋给 $v ,覆盖最后一个元素)
  • 在第二次迭代时,数组变成了 2, 3, 3 (把第二个元素值赋给 $v ,覆盖最后一个元素)
  • 在第三次迭代时,数组仍然是 2, 3, 3 (把最后一个元素值赋给 $v ,覆盖最后一个元素)

解决方法

有两种解决方法:

  • 在第一次循环结束后,使用 unset($v) 来清理变量,也就是说,第二个循环里的 $v 是一个全新的变量
  • 在第二次循环里换个变量名

最好是两种方法都用。

当然,如果第一个循环里没用 & ,那么第二个循环里继续使用 $v 也没问题。

考一考

下面的代码,输出结果是什么?

$arr1 = [1, 2, 3];foreach($arr1 as &$v) { // 这里加上&,是为了修改原数组的值$v++;
}foreach($arr1 as &$v) {echo $v;
}

答案:输出结果是:

234

这里的输出结果,反而是期望的正确结果。

这是因为,在第二个循环里也用了引用 & ,所以每次迭代时, $v 会正确的指向每个元素。

总结

加不加 & ,本质的区别在于:

  • 不加 & 时:复制。在第一个例子中,会把迭代的元素值“复制”到 $v (注意 $v 指向了数组最后一个元素)
  • 加上 & 时:不复制,而是把 $v 改为指向迭代的元素。

换句话说:

  • 不加 & 时, $v 的内存地址不会变化,并把迭代的元素值复制过来:
    • 如果 $v 变量已经存在,则继续用它(第一个例子就是这种情况)
    • 如果 $v 变量不存在,则创建一个全新变量,后续迭代时,其内存地址不再变化
  • 加上 & 时, $v 不管是不是全新的变量,都会随着每次迭代,将其内存地址动态指向迭代的元素 ( $v 没有开辟另外的内存地址)。

何时使用&

原则:能不用 & 就不用,因为它增加了复杂度,可能会引起潜在的不易发现的问题。

比如一个函数的定义为 function func1($arr1) ,那我就可以放心的传一个数组进去,而不用担心该函数会修改我的数组。

& 常见的使用场景如下:

循环里修改元素值

foreach($arr1 as &$v) {$v++;
}unset($v);

函数内修改参数值

function swap(&$a, &$b) {$tmp = $a;$a = $b;$b = $tmp;
}

注:如果没记错,Pascal里,带不带 & ,分别叫做“值参”和“变参”。

function func1(&$arr1) { // 如果不带 & ,整个数组会被复制一份......$arr1[0]++;
}

注:PHP 5+ 对写时复制(Copy-On-Write)有优化,也就是说,即使是传值,也只有在确实有修改时,才会复制。因此,多数情况下,无需因为考虑性能而使用传引用的方式。

多个变量指向同一个内存地址

$a = 1;
$b = &$a; // $b 和 $a 指向同一个值
$b = 2;
echo $a; // 输出 2($a 也被修改)

函数返回引用

function &getSingleton() {static $instance = null;if ($instance === null) {$instance = new HeavyObject();}return $instance; // 返回引用,避免复制
}
$obj = &getSingleton(); // 必须用 & 接收

在链式API中,也经常需要返回原来的对象,而不能复制一个新对象。

http://www.dtcms.com/wzjs/361051.html

相关文章:

  • 太原做网站的网络工作室营销心得体会感悟300字
  • dedecms织梦系统网站防会员注册机网络营销师证书需要多少钱
  • 免费的旅游网站模板西安今日头条新闻
  • 网站开发科技公司网站网络优化外包
  • 关于推动门户网站建设d如何在百度上发布广告
  • 北京建站优化公司百度推广费用
  • 做设计一般用的素材网站是什么意思在线网页生成器
  • 郑州企业免费建站四川游戏seo整站优化
  • 公司电商网站建设方案模板营销软件哪个好
  • 天水做网站百度一下首页手机版
  • 淘宝网站首页怎么做网站优化网站
  • 国内男女直接做的视频网站新人做外贸怎么找国外客户
  • 石狮网站开发大连seo外包平台
  • 辽宁官方网站做辣白菜国家再就业免费培训网
  • java做的网站怎么设置关闭和开启网站访问不了色盲图
  • 网站设计制作上海收录网
  • 海口网球场网站seo快速排名优化的软件
  • 找题做的网站信息发布网站有哪些
  • 找新疆做网站的网页设计个人主页模板
  • 星锐网站建设温州云优化seo
  • 郑州网站制作案例网络公司名字大全
  • 订货网站开发价格奶盘seo伪原创工具
  • wordpress author 404常用的seo查询工具
  • 服务网站建设公司seo刷关键词排名免费
  • 门户网站开发费怎做账常州网站推广
  • 济南推广网站建设球队积分排名
  • 街舞舞团公司做网站网店运营实训报告
  • 网站建设五行属什么搜索优化软件
  • dw制作简单网站小程序开发制作
  • 桂林论坛网站建设如何免费做视频二维码永久