栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c/c++抽象数据类型实验

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c/c++抽象数据类型实验

目录

文章目录

前言

一、数据类型描述

二、源代码(扩展名.cpp)

1.引入库

2.读入数据

代码段的理解


前言

作为新手,模仿+理解+运用是学习的三个阶段

本文以理解代码段为学习目标


一、数据类型描述

三元组Triplet的定义:
ADT Triplet{
数据对象:D={e1, e2, e3|e1, e2, e3属于ElemType(定义了关系的某个集合)}
数据关系:R={|}
基本操作:
initTriplet(&T, v0, v1, v2)
初始条件:
操作结果:构造三元组T,元素e1, e2和e3分别被赋予参数v1, v2, v3的值。
destroyTriplet(Triplet T)
初始条件:三元组T已经存在。
操作结果:销毁三元组T。
printTriplet(T)
初始条件:三元组T已经存在。
操作结果:显示三元组T。
getElem(T, i, &e)
初始条件:三元组T已经存在, 1 <= i <= 3。
操作结果:用e返回三元组T的第i(1~3)个元素的值。
putElem(&T, I, e)
初始条件:三元组T已经存在, 1 <= i <= 3。
操作结果:用e的值取代三元组T的第i(1~3)个元素的值。 
getMax(T, &e)
初始条件:三元组T已经存在。
操作结果:用e返回三元组T的最大值。
getMin(T, &e)
初始条件:三元组T已经存在。
操作结果:用e返回三元组T的最小值。
isAscending(T)
初始条件:三元组T已经存在。
操作结果:如果T的三个元素按升序排序,则返回OK,否则返回ERROR。
isDescending(T)
初始条件:三元组T已经存在。
操作结果:如果T的三个元素按降序排序,则返回OK,否则返回ERROR。
Add(T1, &T2)
初始条件:存在三元组T1, T2。
操作结果:用T2带回操作结果。
mulCoef(&T1, coef)
初始条件:三元组T1已经存在。
操作结果:用T1带回乘系数之后都结果。
}ADT Triplet

二、源代码(扩展名.cpp)

1.引入库

代码如下(示例):

# include //标准的输入输出函数库 
# include //使用动态分配内存必须引入的函数库 
# define OK 1 //宏定义,下同 
# define ERROR 0
# define OVERFLOW -2 
typedef int Status; //给int起了个别名(Status),下同 
typedef float ElemType;
typedef ElemType *Triplet; //声明Triplet为指向任意类型(此处为ElemType)的指针 
//三元组的初始化//
void initTriplet(Triplet &T, ElemType v0, ElemType v1, ElemType v2)
{
	//动态分配内存
	T = (ElemType *)malloc(3*sizeof(ElemType)); 

	if (!T)  
	{
		printf("分配内存失败!");
		exit(OVERFLOW);
	}
	T[0] = v0;
	T[1] = v1;
	T[2] = v2;
}
//销毁三元组//
void destroyTriplet(Triplet &T)
{
	free(T);
	printf("分配内存已释放!");
	exit(0);
}
//销毁三元组//
void destroyTriplet_2(Triplet &T)
{
	 delete []T; 
	 printf("分配内存已释放!");
	 exit(0);
}
//显示三元组
void printTriplet(Triplet T)
{
	printf("调用初始化函数后,T的三个值为:%.1f,%.1f,%.1fn", T[0], T[1], T[2]);
}
// 用e获取T的第i(1~N)个元素的值// 
Status getElem(Triplet T, int i, ElemType &e)
{
	if (i < 1 || i > 3)
		return ERROR;
	else e = T[i-1]; 
	return OK;
}
// 置T的第i元的值为e 
Status putElem(Triplet &T, int i, ElemType e)
{
	if (i < 1 || i > 3)
		return ERROR;
	else T[i-1] = e; 
	return OK;
}
//用e返回值指向T的最大元素的值
ElemType getMax(Triplet T,  ElemType &e)
{
	if (T[0] > T[1])
		e = T[0];
	else
		e = T[1];
	if (T[2] > e)
		e = T[2];
	printf("三元组T的最大元素的值为:%4.2fn",e);
	return e; 
} 
//用e返回值指向T的最小元素的值
ElemType getMin(Triplet T, ElemType &e)
{
	if (T[0] < T[1])
		e = T[0];
	else
		e = T[1];
	if (T[2] < e)
		e = T[2];
	printf("三元组T的最小元素的值为:%4.2fn",e);
	return e;
} 
//如果T的三个元素按升序排序,则返回1,否则返回0//
void isAscending(Triplet T)
{
	if (((T[0] <= T[1]) && (T[1] <= T[2] )) != ERROR)
		printf("T的三个元素按升序排序n");
	else printf("T的三个元素不是按升序排序");
} 
//如果T的三个元素按降序排序,则返回1,否则返回0//
void isDescending(Triplet T)
{
	if (((T[0] >= T[1]) && (T[1] >= T[2])) != ERROR)
		printf("T的三个元素按降序排序n"); 
	else printf("T的三个元素不是按降序排序");
} 
//两个三元组相加
void add(Triplet T, Triplet &T2)
{
	int i;
	for (i = 0; i < 3; i++)
		T2[i] += T[i]; 
} 
//三元组的各分量同乘比例系数
void mulCoef(Triplet &T, float coef)
{
	int i;
	for (i = 0; i < 3; i++)
		T[i] *= coef;
} 
int main()
{
	Triplet T, T2;
	ElemType v0, v1, v2, e, coef;
	int funNum, i;
	printf("----三元组操作主菜单----n");
	printf("----1.三元组初始化----n"); 
	printf("----2.显示三元组----n");
	printf("----3.用e获取T的第i(1~N)个元素的值----n");
	printf("----4.置T的第i个元素的值为e----n");
	printf("----5.是否升序排列----n");
	printf("----6.是否降序排列----n");
	printf("----7.取最大值----n");
	printf("----8.取最小值----n");
	printf("----9.输入另一个三元组相加----n");
	printf("----10.三元组的各分量同乘比例系数----n");
	printf("----11.退出系统----n");
	while (1)
	{
		printf("请输入你想完成的功能编号:n"); 
		scanf("%d", &funNum);
		switch (funNum)
		{
			case 1: printf("请输入三元组的每个元素:n");
					scanf("%f %f %f", &v0, &v1, &v2);
					initTriplet(T, v0, v1, v2);
					break;
			case 2: printTriplet(T);
					break;
			case 3: printf("请输入要获取第几个元素的值:n");
					scanf("%d", &i);
					getElem(T, i, e);
					printf("第%d个元素的值为:%4.2fn", i, e);
					break;
			case 4: printf("请输入要更改的位置和要输入的值:n");
					scanf("%d %f", &i, &e);
					putElem(T, i, e);
					printf("新的三元组为:n");
					printTriplet(T);
					break;
			case 5: isAscending(T);
					break;
			case 6: isDescending(T);
					break;
			case 7: getMax(T, e);
					break;
			case 8: getMin(T, e);
					break;
			case 9: printf("请输入另一个三元组的每个元素n");
					scanf("%f %f %f", &v0, &v1, &v2);
					initTriplet(T2, v0, v1, v2);
					add(T, T2);
					printf("相加之后的三元组的值为:n");
					printTriplet(T2);
					break;
			case 10: printf("请输入所乘的系数n");
					scanf("%f", &coef);
					mulCoef(T, coef);
					printf("每项乘系数之后的三元组为:n");
					printTriplet(T);
					break;
			case 11: destroyTriplet(T);
					destroyTriplet(T2);
					break;
			default: printf("没有你想完成的功能n");break;
		}
	}
	return 0;
}

