C语言程序程序稳定性测试

(1)设计一个自动数据生成程序,能自动生成指定行数的随机整数并写入到一个文件当中,随机整数的范围可以被控制,例如控制在0 到100 间,这个程序的操作命令行参数如:d:>intgen.exe data1.txt 0 100 7777, 程序意味着产生0-100 之间的随机数共7777 个,并写入输出文件data1.txt中, 每行1 个数据, 共7777 行,程序执行完毕以后打开data1.txt 观察一下数据以及格式是否正确;
在C 语言中,rand() 可以用来产生随机数,但是这不是真正意义上的随机数,是一个伪随机数,我们称它为种子,他是以某一个递推公式推出来的一系列数,当这个数很大的时候,就符
合正态分布,当计算机开机后,这个种子的值就定了,非你破坏了系统,为改变这给种子的值,C 提供了srand() 函数,它的原形是void srand(inta)。rand 产生的随机数从0 到rand-max,
rand-max 定义在stdlib.h,其值至少为32767. 在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand() 在调用时会自动设随机数种子为1,一般用for语句来设置种子的个数。从x 到y,有y-x+1 个随机数,产生从x 到y 的数只需要下面代码中第25 行代码k=rand()%(y-x+1)+x;。
自动生成7777 个0-100 间的随机数代码intgen.c 如下:

#include <stdlib.h>
#include <stdio.h>
#include <time.h> //设置时钟种子
int main(int argc,char*argv[])
{int i;
int k;//存放随机数
int a;//产生随机数个数
int x;//随机数区间起点
int y;//随机数区间终点
sscanf(argv[2],"%d",&x); //argv[]是字符串格式,sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。从一个字符串中读进与指定格式相符的数据
sscanf(argv[3],"%d",&y);
sscanf(argv[4],"%d",&a);
FILE*fp2;//文件指针表示的写入流
if (argc!=5){printf("参数输入不正确!");  printf("提示:命令 输出文件 随机数区间起点 随机数区间终点 随机数个数");}
srand( (unsigned)time( NULL ) );{fp2=fopen(argv[1],"w");//打开并写入参数argv[1]对应的输出文件,与“w”相比“a”也可以写入文件,但是写之前文件不进行格式化 for( i = 0; i < a; i++ ){k=rand()%(y-x+1)+x;//printf( "产生随机数:%d\n", k);fprintf(fp2,"%d\n",k);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容} }
fclose(fp2);
if (fclose(fp2)!=0);{printf("文件 %s\n 关闭错误",argv[1]);}
}
//验证:
//gcc intgen.c -o intgen.exe
//intgen.exe data1.txt 0 100 7777

生成随机数运行结果如下图写完数据后已经采用fclose(fp2) 关闭写入流,但是提示文件未关闭成功。

(2)将生成的数据文件data1.txt 作为p.exe 的输入数据文件执行计算,例如:d:>p.exe data1.txt data2.txt 7,这样将输入数据的7 次方计算结果输出到data2.txt;
代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc,char*argv[])
{FILE*fp1,*fp2;//文件指针表示的两个流if (argc!=4){printf("参数输入不正确!");   printf("提示:命令 输入文件 输出文件 幂次");}if(fp1==NULL){printf("输入文件打开失败");return 0;}fp1=fopen(argv[1],"r");//打开并读取参数argv[1]对应的输入文件int a,c, i=0,j=0;int lines = 0; //行数int temp;//用于求幂float x,y;//x为输入的数字,y为输出的数字//fp2=fopen(argv[2],"w");//打开并写入参数argv[2]对应的输出文件,与“w”相比“a”也可以写入文件,但是写之前文件不进行格式化//检测行数//while((c = fgetc(fp1))!= EOF){if(c=='\n') lines++; } lines = lines+1; fclose(fp1);int data[ lines ]; //存放运算结果 char sdigit [ lines*2]; //检测格式数组//判断文件格式/    fp1=fopen(argv[1],"r");//打开并读取参数argv[1]对应的输入文件while(!feof(fp1))//feof本身是一个非负的整型常量,表明以达到文件末尾{fscanf(fp1,"%s",sdigit);for(j=0;sdigit[j];++j){if(isdigit(sdigit[j])){//x=sdigit[j];//y=pow(x,3);//fprintf(fp2,"%f\n",y);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容}//返1else{printf("文件中有字母或汉字");//fprintf(fp2,"%c\n",sdigit[j]);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容  exit(0);}}}fclose(fp1);//写入文件///float x,y;//x为输入的数字,y为输出的数字fp1=fopen(argv[1],"r");//打开并读取参数argv[1]对应的输入文件fp2=fopen(argv[2],"w");//打开并写入参数argv[2]对应的输出文件,与“w”相比“a”也可以写入文件,但是写之前文件不进行格式化while(!feof(fp1))//feof本身是一个非负的整型常量,表明以达到文件末尾{fscanf(fp1,"%f\n",&x);//格式化的文件输入,读入并且赋值给实际参数,从第一个参数fp1指定的流中读入内容//scanf("%d",&x);//总是从标准输入流stdin中读入内容//y=x*x*x;//计算x的三次方sscanf(argv[3],"%d",&temp); //argv[3]是字符串格式,sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。从一个字符串中读进与指定格式相符的数据printf("temp:%d",temp);data[i]=pow(x,temp);printf("data[%d]:%d",i,data[i]);//fprintf(fp2,"%f\n",y);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容//prinf("%d",&y);//总是从标准输入流stdin中输出内容fprintf(fp2,"%d\n",data[i]);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容i++;}fclose(fp1);fclose(fp2);return 0;if (fclose(fp1)!=0);//关闭文件成功关闭则返回值为0{printf("文件 %s\n 关闭错误",argv[1]);}if (fclose(fp2)!=0);{printf("文件 %s\n 关闭错误",argv[2]);}
}

