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. Windows 下 exe 服务注册到 service 服务中

    window 下注册 exe 程序.添加到 服务中. window 注册服务方式 一. regsvr 方式 直接在 程序目录执行: Regsvr 32 命令是Windows中控件文件 ( 如扩展名为D ...

  2. ThetaSome_ThetaAll子查询

    基本语法 表达式 θ some(子查询) 表达式 θ all (子查询) 语法中,θ是比较运算符 <,>,>=,<=,=,<> 如果表达式的值至少与子查询的结果的某 ...

  3. HttpUtility.UrlEncode编码重写

    1. 某些系统方法,例如.NET系统方法HttpUtility.UrlEncode会将‘=’编码成‘%3d’,而不是%3D,导致加密签名通不过验证,请开发者注意检查. 2.Java 1.3和早期版本中 ...

  4. html 超链接标签 锚点 a标签伪类

    一个简易的连接 <a href="01.html">01</a> <body> <a href="01.html" t ...

  5. pythonのdjango CSRF简单使用

    一.简介 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防跨站请求伪造功 ...

  6. POJ 3190

    POJ3190                               摊位预订.时间限制:1000MS内存限制:65536K.共提交材料:12959份接受:4 546名特别法官.描述. 哦,那些 ...

  7. mysql索引与查询优化

    索引加锁 对于InnoDB来说,索引可以让查询锁住更少的行,从而可以在并发情况下拥有更佳表现. 下面演示一下查询锁与索引之间的关系. 前面使用的t_user_action_log表目前有一个id为主键 ...

  8. 【算法】【python实现】二叉树深度、广度优先遍历

    二叉树的遍历,分为深度优先遍历,以及广度优先遍历. 在深度优先遍历中,具体分为如下三种: 先序遍历:先访问根节点,再遍历左子树,再遍历右子树: 中序遍历:先遍历左子树,再访问根节点,再遍历右子树: 后 ...

  9. Jquery点击div之外的地方隐藏当前div

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script sr ...

  10. Niagara workbench (Basic )

    1.the basic information about workbench Last saved  station open in the workbench or opened  another ...