2018年10月20日10:39:40

先说结论,foreach 维护的是一套属于自己的数组指针

会在操作数据的时候,分裂一套变量地址,即使你强制使用 & 取地址一样会分裂,不会引用同一套指针

所有在foreach的时候需要主动操作指针的时候,就会出现问题,很容易key超出变量的长度

测试demo

1,测试指针是否同步,会受到数组操作函数的影响

$a = [3,4,5,6,7];

foreach ($array as $k => $v) {
p($v);
p(next($array));
}

结果是不受影响,如果需要复杂指针操作就需要,自己移动指针,使用以下的方法

while(key($a)!==null){
echo key($a)."=>".current($a)."\n";
next($a);
}

对象指针操作参看

https://www.cnblogs.com/zx-admin/p/10430782.html

以下是一个实例

连续 加 减 乘 除

$parameter = [10, 20, 30, 40, 50, 60];
$rr = $parameter;
for ($i = 1; $i <= (count($rr) - 1 ); $i++) {
p($i);
reset($parameter);
$data_1 = current($parameter);
array_shift($parameter); $data_2 = current($parameter);
array_shift($parameter);
// if (!empty($data_2)) {
$res = bcdiv($data_1, $data_2, 2);
array_unshift($parameter, $res);
p($parameter);
}

封装过的方法

2019年1月2日12:07:01 经过修改过的方法

//多个参数 bc系列 加 减 乘 除 可扩展
if (!function_exists('multiple_parameters_bc')) {
/*
* add 加
* sub 减
* mul 乘
* div 除
*/ function multiple_parameters_bc($type = 'add', $accuracy = 2, ...$parameter) {
// pp($parameter);
//bc 对小数点位数不是四舍五入,先高精度计算最后对小数点位数四舍五入
// $calculation_accuracy 计算时保持的小数点精度 返回值保留的精度$accuracy
$calculation_accuracy = 10;
if (count($parameter) < 2) {
throw new \Exception('参数少于2个');
}
//防止数组操作导致循环次数异常
$temp = $parameter;
for ($i = 1; $i <= (count($temp) - 1 ); $i++) {
// p($i);
//保证指针一直指向数组第一个元素
reset($parameter);
//获取第一个元素
$data_1 = current($parameter);
array_shift($parameter);
//获取第二个元素
$data_2 = current($parameter);
array_shift($parameter); if ($type == 'add') {
$res = bcadd($data_1, $data_2, $calculation_accuracy);
} elseif ($type == 'sub') {
$res = bcsub($data_1, $data_2, $calculation_accuracy);
} elseif ($type == 'mul') {
// if ((int) $data_2 == 0) {
// throw new \Exception('被乘元素不能为0');
// }
$res = bcmul($data_1, $data_2, $calculation_accuracy);
} elseif ($type == 'div') {
if ((int) $data_2 == 0) {
throw new \Exception('被除元素不能为0');
}
$res = bcdiv($data_1, $data_2, $calculation_accuracy);
} else {
throw new \Exception('计算类型不识别');
}
//计算结果再次压入队首,循环继续使用
array_unshift($parameter, $res);
}
//加减不需要四舍五入,只需要截取小数位精度 ,乘除需要四舍五入
if ($type == 'add') {
return number_format($parameter['0'], $accuracy, '.', '');
} elseif ($type == 'sub') {
return number_format($parameter['0'], $accuracy, '.', '');
} elseif ($type == 'mul') {
return round($parameter['0'], $accuracy);
} elseif ($type == 'div') {
return round($parameter['0'], $accuracy);
} else {
throw new \Exception('计算类型不识别');
}
} }

经过测试没有什么问题,注意出发的时候,结果溢出,因为是没计算完就四舍五入,如果特殊需要,可以自己优化一下除法

修改版本1

function multiple_parameters_bc(string $type = '+', int $accuracy = 2, ...$parameter) {
// pp($parameter);
//bc 对小数点位数不是四舍五入,先高精度计算最后对小数点位数四舍五入
// $calculation_accuracy 计算时保持的小数点精度 返回值保留的精度$accuracy
$calculation_accuracy = 30;
if (count($parameter) < 2) {
throw new \Exception('参数少于2个');
}
//防止数组操作导致循环次数异常
$temp = $parameter;
for ($i = 1; $i <= (count($temp) - 1 ); $i++) {
// p($i);
//保证指针一直指向数组第一个元素
reset($parameter);
//获取第一个元素
$data_1 = current($parameter);
array_shift($parameter);
//获取第二个元素
$data_2 = current($parameter);
array_shift($parameter); if ($type == '+') {
$res = bcadd($data_1, $data_2, $calculation_accuracy);
} elseif ($type == '-') {
$res = bcsub($data_1, $data_2, $calculation_accuracy);
} elseif ($type == '*') {
// if ((int) $data_2 == 0) {
// throw new \Exception('被乘元素不能为0');
// }
$res = bcmul($data_1, $data_2, $calculation_accuracy);
} elseif ($type == '/') {
if ((int) $data_2 == 0) {
throw new \Exception('被除元素不能为0');
}
$res = bcdiv($data_1, $data_2, $calculation_accuracy);
} else {
throw new \Exception('计算类型不识别');
}
//计算结果再次压入队首,循环继续使用
array_unshift($parameter, $res);
}
//加减不需要四舍五入,只需要截取小数位精度 ,乘除需要四舍五入
if ($type == '+') {
return number_format($parameter['0'], $accuracy, '.', '');
} elseif ($type == '-') {
return number_format($parameter['0'], $accuracy, '.', '');
} elseif ($type == '*') {
return round($parameter['0'], $accuracy);
} elseif ($type == '/') {
return round($parameter['0'], $accuracy);
} else {
throw new \Exception('计算类型不识别');
}
}

