C++中如何从二分法函数提取存储迭代点的两个数组
解决二分法迭代点数组提取的问题
我看了你的代码,问题主要出在数组参数的传递方式以及函数调用时的传参错误上,这导致你无法正确把迭代过程中的a、b值存储到数组里。下面是具体的修正方案和解释:
第一步:修正二分法函数的参数定义
C++中,数组作为函数参数传递时,不需要用引用(数组会自动退化为指针),你原来的double &points_a[],double &points_b[]写法是错误的,应该改成:
double dihotom(double a, double b, double e, double(*fp)(double), int &iter, double points_a[], double points_b[])
或者更清晰的指针写法(效果完全一致):
double dihotom(double a, double b, double e, double(*fp)(double), int &iter, double* points_a, double* points_b)
第二步:修正main函数中的调用方式
你调用dihotom时传的points_a[3]和points_b[3]是数组的越界元素(数组下标从0开始,points_a[3]是第4个元素,超出了你定义的double points_a[3]的范围),应该直接传递数组名,让它自动退化为指针:
double k3 = dihotom(0.5, 1, 0.0001, f3, int_s, points_a, points_b);
第三步:优化迭代逻辑(可选)
你原来用公式计算的iter是理论迭代次数,但实际循环的it是真实执行的次数,建议把iter设置为实际迭代次数,这样输出更准确;同时添加数组边界判断,避免存储时越界:
// 注释掉原来的理论迭代次数计算,循环结束后赋值实际次数 // iter=(log10((b-a)/e))/log10(2); // ... do{ // 循环内逻辑不变 it++; // 加k<3判断,防止超出数组存储上限 if(it == step_current && k < 3){ points_a[k] = a; points_b[k] = b; k++; step_current += step; } // ... }while (fabs(a-b)>=e); iter = it; // 传递实际迭代次数
完整修正后的代码
#include <stdio.h> #include <math.h> #include <stdlib.h> double f1(double x){ return x*x-5*sin(x); } double f2(double x){ return exp(x)-pow(10,x); } double f3(double x){ return sin(x)-x+0.15; } double f4(double x){ return x-pow(9+x,0.5)+x*x-4; } double dihotom(double a, double b, double e, double(*fp)(double), int &iter, double points_a[], double points_b[]){ double c, fc, fa = fp(a); int it = 0; int k = 0; // 计算理论迭代次数用于分步存储 int theoretical_iter = (log10((b-a)/e))/log10(2); int step = theoretical_iter / 3; int step_current = step; do{ c = (a + b)/2; fc = fp(c); if (fa * fc <= 0) b = c; else a = c; it++; // 存储指定步骤的a、b值,同时避免数组越界 if(it == step_current && k < 3){ points_a[k] = a; points_b[k] = b; k++; step_current += step; } fa = fp(a); printf("it %d: a = %lf,b = %lf\n", it, a, b); }while (fabs(a - b) >= e); iter = it; // 传递实际执行的迭代次数 return c; } int main(int argc, char *argv[]) { int int_s = 0; double points_a[3]; double points_b[3]; // 初始化数组,避免未赋值的垃圾值输出 for(int i=0; i<3; i++){ points_a[i] = 0.0; points_b[i] = 0.0; } double k3 = dihotom(0.5, 1, 0.0001, f3, int_s, points_a, points_b); printf("For F3 - root = %lf, F3(%.2lf)=%lf ;iter =%d\n", k3, k3, f3(k3), int_s); for(int i=0; i<3; i++){ printf("step : %d , a: %lf, b: %lf\n", i, points_a[i], points_b[i]); } return 0; }
关键修改点总结
- 修正了数组参数的传递方式,让函数能正确操作main函数中定义的数组
- 修复了函数调用时的数组越界传参问题
- 添加了
k<3的判断,防止存储时超出数组范围 - 将
iter设置为实际迭代次数,让输出更准确 - 初始化数组避免输出未赋值的垃圾值
这样修改后,你就能正确提取并输出迭代过程中指定步骤的a和b值了。
内容的提问来源于stack exchange,提问作者user17059077
相关产品推荐
相关产品推荐

