那一天,人类终于回想起被C语言支配的恐惧
Bug出现情景:哎,这个bug出现在printf中,打印一个double小数,大概在10-7左右。
Bug 完整的信息:Expression: (“unexpected input value; log10 failed”, 0)
出现的语句为:printf("一次运行时长:%6.2e\n",duration);
已解决Bug的正确完整代码——可用于计算同一问题的不同算法的单次运行时间
#include<stdio.h>
#include<time.h>
#include<math.h>
#include<stdlib.h>
#pragma warning(disable : 4996)
//函数指针定义
typedef double(*P)(int,double[],double);
//全局变量声明
clock_t start, stop; //开始计时打点数,终止计时打点数 clock tick
double duration; //函数单次运行时间长度
#define MAXN 10 //常数项系数个数
#define MAXK 1e7 //函数多次循环次数
//算法1——累加,多次方乘积
double f1(int n, double a[], double x) {
int p = a[0];
for (int i = 1; i < n; i++)
p += (a[i] * pow(x, i));
return p;
}
//算法2——加法,乘积
double f2(int n, double a[], double x) {
int p = a[n];
for (int i = n; i > 0; i--)
p = a[i - 1] + x * p;
return p;
}
//优化后的,算法执行时间计算函数
void calculateTime(int n,double a[],double x,double TestFunction(int,double[],double)) {
start = clock();
double p = 0;
for (int i = 0; i < MAXK; i++)
p = TestFunction(n,a,x);
stop = clock();
duration = (double)(stop - start) / CLK_TCK / MAXK ;
printf("运行总打点数:%d\n",stop - start);
printf("一次运行时长:%6.2e\n",duration);
}
//主函数
int main() {
//打印本机 每秒所走的时钟打点数
//printf("CLK_TCK:%d\n", CLK_TCK);
double a[MAXN];
for (int i = 0; i < MAXN; i++)
a[i] = (double)i;
calculateTime(MAXN - 1, a, 2,f1);
calculateTime(MAXN - 1, a, 2,f2);
return 0;
}
Bug原因总结
C很牛逼,C的return返回值如果不接住,就直接写入内存,不销毁不清除数据,哈哈哈,错误原因在于两个return double的算法f1、f2与calculate函数。
double f1(int n, double a[], double x) {
return p;
}
double f2(int n, double a[], double x) {
return p;
}
//在下面的calculateTime函数中,如果没有复制给一个double局部变量,就会出现本bug
void calculateTime(int n,double a[],double x,double TestFunction(int,double[],double))
{
...
for (int i = 0; i < MAXK; i++)
TestFunction(n,a,x);
...
}
TestFunction(n,a,x);这个函数的返回值,会占满这个进程的所拥有的内存空间,然后造成脏数据存在。而在printf duration变量的时候,就会导致,有乱七八糟的字符被读入到printf函数中。
也就是——unexpected input value
,我吐了,你萌呢