将生成的0-100 的随机数进行7 次方的计算时输出文件如图:

发现所有输出结果相同,猜测是计算后数据溢出,采用整型变量int 存储其取值范围为-32768 到32767,超出这个范
围就不能储存,在编译解决一些实际问题时,可定义一些无符号数据类型节省数据空间即可将 int 型改为unsigned int, 此时存储范围为0 到65535。或者实用长型long int(简写为long) 替代 int,甚至是unsigned long int、unsigned long long int 使数据空间更大。k 考虑到100 的7 次方数值范围为10 的14 次方化为二进制约为2 的47 次方即需要至少47 位二进制表示,故要选用
unsigned long int 或long long int 来定义数据类型,也可以采用double 型(比特数为64 位)。
通过代码调试证明了上图乱码原因是数据类型定义不正确造成的,改进后计算结果如下图:

(3)将输入文件数据扩展到10 万行, 测试p.exe 是否还能正确的执行计算并输出结果;
执行intgen.exe data1.txt 0 100 100000 命令,产生10 万行的随机数据的文件data1.tex 如下图:

将生成的10 万行0-100 的随机数测 p.exe,进行7 次方的计算时输出文件如下图:
(4)修改计算程序p.exe 的源代码, 加入执行时间的计算,从而能够输出程序的计算时间, 针对输入数据文件100 行,1000 行,1 万行,10 万行等得出程序计算的消耗时间结果;
C 语言程序的运行时间,一般采用两种方法,一种是精确到毫秒时间,一种是精确到微妙时间,精确到微秒时间原理是CPU 次数除以频率,用到函数包#includewindows.h<>函数包,精确到毫秒时间用到函数包#includetime.h<>函数包里的clock() 函数,修改计算程序p.exe 的源代码,精确到微秒级编译生成p4.exe,精确到毫秒秒级编译生成p5.exe,为了方便下题绘图,分别将p4.exe 与p5.exe 不同行数的数据运行时间写入time1.txt 与time2.txt 中。
在p.c 中加入执行时间计算函数,对程序运行时间进行计时(p4.c 中的9-16 行、83-86 行),以及创建了一个运行时间的输入流,将每次运行时间输入到time1.txt 中(p4.c 中的86-87 行),微秒级编译代码p4.c 如下所示:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include <ctype.h>
#include <stdlib.h>
#include <Windows.h>
int main(int argc,char*argv[])
{double run_time;LARGE_INTEGER time_start;  //开始时间LARGE_INTEGER time_over;  //结束时间double dqFreq;        //计时器频率LARGE_INTEGER f; //计时器频率QueryPerformanceFrequency(&f);dqFreq=(double)f.QuadPart;QueryPerformanceCounter(&time_start);   //计时开始FILE*fp1,*fp2,*fp3;//文件指针表示的两个流if (argc!=4){printf("参数输入不正确!"); printf("提示:命令 输入文件 输出文件 幂次");}if(fp1==NULL){printf("输入文件打开失败");return 0;}fp1=fopen(argv[1],"r");//打开并读取参数argv[1]对应的输入文件int a,c, i=0,j=0;int lines = 0; //行数int temp;//用于求幂float x,y;//x为输入的数字,y为输出的数字//fp2=fopen(argv[2],"w");//打开并写入参数argv[2]对应的输出文件,与“w”相比“a”也可以写入文件,但是写之前文件不进行格式化//检测行数//while((c = fgetc(fp1))!= EOF){if(c=='\n') lines++; } lines = lines+1; fclose(fp1);double data[ lines ]; //存放运算结果 char sdigit [ lines*2]; //检测格式数组//判断文件格式/ fp1=fopen(argv[1],"r");//打开并读取参数argv[1]对应的输入文件while(!feof(fp1))//feof本身是一个非负的整型常量,表明以达到文件末尾{fscanf(fp1,"%s",sdigit);for(j=0;sdigit[j];++j){if(isdigit(sdigit[j])){//x=sdigit[j];//y=pow(x,3);//fprintf(fp2,"%f\n",y);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容}//返1else{printf("文件中有字母或汉字");//fprintf(fp2,"%c\n",sdigit[j]);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容  exit(0);}}}fclose(fp1);//写入文件///float x,y;//x为输入的数字,y为输出的数字fp1=fopen(argv[1],"r");//打开并读取参数argv[1]对应的输入文件fp2=fopen(argv[2],"w");//打开并写入参数argv[2]对应的输出文件,与“w”相比“a”也可以写入文件,但是写之前文件不进行格式化while(!feof(fp1))//feof本身是一个非负的整型常量,表明以达到文件末尾{fscanf(fp1,"%f\n",&x);//格式化的文件输入,读入并且赋值给实际参数,从第一个参数fp1指定的流中读入内容//scanf("%d",&x);//总是从标准输入流stdin中读入内容//y=x*x*x;//计算x的三次方sscanf(argv[3],"%d",&temp); //argv[3]是字符串格式,sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。从一个字符串中读进与指定格式相符的数据data[i]=pow(x,temp);//fprintf(fp2,"%f\n",y);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容//prinf("%d",&y);//总是从标准输入流stdin中输出内容fprintf(fp2,"%f\n",data[i]);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容i++;}QueryPerformanceCounter(&time_over);    //计时结束run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;//乘以1000000把单位由秒化为微秒,精度为1000 000/(cpu主频)微秒printf("\nrun_time:%fus\n",run_time);fp3=fopen("time1.txt","a");//打开并写入time1.txt输出文件,与“w”相比“a”也可以写入文件,但是写之前文件不进行格式化fprintf(fp3,"%f\n",run_time);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容return 0;fclose(fp1);fclose(fp2);fclose(fp3);return 0;if (fclose(fp1)!=0);//关闭文件成功关闭则返回值为0{printf("文件 %s 关闭错误",argv[1]);}if (fclose(fp2)!=0);{printf("文件 %s关闭错误",argv[2]);}if (fclose(fp3)!=0);{printf("文件time1.txt关闭错误");}
}
/
//验证
//gcc p4.c -o p4.exe
//gcc intgen.c -o intgen.exe
//intgen.exe data1.txt 0 100 100
//p4.exe data1.txt data2.txt 7
//intgen.exe data1.txt 0 100 1000
//p4.exe data1.txt data2.txt 7
//intgen.exe data1.txt 0 100 10000
//p4.exe data1.txt data2.txt 7
//intgen.exe data1.txt 0 100 100000
//p4.exe data1.txt data2.txt 7

