赞
踩
源代码见资源:https://download.csdn.net/download/weixin_44410704/19840894
题目:科学计算器
用C语言实现十进制到二进制、八进制、十六进制的转换,并实现基本的加法运算。
任务:编程实现以下功能
① 根据以上功能需求,自己定义合适的数据结构,并说明原因;
② 每个功能提供友好的用户界面,方便用户操作。
需设计合理的数据结构和算法,实现一个拥有友好用户界面的系统,用户可以切换至各个子模块,包括十进制转二进制、二进制加法、十进制转八进制、八进制加法、十进制转十六进制、十六进制加法、二进制移位运算、二进制乘法,用户可以对以上子模块进行测试。
2.1.1 数据结构
1、逻辑结构
由于本系统的数据元素之间是一对一的关系,因此选择了线性结构。
2、存储结构
方案对比: 顺序存储结构 VS 链式存储结构
顺序存储结构:
优点:
①无需为表示表中元素之间的逻辑关系而增加额外的存储空间;
②可以快速地存取表中任意位置的元素。
缺点:
①插入和删除操作需要移动大量元素;
②当线性表长度变化较大时,难以确定存储空间的容量。
链式存储结构:
优点:在执行插入删除操作时,不需要移动元素,但在表尾插入数据时相比于顺序存储结构优势不明显。
缺点:遍历必须从第一个元素开始一个一个遍历,增加了额外的存储空间。
方案选择:由于本系统存储数据量较小,在可控范围内;遍历较多,且插入元素均是在表尾插入元素,因此选择了顺序存储结构。
3、线性表定义
typedef struct
{
ElemType data[MAXSIZE]; /* 数组,存储数据元素,本系统设置为char型 */
char length; /* 线性表当前长度 */
}SqList;
2.1.2系统总体框图
本系统开始运行即进入系统,使用菜单提示用户输入,用户使用键盘输入字符选择子模块测试,用户可键入‘q’退出系统。
当键入‘o’时,打印菜单;
当键入‘a’时,测试问题1;
当键入‘b’时,测试问题2;
当键入‘c’时,测试问题3;
当键入‘d’时,测试问题4;
当键入‘e’时,测试问题5;
当键入‘f’时,测试问题6;
当键入‘g’时,测试问题7;
当键入‘h’时,测试问题8;
当键入‘q’时,退出系统;
当键入其他字符,系统会打印出错信息,提示用户输入有效的字符。
说明:本系统的前7个问题均输入0-255之间的十进制数据,第八个问题输入0-15之间的十进制数据。(在提示用户输入时附有说明。)
2.2.1 问题1:十进制转二进制
2.2.2 问题2:二进制加法
2.2.3 问题3:十进制转八进制
2.2.4 问题4:八进制加法
2.2.5 问题5:十进制转16进制
2.2.6 问题6:16进制加法
2.2.7 问题7:二进制移位
2.2.8 问题8:二进制乘法
3.1.1 存储结构设计
3.1.2 主要功能模块算法设计及流程图
1、Status ListInsert(SqList* L, int i, ElemType e)
a. 功能
在L中第i个位置之前插入新的数据元素e,L的长度加1。
b. 参数含义
L:线性表地址;
i:需插入数据的位置;
e:需插入的数据;
Status:函数执行成功返回1,否则返回0。
c. 思路
①如果插入位置不合理,抛出异常;
②如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;
③从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;
④将要插入元素填入位置i处;
⑤表长加1。
d. 流程图
2、Status Input_data_save(SqList* L);
a. 功能
键盘输入两个0-255的十进制数,保存至线性表L,转换为二进制并保存至线性表L,打印结果。
b. 参数含义
L:线性表地址
返回值Status:当函数执行成功返回OK(1)。
c. 思路
①十进制转换为二进制时先插入低位,再插入高位;每插入一位数据右移一位;
②如果转换成的二进制的1的最高位小于8,那么从该位的高一位开始插入0,直至二进制为8位。
d. 流程图
3、Status ListTraverse_b_a(SqList L, char a, char b);
a. 功能
倒序打印L中位置在a-b之间的数据。
b. 参数含义
L:线性表地址;
a:需打印数据的首位置;
b:需打印数据的尾位置。
c. 思路
根据位置遍历线性表并打印即可。
d. 流程图
3.2.1 存储结构设计
3.2.2 主要功能模块算法设计及流程图
1、Status B_add(SqList* L, char a_loc, char b_loc, char location);
a. 功能
L中数据首地址在a_loc和b_loc的八位二进制数据相加,结果存储到首地址为location的地址。
说明:由于本系统的地址存储均是低位对应线性表低位,高位对应线性表高位,所以此处的首地址为最低位地址。
b. 参数含义
L:线性表地址;
a_loc:第一个加数的最低位地址; b_loc:第二个加数的最低位地址;
location:需要存储的和的最低位地址 Status:函数执行成功返回1。
c. 思路
对两个八位二进制数的最低位执行加法运算,用C存储进位(有进位c = 1,无进位c = 0),并将进位添加到下一次执行加法运算中,以此循环八次,最终将进位存储到和的第九位。
d. 流程图
2、Status Two_to_Ten(SqList* L, char a, char b,char location);
a. 功能
将链表中位置在a-b的二进制数据转换为十进制,结果存储到首地址为location的地址。
b. 参数含义
L:线性表地址;
a:需转换数据的最低位地址; b:需转换数据的最高位地址;
location:需要存储的和的最低位地址 Status:函数执行成功返回1。
c. 思路
十进制 = (((二进制最高位*2 + 次高位)*2 + 次次高位)*2……+次低位)*2 +最低位
d. 流程图
3.3.1 存储结构设计
3.3.2 主要功能模块算法设计及流程图
1、Status Question_3(SqList* L);
a. 功能
键盘输入两个0-255的十进制数,保存至线性表L,转换为八进制并保存至线性表L,打印结果。
b. 参数含义
L:线性表地址; 返回值Status:当函数执行成功返回OK(1)。
c. 思路
①十进制转换为八进制时先插入低位,再插入高位;每插入一位数据右移三位;
d. 流程图
3.4.1 存储结构设计
3.4.2 主要功能模块算法设计及流程图
1、Status Question_4(SqList* L);
a. 功能:L中两位八进制数据相加,结果存储到L。
b. 参数含义
L:线性表地址; Status:函数执行成功返回1。
c. 思路
对两个八位二进制数的最低位执行加法运算,用c存储进位(有进位c = 1,无进位c = 0),并将进位添加到下一次执行加法运算中,以此循环三次。
d. 流程图
2、Status Two_to_Ten(SqList* L, char a, char b,char location);
a. 功能
将链表中位置在a-b的八进制数据转换为十进制,结果存储到首地址为location的地址。
b. 参数含义
L:线性表地址;
a:需转换数据的最低位地址; b:需转换数据的最高位地址;
location:需要存储的和的最低位地址 Status:函数执行成功返回1。
c. 思路
十进制 = (((八进制最高位*8 + 次高位)*8 + 次次高位)*8……+次低位)*8 +最低位
d. 流程图
3.5.1 存储结构设计
3.5.2 主要功能模块算法设计及流程图
1、Status Question_5(SqList* L);
a. 功能:键盘输入两个0-255的十进制数,保存至线性表L,转换为16进制并保存至线性表L,打印结果。
b. 参数含义
L:线性表地址; 返回值Status:当函数执行成功返回OK(1)。
c. 思路
①十进制转换为16进制时先插入低位,再插入高位;每插入一位数据右移四位;
d. 流程图
3.6.1 存储结构设计
3.6.2 主要功能模块算法设计及流程图
1、Status Question_6(SqList* L);
a. 功能:L中两位16进制数据相加,结果存储到L。
b. 参数含义
L:线性表地址; Status:函数执行成功返回1。
c. 思路
对两个16进制数的最低位执行加法运算,用c存储进位(有进位c = 1,无进位c = 0),转移到次低位,两个16进制数的次低位执行加法运算,以此循环三次。
d. 流程图
2、Status Sixteen_to_Ten(SqList* L, char a, char b);
a. 功能
将链表中位置在a-b的16进制数据转换为十进制,结果存储L表尾。
b. 参数含义
L:线性表地址; Status:函数执行成功返回1。
a:需转换数据的最低位地址; b:需转换数据的最高位地址;
c. 思路
十进制 = (((八进制最高位*16 + 次高位)*16 + 次次高位)*16……+次低位)*16 +最低位
d. 流程图
3.7.1 存储结构设计
3.7.2 主要功能模块算法设计及流程图
1、Status copy(SqList* L, char a, char b);
a. 功能:复制线性表中a-b之间的数据到表尾。
b. 参数含义
L:线性表地址; Status:函数执行成功返回1。
a :需要复制数据的首位置 b :需要复制数据的尾位置
c. 思路
按顺序寻找区域内的数据并插入到表尾即可。
d. 流程图
2、Status shift_left(SqList* L, char a, char b, char shift_left);
a. 功能:将线性表L中a-b之间的二进制数据左移shift_left位并原地保存在a-b之间。
b. 参数含义
L:线性表地址; Status:函数执行成功返回1。
a :需要左移数据的首位置 b :需要左移数据的尾位置
c. 思路
覆盖掉高位,用0补充低位。
d. 流程图
3、Status shift_right(SqList* L, char a, char b, char shift_right)
a. 功能:将线性表L中a-b之间的二进制数据右移shift_left位并原地保存在a-b之间。
b. 参数含义
L:线性表地址;
Status:函数执行成功返回1。
a :需要右移数据的首位置
b :需要右移数据的尾位置
c. 思路
覆盖掉低位,高位补0。
d. 流程图
3.8.1 存储结构设计
3.8.2 主要功能模块算法设计及流程图
1、Status Question_8_multi(SqList* L)
a. 功能:输入数据a、b,将a、b转换为二进制,执行a*b运算,保存积的二进制和十进制,打印各个数据。
b. 参数含义
L:线性表地址; Status:函数执行成功返回1。
c. 流程图
测试数据1:
测试数据1:
测试数据1:
测试数据1:
测试数据1:
测试数据1:
测试数据1:
测试数据1:
在开始的设计当中,没有完整地设计整个程序合适的存储结构,而是走一步看一步,在调试过程中经常调着调着存储的顺序就混乱了;搞不清楚哪里存的什么,输出结果不正确;经过很长时间的调试程序总算是正确了,但效率太低。后来就首先想清楚存储结构,需要用到哪些函数等等,当计划好了以后,调试程序就效率高太多了。
因此我学到了教训就是,在写程序时,要先想清楚数据的存储结构,需要哪些函数,哪些函数能够公用等等基本的框架,才可动手敲代码。
由于每次输入字符以后都需要按回车键,又由于是使用getchar()函数获取到键盘的输入,于是回车键就带来了影响,导致程序运行时会输出不需要的东西。
解决方法是:在switch语句中添加一个‘\n’字符选择,当检测到回车键时不执行任何操作直接break即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。