程序设计分组训练 实验2实验报告

1. 相关知识准备

1.1 rand函数

rand函数产生的是伪随机数,也就是说它不是一个真实的随机数。伪随机数是怎么实现的原理大概如下:如果约定:a1=f(seed),an+1=f(an)a1=f(seed),an+1=f(an)那你可以行到一个序列:a1,a2,a3…an,那么要制作一个伪随机函数rand,只需要让它每调用一次就返回序列的下一个元素就行。就相当于第1次调用rand返回a1,第2次返回a2,…,第n次返回an,这样每次调rand都能拿到一个不同的数,只要整个序列的规律不明显,整个函数看起来就是随机的。现在计算机上的rand函数都是用这样的原理实现的,这里的seed被称为“随机数种子”。但这里有一个问题,如果seed不变,那我们每次调用rand函数获取的序列都是相同的。这就会造成有的程序跑一遍退出后,再重新跑一遍,两次的输出结果是相同的。所以我们还需要一个接口去设置seed值,这个接口就是srand函数。
计算机启动时就设定好了种子值,如果不调用srand函数重新设定的话,在同一次程序运行中,产生的随机数是不同的,但不同次运行中,结果完全一样。因此,需要使用srand函数来重设种子。

1.2 srand函数

srand()用来设置rand()产生随机数时的随机数种子。在调用rand()函数产生随机数前,必须先利用srand()设好随机数种子(seed), 如果未设随机数种子, rand()在调用时会自动设随机数种子为1。srand()函数定义 : void srand (unsigned int seed);通常可以利用geypid()或time(0)的返回值来当做seed;如果你用time(0)的话,要加入头文件#include<time.h>。即srand(time(0))。

1.3 命令行参数

main函数参数可以由命令行输入,这包括两个参数:int argc和 char *argv[]。其中,前者代表程序启动时,命令行参数的个数,包括程序名本身,则argc至少为1。后者是指针数组,每一个指针指向一个字符串。
在使用命令行的时候可以用change disk命令改变盘符位置再输入相应的程序名和相关参数进行操作。
相关命令行参数博客称熟练使用命令行有助于提升效率和可移植性。

2. 实验操作

2.1 atoi函数

在命令行参数中的均为字符串形式,则需要将其中代表数组数的字符串改成整形。
而int atoi(const char *str)可以把字符串转换为一个整数,其机制是遍历字符串把每个元素转为相应的数再结合权位最后得出相应的整数。

2.2 判断命令行参数个数并把参数默认初始化

在操作中,命令行可能得到的是只有三元组数目或文件名的参数,这是需要对参数进行判定,然后对命令行没有指定的部分进行默认化。这里对argv[1]判定,思路是遍历其中每一个元素,判断其ASCII码是否在‘0’和‘9’之间。代码如下:

01:			length = strlen(argv[1]);
02:			for(k=1;k<=length;k++){
03:			//判断是否是随机数个数
04:				if(argv[1][k]>='0'&&argv[1][k]<='9') continue;
05:				else break;
06:			} 
07:			if(k==length){
08:				number = atoi(argv[1]);
09:				strcpy(txtaddress, "test2.txt");
10:			}
11:			else{
12:				strcpy(txtaddress, argv[1]);
13:				number = rand();
14:			}

2.3 写入txt文本文件并生成随机数

设置FLIE*pf 以‘w’模式打开一个txt文件,遍历结构体写入文件中,然后关闭。随机数以rand函数生成。代码如下。

15:void Fileopreate(int number, char txtaddress[]){
16:// 生成文件指针 以w模式打开
17:	FILE*pf = fopen(txtaddress, "w");
18:	int(*array)[3] = (int(*)[3])malloc(sizeof(int)*number*3);
19:	
20:	
21:	for(int i=0; i<number; i++ ){
22:				for(int j=0; j<3; j++){
23:					array[i][j] =rand()%100;
24:				}
25:	}
26://空指针的操作
27:	if(pf==NULL){
28:		printf("open error\n");
29:		exit(0);
30:	}
31:	fprintf(pf, "%d\n", number);
32:	for(int i=0; i<number; i++){
33:		for(int j=0; j<3; j++){
34:			fprintf(pf,"%d, ", array[i][j]);
35:		}
36:		fprintf(pf, "\n");
37:	}
38:	if(fclose(pf)!=0){
39:		printf("close error\n");
40:	}
41:	//标记性语句,便于调试
42:	printf("opreate success!\n");
43:	free(array);
44:}
2.4	三种数据结构的实现
(1)	指针数组
利用malloc函数动态申请内存。
01:int(*array)[3] = (int(*)[3])malloc(sizeof(int)*number*3);
02:……
03:free(array);