2.读入数据

代码如下:


代码段的理解

上文的源代码中,基本每段代码之后都有程序注释,作为新手,程序注释更是我们检验理解能力的"一杆秤“。

除程序注释,以下方面是对整片代码的理解:

1.指针问题

c中指针内容没掌握好的同学,(例如我),刚开始会对上述代码会有疑惑,全文中只有开头typedef ElemType *Triplet;中带有出现指针定义的间接访问运算符”*“,好像与下面代码显得格格不入

而理解代码的话,你会惊奇的发现,下面代码基本全部使用了指针,每一个变量T都是指针型变量,“指针无处不在”。

上面指出typedef ElemType *Triplet;是在声明Triplet为指向任意类型(此处为ElemType)的指针,所以,下面每一个Triplet数据类型的变量,全都是指向ElemType类型的指针变量,

在子函数中,会发现许多T[0]的用法,其实这就是指针的便捷之处,如果我们用结构体的话,必须 使用类似T.e[0]的形式,才能做一系列操作,但如果上面定义指针类型的话,直接使用T[0]即可。

T[0]的用法有些类似数组,对于数组而言,数组名[]可对数组中的元素操作,而对于指针变量同样适用,指针变量名T[]即可对指针指向的内容操作。(注意,不是指针本身的内容(或者说指针指向的方向))。

2.引用问题

上述代码我们使用了c++中的“引用”,(这也就是为什么源代码的扩展名要为.cpp),引用通俗来讲,就是给变量a又取了一个名字为变量b,所以引用并没有给b分配内存空间,而是让b与a共用同一块内存空间,此处与指针不同

在上述代码的参数传递中,我们多次使用了引用"&T",对于什么时候需要使用来说,如果你要改变某个实参的值,就对某个实参使用引用,反之,则不用。

3.针对上文使用的动态内存分配问题

本实验要求动态内存分配,其实对于三元组来说,并没有把动态内存分配的功能发挥的淋漓精致,但也简单的让我们看到了其强大功能的一二。

动态内存分配需要使用指针,指针的强大上文已经略有细说,我们慢慢体会。

动态分配内存要养成及时把需要释放的内存给释放掉的好习惯,对于大量的程序代码段,有助于提升系统的效率,减少所占内存。

写在最后

上文多次写了我对指针的理解,比如说两个特性,方向与大小,

但只是配和理解,真正应该以配合理解去使理解专业化,而不应该停留在配合理解或者被其框架所束缚。

浮游乎万物之祖,物物而不物于物。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/780089.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号