基于C语言、线性表的 二、八、十、十六进制转换 及 加运算、左右移位运算、乘法运算 的科学计算器设计

源代码见资源:https://download.csdn.net/download/weixin_44410704/19840894

一、需求分析

1.1 设计题目

题目:科学计算器
用C语言实现十进制到二进制、八进制、十六进制的转换,并实现基本的加法运算。
任务:编程实现以下功能

  1. 十进制转换位二进制输出
    输入两个十进制整数a和b。将这两个十进制数a、b转换成二进制数,保存并将这两个二进制数打印输出。
    例如:a=6=110, b=5=101;
  2. 二进制加法运算
    实现二进制加法,将二进制转换后的a、b相加,结果分别以二进制和十进制输出。
    例如:a+b=110+101=1011
  3. 十进制转换位八进制输出
    与(1)类似,将十进制数a、b转换成八进制数,保存并将这两个八进制数打印输出。
  4. 八进制加法运算
    与(2)类似,实现八进制加法,将八进制转换后的a、b相加,结果分别以八进制和十进制输出。
  5. 十进制转换位十六进制输出
    与(1)类似,将十进制数a、b转换成十六进制数,保存并将这两个十六进制数打印输出。
  6. 十六进制加法运算
    与(2)类似,实现十六进制加法,将十六进制转换后的a、b相加,结果分别以十六进制和十进制输出。
  7. 试完成二进制移位运算(选做)
    实现二进制移位运算,结果分别以二进制和十进制输出。<< 左移位运算:运算数对应的二进制数位全部左移若干位,高位丢弃,低位补0。
    例如:>>右移位运算:运算数对应的二进制数位全部右移若干位,高位补0,低位丢弃
    例如:a>>1 = 110>>1 = 11
  8. 试完成二进制乘法运算(选做)
    实现二进制乘法运算,将二进制转换后的a、b相乘,结果以二进制输出。
    例如:a=110, b=101。二进制数a乘以b,乘数a=110的每一位分别与乘数b=101相乘,得到110、000(左移一位)、110(左移两位),将其加起来,得到11110

1.2 设计要求

① 根据以上功能需求,自己定义合适的数据结构,并说明原因;
② 每个功能提供友好的用户界面,方便用户操作。

1.3 系统功能需求分析

需设计合理的数据结构和算法,实现一个拥有友好用户界面的系统,用户可以切换至各个子模块,包括十进制转二进制、二进制加法、十进制转八进制、八进制加法、十进制转十六进制、十六进制加法、二进制移位运算、二进制乘法,用户可以对以上子模块进行测试。

二、概要设计

2.1 系统总体设计框架

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 系统功能模块图

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.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 问题2:十进制转换为二进制

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 问题3:十进制转换为八进制

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 八进制加法

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 问题5:十进制转换为16进制

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 16进制加法

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 二进制移位运算

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 二进制乘法运算

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. 流程图
在这里插入图片描述

四、测试数据与测试输出结果

4.1 十进制转二进制

测试数据1:
在这里插入图片描述

(图1.1)
测试数据2:

在这里插入图片描述

(图1.2)

4.2 二进制加法

测试数据1:

在这里插入图片描述

(图2.1)
测试数据2:

在这里插入图片描述

(图2.2)

4.3 十进制转八进制

测试数据1:
在这里插入图片描述

(图3.1)
测试数据2:

在这里插入图片描述

(图3.2)

4.4 八进制加法

测试数据1:
在这里插入图片描述

(图4.1)
测试数据2:

在这里插入图片描述

(图4.2)

4.5 十进制转16进制

测试数据1:
在这里插入图片描述

(图5.1)
测试数据2:

在这里插入图片描述

(图5.2)

4.6 16进制加法

测试数据1:
在这里插入图片描述

(图6.1)
测试数据2:

在这里插入图片描述

(图6.2)

4.7 二进制移位

测试数据1:
在这里插入图片描述

(图7.1)
测试数据2:

在这里插入图片描述

(图7.2)

4.8 二进制乘法

测试数据1:
在这里插入图片描述

(图8.1)
测试数据2:

在这里插入图片描述

五、遇到的问题

5.1 存储结构的问题

在开始的设计当中,没有完整地设计整个程序合适的存储结构,而是走一步看一步,在调试过程中经常调着调着存储的顺序就混乱了;搞不清楚哪里存的什么,输出结果不正确;经过很长时间的调试程序总算是正确了,但效率太低。后来就首先想清楚存储结构,需要用到哪些函数等等,当计划好了以后,调试程序就效率高太多了。
因此我学到了教训就是,在写程序时,要先想清楚数据的存储结构,需要哪些函数,哪些函数能够公用等等基本的框架,才可动手敲代码。

5.2 回车键干扰问题

由于每次输入字符以后都需要按回车键,又由于是使用getchar()函数获取到键盘的输入,于是回车键就带来了影响,导致程序运行时会输出不需要的东西。
解决方法是:在switch语句中添加一个‘\n’字符选择,当检测到回车键时不执行任何操作直接break即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jasmine-Lily

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值