(2) 结构体

04:void Fileopreate2(int number, char txtaddress[]){
05:	FILE*pf = fopen(txtaddress, "w");
06:	struct array2* array[] = (array2*)malloc(sizeof(array2)*number);
07:	
08:	for(int i=0; i<number; i++ ){
09:		array[i]->a =rand()%100;
10:		array[i]->b =rand()%100;
11:		array[i]->c =rand()%100;
12:	}
13:	if(pf==NULL){
14:		printf("open error\n");
15:		exit(0);
16:	}
17:	fprintf(pf, "%d\n", number);
18:	for(int i=0; i<number; i++){
19:		fprintf(pf,"%d, %d, %d\n", array[i]->a,array[i]->b,array[i]->c);
20:		}
21:		fprintf(pf, "\n");
22:	
23:	if(fclose(pf)!=0){
24:		printf("close error\n");
25:	}
26:	
27:	printf("opreate success!\n");
28:	free(array);
}

(3) 一维数组模拟二维数组

01:void Fileopreate3(int number, char txtaddress[]){
02:	FILE*pf = fopen(txtaddress, "w");
03:	int *array=(int*)malloc(sizeof(int)*number*3);
04:	for(int i=0; i<number; i++ ){
05:		for(int j=0;j<3; j++){
06:			array[i*3+j]= rand%100;
07:		}
08:		
09:	if(pf==NULL){
10:		printf("open error\n");
11:		exit(0);
12:	}
13:	fprintf(pf, "%d\n", number);
14:	for(int i=0; i<number; i++){
15:		for(int j=0; j<3; j++){
16:			fprintf(pf,"%d, ", array[i*3+j);
17:		}
18:		fprintf(pf, "\n");
19:	}
20:	if(fclose(pf)!=0){
21:		printf("close error\n");
22:	}
23:	
24:	printf("opreate success!\n");
25:	free(array);
26:}
27:
28:}

3. 程序健壮性

3.1 健壮性的概念

健壮性是指软件对于规范要求以外的输入情况的处理能力。
所谓健壮的系统是指对于规范要求以外的输入能够判断出这个输入不符合规范要求,并能有合理的处理方式。另外健壮性有时也和容错性,可移植性,正确性有交叉的地方。比如,一个软件可以从错误的输入推断出正确合理的输入,这属于容错性量度标准,但是也可以认为这个软件是健壮的。一个软件可以正确地运行在不同环境下,则认为软件可移植性高,也可以叫,软件在不同平台下是健壮的。一个软件能够检测自己内部的设计或者编码错误,并得到正确的执行结果,这是软件的正确性标准,但是也可以说,软件有内部的保护机制,是模块级健壮的。软件健壮性是一个比较模糊的概念,但是却是非常重要的软件外部量度标准。软件设计的健壮与否直接反应了分析设计和编码人员的水平。即所谓的高手写的程序不容易死。

3.2 本程序健壮性分析

本程序只考虑到用户输入三个参数的情况,对于其他情况没有考虑。其实可以再switch-case中加入default进行处理。再比如,除第一个参数是程序名之外,后两个参数的位置可以考虑乱序任有效,即无论用户先输入数组数还是文件名都可以通过内部的判断得到正确处理。
之前对健壮性接触比较少,现在逐步有了用户的思维,用户的可能性是无穷无尽的,程序编写人员要提前把相应、可能的不符合要求的数据想到,进而返回错误类型,帮助用户修改相应数据,甚至判断用户真实意——这些都是应有之意。

4. 心得体会

本次实验中,对于rand函数、srand函数,malloc和free函数有了更深的理解。对于数组做函数的参数和函数返回多个数值的情况有了更深的理解,在这种情况下,通过指针或指针数组显然是事半功倍的。
最令我感到高兴的是,这次对于实验报告的编写有了更多的体会。采用论文相关格式制定好的样式有利于排版和格式统一,一举改变了此前先码字再排版的情况。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值