foreach next 操作数组指针移动问题
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 操作数组指针移动问题的更多相关文章
- PHP中使用数组指针函数操作数组示例
数组的内部指针是数组内部的组织机制,指向一个数组中的某个元素.默认是指向数组中第一个元素通过移动或改变指针的位置,可以访问数组中的任意元素.对于数组指针的控制PHP提供了以下几个内建函数可以利用. ★ ...
- php foreach 操作数组的代码
php foreach 操作数组的代码. foreach()有两种用法: foreach(array_name as $value) { statement; } 这里的array_na ...
- C语言数组和指针的理解_在取地址运算上的操作_指针加减操作_a 和&a 的区别
1.一个实例+理论分析 在了解数组和指针的访问方式前提下,下面再看这个例子: main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); pr ...
- C语言数组操作和指针操作谁更高效
在上一篇博文 代码优化小技巧(持续更新......) 第三条关于数组和指针谁更高效, 意犹未尽, 决定单独拉出一篇来讲 1. 数组和指针操作对比 #include <stdio.h> i ...
- 用数组指针遍历数组,FOR/FOREACH遍历数组
1. 用数组指针遍历一维数组 <?php header("Content-type:text/html;charset=utf-8"); /*用数组指针遍历一位数组的值*/ ...
- 陕西师范大学第七届程序设计竞赛网络同步赛 I 排队排队排队【数组任一位可以移动到队头,最少移动几次增序/数组指针操作】
链接:https://www.nowcoder.com/acm/contest/121/I来源:牛客网 题目描述 ACM竞赛队内要开运动会啦!!!! 竞赛队内的一群阳光乐观积极的队员们迅速的在操场上站 ...
- 慕课网-Java入门第一季-6-8 使用 foreach 操作数组
来源:http://www.imooc.com/code/1864 foreach 并不是 Java 中的关键字,是 for 语句的特殊简化版本,在遍历数组.集合时, foreach 更简单便捷.从英 ...
- 使用 foreach 操作数组
foreach 并不是 Java 中的关键字,是 for 语句的特殊简化版本,在遍历数组.集合时, foreach 更简单便捷.从英文字面意思理解 foreach 也就是“ for 每一个”的意思,那 ...
- Delphi 的内存操作函数(2): 给数组指针分配内存
静态数组, 在声明时就分配好内存了, 譬如: var arr1: ..] of Char; arr2: ..] of Integer; begin ShowMessageFmt('数组大小 ...
随机推荐
- 第29月第14天 evpp
1.evpp https://github.com/Qihoo360/evpp/tree/master/examples/recipes/self_control_timer https://blog ...
- 爬虫-通过本地IP地址从中国天气网爬取当前城市天气情况
1.问题描述 最近在做一个pyqt登录校园网的小项目,想在窗口的状态栏加上当天的天气情况,用爬虫可以很好的解决我的问题. 2.解决思路 考虑到所处位置的不同,需要先获取本地城市地址,然后作为中 ...
- react-native获取屏幕尺寸
项目中需要获取手机的尺寸 import {Dimensions} from "react-native" var WINDOW = Dimensions.get("win ...
- 038_nginx backlog配置
一. backlog=number sets the backlog parameter in the listen() call that limits the maximum length for ...
- 【easy】power of 2,3,4
============================== 2的幂次 ================================ 最佳解法 如果一个数是2的次方数的话,根据上面分析,那么 ...
- 快速搭建一个Spring Boot + MyBatis的开发框架
前言:Spring Boot的自动化配置确实非常强大,为了方便大家把项目迁移到Spring Boot,特意总结了一下如何快速搭建一个Spring Boot + MyBatis的简易文档,下面是简单的步 ...
- lnoi2019游记
好诡异的省选...... day0: 莫名其妙的订了下午从sy到dl的火车,得五点多才能到,所以.......是不需要试机的吗...... 好吧... 看着停课的jflr们,感觉他们好强啊,像我这种酱 ...
- Emacs Org-mode 3 表格
Org 使用内置的表格编辑器.可以进行简单的表格编写和计算. Org中的表格 第一个非空字符“|” 视为表格的起始位置,后面的“|” 视为字段分隔符. 3.1 生成表格 编写表格时,可以将字段先写好, ...
- 《学习之道》第八章孤军奋战or组队合作
孤军奋战与组队合作:别再苦思冥想,拖延行为需要差别对待 对拖延我得提一个小建议,你要暂时把自己与那些会干扰你的人和事隔离开.自己到一个房间里去,或者去图书馆,这样就没什么事能让你分心了. 如果一门课让 ...
- C#使用FileSystemWatcher控件实现的文件监控功能示例
本文实例讲述了C#使用FileSystemWatcher控件实现的文件监控功能.分享给大家供大家参考,具体如下: FileSystemWatcher 可以使用FileSystemWatcher组件监视 ...