参考

http://www.phppan.com/2013/04/foreach-exception/

https://blog.csdn.net/asty9000/article/details/82860124

foreach next 操作数组指针移动问题的更多相关文章

  1. PHP中使用数组指针函数操作数组示例

    数组的内部指针是数组内部的组织机制,指向一个数组中的某个元素.默认是指向数组中第一个元素通过移动或改变指针的位置,可以访问数组中的任意元素.对于数组指针的控制PHP提供了以下几个内建函数可以利用. ★ ...

  2. php foreach 操作数组的代码

    php foreach 操作数组的代码.   foreach()有两种用法:  foreach(array_name as $value)  {  statement;  }  这里的array_na ...

  3. C语言数组和指针的理解_在取地址运算上的操作_指针加减操作_a 和&a 的区别

    1.一个实例+理论分析 在了解数组和指针的访问方式前提下,下面再看这个例子: main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); pr ...

  4. C语言数组操作和指针操作谁更高效

    在上一篇博文  代码优化小技巧(持续更新......) 第三条关于数组和指针谁更高效, 意犹未尽, 决定单独拉出一篇来讲 1. 数组和指针操作对比 #include <stdio.h> i ...

  5. 用数组指针遍历数组,FOR/FOREACH遍历数组

    1. 用数组指针遍历一维数组 <?php header("Content-type:text/html;charset=utf-8"); /*用数组指针遍历一位数组的值*/ ...

  6. 陕西师范大学第七届程序设计竞赛网络同步赛 I 排队排队排队【数组任一位可以移动到队头,最少移动几次增序/数组指针操作】

    链接:https://www.nowcoder.com/acm/contest/121/I来源:牛客网 题目描述 ACM竞赛队内要开运动会啦!!!! 竞赛队内的一群阳光乐观积极的队员们迅速的在操场上站 ...

  7. 慕课网-Java入门第一季-6-8 使用 foreach 操作数组

    来源:http://www.imooc.com/code/1864 foreach 并不是 Java 中的关键字,是 for 语句的特殊简化版本,在遍历数组.集合时, foreach 更简单便捷.从英 ...

  8. 使用 foreach 操作数组

    foreach 并不是 Java 中的关键字,是 for 语句的特殊简化版本,在遍历数组.集合时, foreach 更简单便捷.从英文字面意思理解 foreach 也就是“ for 每一个”的意思,那 ...

  9. Delphi 的内存操作函数(2): 给数组指针分配内存

    静态数组, 在声明时就分配好内存了, 譬如: var   arr1: ..] of Char;   arr2: ..] of Integer; begin   ShowMessageFmt('数组大小 ...

随机推荐

  1. linux磁盘空间满?

    磁盘空间满啦 找到项目的logs文件夹 进入logs文件夹,会看到很多access.log*文件. 在Xshell里,输入命令cd 到项目节点的logs文件夹 可能还需要清空下回收站.

  2. 51nod 1035 最长的循环节

    正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数,假如存在多个最优的答案,输出所有答案中最大的那个数. 1/6= 0.1( ...

  3. “百度杯”CTF比赛 2017 二月场 爆破-3

    进入题目,题目源码: <?php error_reporting(0);session_start();require('./flag.php');if(!isset($_SESSION['nu ...

  4. 新手如何理解JS面向对象开发?

    今天有时间讲讲我对面向对象的理解跟看法,尽量用通俗的语言来表达,多多指教! 如今前端开发已经越来越火了,对于前端开发的要求也是越来越高了,在面试中,经常有面试官会问:你对JS面向对象熟悉吗? 其实,也 ...

  5. win7下安装linux(centos6.5)双系统详细小白教程

    在正式介绍linux安装教程之前,先声明一下本人也是刚开始接触linux,所以教程只以成功安装linux为目标,里面的具体步骤我都是参考网上的教程自己操作实现的,至于为什么要这么做就不多做解释,大家想 ...

  6. myeclipse安装spring插件

    1.查看 myeclipse 中的 eclipse 对应的版本 2.下载对应eclipse的 spring 插件 首先要安装spring插件,可以到spring官网下载  地址(https://spr ...

  7. centos/linux/ubuntu在局域网上网

    前言:对于服务器来说,一般不会安装windowns系统,都是会安装类unix系统,在局域网或者在内网中,上网还是走代理上网 1.知道代理服务器的ip及端口 2.就两条命令 export  http_p ...

  8. jetbrains的JetBrains PyCharm 2018.3.1破解激活到2100年(最新亲测可用)

    破解补丁激活 之前看了好多的其它的方法感觉都不是很靠谱还是这个本人亲试可以长期有效不仅能激活pycharm.jetbrains的JetBrains PyCharm 2018.3.1破解激活到2100年 ...

  9. [转]一个普通IT人的十年回顾---金旭亮

    金旭亮老师十年体会,很有收获.转自网络. 金旭亮于1989年与超级解霸的开发者梁肇新同时迈入广西大学的校门,却走了一条与其不同的路. 1994年起开始自学计算机专业本科课程,并开始编程,从未间断,迄今 ...

  10. 527D.Clique Problem

    题解: 水题 两种做法: 1.我的 我们假设$xi>xj$ 那么拆开绝对值 $$xi-w[i]>x[j]+w[j]$$ 由于$w[i]>0$,所以$x[i]+w[i]>x[j] ...