对代码进行验证一,产生100 行随机数据,计算7 次方后输出运行时间如图:

对代码进行验证二,产生1000 行随机数据,计算7 次方后输出运行时间如图:

对代码进行验证三,产生1 万行随机数据,计算7 次方后输出运行时间如图:

对代码进行验证四,产生1 万行随机数据,计算7 次方后输出运行时间如图:

输出的time1.txt 文件如图:

对10 万行的数据反复执行发现每次时间有很大偏差,产生这种结果的原因是程序调用系统
CPU 并且现在CPU 支持动态调频,所以运行时间也有所不同。

在p.c 中加入执行时间计算函数clock();,对程序运行时间进行计时(p5.c 中的9-16 行、83-86 行),以及创建了一个运行时间的输入流,将每次运行时间输入到time2.txt 中(p5.c 中的86-87 行),微秒级编译代码p5.c 如下所示:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include <ctype.h>
#include <stdlib.h> //用到rand()函数
#include<time.h>   //用到clock()函数
int main(int argc,char*argv[])
{double begintime,endtime,run_time;begintime=clock();  //计时开始FILE*fp1,*fp2,*fp3;//文件指针表示的两个流if (argc!=4){printf("参数输入不正确!"); printf("提示:命令 输入文件 输出文件 幂次");}if(fp1==NULL){printf("输入文件打开失败");return 0;}fp1=fopen(argv[1],"r");//打开并读取参数argv[1]对应的输入文件int a,c, i=0,j=0;int lines = 0; //行数int temp;//用于求幂float x,y;//x为输入的数字,y为输出的数字//fp2=fopen(argv[2],"w");//打开并写入参数argv[2]对应的输出文件,与“w”相比“a”也可以写入文件,但是写之前文件不进行格式化//检测行数//while((c = fgetc(fp1))!= EOF){if(c=='\n') lines++; } lines = lines+1; fclose(fp1);double data[ lines ]; //存放运算结果 char sdigit [ lines*2]; //检测格式数组//判断文件格式/ fp1=fopen(argv[1],"r");//打开并读取参数argv[1]对应的输入文件while(!feof(fp1))//feof本身是一个非负的整型常量,表明以达到文件末尾{fscanf(fp1,"%s",sdigit);for(j=0;sdigit[j];++j){if(isdigit(sdigit[j])){//x=sdigit[j];//y=pow(x,3);//fprintf(fp2,"%f\n",y);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容}//返1else{printf("文件中有字母或汉字");//fprintf(fp2,"%c\n",sdigit[j]);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容  exit(0);}}}fclose(fp1);//写入文件///float x,y;//x为输入的数字,y为输出的数字fp1=fopen(argv[1],"r");//打开并读取参数argv[1]对应的输入文件fp2=fopen(argv[2],"w");//打开并写入参数argv[2]对应的输出文件,与“w”相比“a”也可以写入文件,但是写之前文件不进行格式化while(!feof(fp1))//feof本身是一个非负的整型常量,表明以达到文件末尾{fscanf(fp1,"%f\n",&x);//格式化的文件输入,读入并且赋值给实际参数,从第一个参数fp1指定的流中读入内容//scanf("%d",&x);//总是从标准输入流stdin中读入内容//y=x*x*x;//计算x的三次方sscanf(argv[3],"%d",&temp); //argv[3]是字符串格式,sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。从一个字符串中读进与指定格式相符的数据data[i]=pow(x,temp);//fprintf(fp2,"%f\n",y);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容//prinf("%d",&y);//总是从标准输入流stdin中输出内容fprintf(fp2,"%f\n",data[i]);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容i++;}endtime = clock(); //计时结束run_time=endtime-begintime;printf("\nrun_time::%fms\n", run_time);fp3=fopen("time2.txt","a");//打开并写入time2.txt输出文件,与“w”相比“a”也可以写入文件,但是写之前文件不进行格式化fprintf(fp3,"%f\n",run_time);//格式化的文件输出,读入并且赋值给实际参数,从第一个参数fp2指定的流中输出内容return 0;fclose(fp1);fclose(fp2);fclose(fp3);return 0;if (fclose(fp1)!=0);//关闭文件成功关闭则返回值为0{printf("文件 %s\n 关闭错误",argv[1]);}if (fclose(fp2)!=0);{printf("文件 %s\n 关闭错误",argv[2]);}if (fclose(fp3)!=0);{printf("文件time1.txt关闭错误");}
}
/
//验证
//gcc p5.c -o p5.exe
//gcc intgen.c -o intgen.exe
//intgen.exe data1.txt 0 100 100
//p5.exe data1.txt data2.txt 7
//intgen.exe data1.txt 0 100 1000
//p5.exe data1.txt data2.txt 7
//intgen.exe data1.txt 0 100 10000
//p5.exe data1.txt data2.txt 7
//intgen.exe data1.txt 0 100 100000
//p5.exe data1.txt data2.txt 7

