我在C语言中尝试使用二分法来找到某些方程的根,但是当我尝试在文件中编写此过程的每一步时,我得到的问题是“分段错误”。这可能是我做过的一个蠢事,但是我一直试图解决这个问题很长一段时间。我正在使用gcc进行编译,这就是代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define R 1.0
#define h 1.0
double function(double a);
void attractor(double *a1, double *a2, double *epsilon);
void attractor(double *a1, double *a2, double *epsilon)
{
FILE* bisection;
double a2_copia, a3, fa1, fa2;
bisection = fopen("bisection-part1.txt", "w");
fa1 = function(*a1);
fa2 = function(*a2);
if(function(*a1) - function(*a2) > 0.0)
*epsilon = function(*a1) - function(*a2);
else
*epsilon = function(*a2) - function(*a1);
fprintf(bisection, "a1 a2 fa1 fa2 epsilon\n");
a2_copia = 0.0;
if(function(*a1) * function(*a2) < 0.0 && *epsilon >= 0.00001)
{
a3 = *a2 - (*a2 - *a1);
a2_copia = *a2;
*a2 = a3;
if(function(*a1) - function(*a2) > 0.0)
*epsilon = function(*a1) - function(*a2);
else
*epsilon = function(*a2) - function(*a1);
if(function(*a1) * function(*a2) < 0.0 && *epsilon >= 0.00001)
{
fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", *a1, *a2, function(*a1), function(*a1), *epsilon);
attractor(a1, a2, epsilon);
}
else
{
*a2 = a2_copia;
*a1 = a3;
if(function(*a1) - function(*a2) > 0)
*epsilon = function(*a1) - function(*a2);
else
*epsilon = function(*a2) - function(*a1);
if(function(*a1) * function(*a2) < 0.0 && *epsilon >= 0.00001)
{
fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", *a1, *a2, function(*a1), function(*a1), *epsilon);
attractor(a1, a2, epsilon);
}
}
}
fa1 = function(*a1);
fa2 = function(*a2);
if(function(*a1) - function(*a2) > 0.0)
*epsilon = function(*a1) - function(*a2);
else
*epsilon = function(*a2) - function(*a1);
fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", a1, a2, fa1, fa2, epsilon);
}
double function(double a)
{
double fa;
fa = (a * cosh(h / (2 * a))) - R;
return fa;
}
int main()
{
double a1, a2, fa1, fa2, epsilon;
a1 = 0.1;
a2 = 0.5;
fa1 = function(a1);
fa2 = function(a2);
if(fa1 - fa2 > 0.0)
epsilon = fa1 - fa2;
else
epsilon = fa2 - fa1;
if(epsilon >= 0.00001)
{
fa1 = function(a1);
fa2 = function(a2);
attractor(&a1, &a2, &epsilon);
fa1 = function(a1);
fa2 = function(a2);
if(fa1 - fa2 > 0.0)
epsilon = fa1 - fa2;
else
epsilon = fa2 - fa1;
}
if(epsilon < 0.0001)
printf("Vanish at %f", a2);
else
printf("ERROR");
return 0;
}
非常感谢,如果这个问题不合适,我很抱歉。
答案 0 :(得分:2)
下面
fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", a1, a2, fa1, fa2, epsilon);
您正在传递double*
个参数而不是预期的double
。应该是
fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", *a1, *a2, fa1, fa2, *epsilon);
代替。
答案 1 :(得分:1)
您有太多打开的文件。您以递归方式调用attractor
,每次调用都将打开文件bisection-part1.txt
。失败时fopen
会返回NULL
。程序终止时出现分段错误,因为您尝试使用NULL
文件描述符。
您需要打开一次文件并将其文件描述符传递给attractor
函数:
void attractor(FILE *bisection, double *a1, double *a2, double *epsilon) { ... }
完成后,您还应该使用fclose
关闭所有文件。
打开文件数量限制通常为1024.可以通过执行ulimit -n
打印。
如果所有fprintf
调用都替换为printf
,则程序将耗尽堆栈空间,因此会以分段错误终止。该程序耗尽堆栈空间,因为函数attractor
的递归级别太高。