对代码进行和微秒级相同的验证,计算7 次方后输出运行时间如图:

对比time1.txt 与time2.txt 的计时数据发现,当程序计算复杂度越低时,毫秒级的计时程序计时误差越大,并且程序计算复杂度小到一定程度时,输出计算时间为0。
毫秒级计时随机数据的7 次方运行时间如图:

毫秒级计时随机低复杂度计算运行时间如图:


采用matlab 绘制运行时间图像,代码及绘制图像如图:

c语言学习进阶-C语言程序稳定性测试相关推荐

  1. c语言学习进阶-C语言程序产生正态分布随机数

    C语言程序产生正态分布随机数 目录 C语言程序产生正态分布随机数 **中心极限定理(大数定理)** **Hasiting有理逼近法:** **反函数产生给定分布的随机数法:** **Box-Mulle ...

  2. c语言学习进阶-C语言程序出错处理

    C语言程序出错处理 命令行参数实现C语言程序出错处理 (1)执行d:>p.exe myinput.txt myoutput.txt 时,如果指定的文件名myinput.txt 不存在,那么程序应 ...

  3. c语言学习进阶-C语言程序性能优化

    标题C语言程序性能优化 (1)进一步提升程序的计算能力.使之能计算任意实数的任意次方的输出结果,我们 将计算的次方数也放在命令行参数中,作为第3 个命令行参数,例如:d:>p.exe input ...

  4. c语言学习进阶-C语言程序实现生成指定区间指定个数随机数

    ##C语言程序实现生成指定区间指定个数随机数 设计一个自动数据生成程序,能自动生成指定行数的随机整数并写入到一个文件当中,随机整数的范围可以被控制,例如控制在0 到100 间,这个程序的操作命令行参数 ...

  5. c语言学习进阶-C语言程序实现矩阵乘法

    (1)设矩阵A 的数据放在A.txt 中,B 矩阵数据放在B.txt 中,这两个矩阵的相乘结果放 在C.txt 中,执行程序:d:>cf.exe A.txt B.txt C.txt 则将结果输出 ...

  6. c语言学习进阶-C语言带命令行参数的文件数据批量计算

    C语言带命令行参数的文件数据批量计算 (1)假设输入文件中的数据为多行整数,把数据文件命名为"InputData.txt",也可以命名为任意的文件名,尝试设计一个c 语言程序, 主 ...

  7. Python语言学习:python语言的特点、入门、基础用法之详细攻略

    Python语言学习:python语言的特点.入门.基础用法之详细攻略 相关内容 Python 基础教程 目录 python语言的特点 python语言的入门 python语言的基础用法 python ...

  8. C语言学习笔记---001C语言的介绍,编译过程原理,工具等

    C语言学习笔记---001C语言的介绍,编译过程原理,工具等 创梦技术交流平台:资源下载,技术交流,网络赚钱: 交流qq群:1群:248318056 2群:251572072 技术交流平台:cre.i ...

  9. Python语言学习:python语言代码调试—异常处理之详细攻略

    Python语言学习:python语言代码调试-异常处理之详细攻略 目录 python语言代码调试-异常处理 异常捕捉可以使用 try/except 语句 相关文章 Python3 错误和异常 | 菜 ...

最新文章

  1. 缓存雪崩缓存击穿缓存穿透的本质
  2. Java学习笔记:内部类/匿名内部类的全面介绍
  3. 如何用web3.js在以太坊区块链上保存数据?
  4. ufldl学习笔记与编程作业:Multi-Layer Neural Network(多层神经网络+识别手写体编程)...
  5. OpenWrt 学习网址
  6. python opencv 学习笔记
  7. Madwifi Mad coding:自底向上分析associated_sta的更新过程 —— RSSI和MACADDR等信息获取的底层原理...
  8. postman 测试excel下载_使用Postman轻松实现接口数据关联
  9. 零基础学启发式算法(1)-贪心算法(Greedy Algorithm)
  10. Nginx伪静态配置和常用Rewrite伪静态规则
  11. vs编译时出现大量ws2def.h的错误的解决方法
  12. 运放的电压比较器电路
  13. 你看,那个人好像一条狗啊~30岁以上的程序员该何去何从?
  14. 有趣的开源软件:语音识别工具Kaldi (一)
  15. 如何用C语言将华氏温度转化为摄氏温度
  16. 变频无线发射机系统电路设计详解
  17. 学习逆向某风控id分析
  18. 网站建设的基本步骤有哪些
  19. Spring入门自学
  20. OPengl学习(二)——opengl环境搭建

热门文章

  1. 未来五年程序员应当具备的十项技能
  2. catia怎么将特征参数化_浅谈Catia VBA与参数化建模的结合
  3. go excel换行符替换_微软Excel与WPS Excel哪个好玩?
  4. windows系统下修改mysql时区_Linux与Windows下修改MySql时区的方法
  5. python123手机版math库-python学习笔记---math,random,operator(三)
  6. 引导linux的工具下载,多系统引导工具(BootThink)下载_多系统引导工具(BootThink)官方下载-太平洋下载中心...
  7. 设计灵感|App中的页面空状态应该如何表现?
  8. android wifi是否可用,Android检测网络连接是否可用
  9. TCP半连接队列(syns queue)和全连接队列(accept queue)
  10. 网址收藏 2020.12.11