数制转换 C 数据结构课程设计.docx
《数制转换 C 数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《数制转换 C 数据结构课程设计.docx(22页珍藏版)》请在冰豆网上搜索。
数制转换C数据结构课程设计
福建农林大学计算机与信息学院
计算机类
课程设计报告
课程名称:
数据结构课程设计
课程设计题目:
数制转换问题
姓名:
XIA
系:
计算机科学与技术
专业:
计算机科学与技术
年级:
2011级
学号:
3116013131
指导教师:
刘必雄
职称:
讲师
2011年12月24日
福建农林大学计算机与信息学院计算机类
课程设计结果评定
评语:
评分项目
分值
得分
综合运用知识能力和实践动手能力强,设计方案合理,计算、分析正确,设计成果质量高;
40
设计态度认真,独立工作能力强,有独到见解,水平较高,并具有良好的团队协作精神;
40
设计报告条理清晰、论述充分、文字通顺、图表规范课程设计报告符合规范要求。
20
成绩:
指导教师签字:
任务下达日期:
评定日期:
数制转换问题
1.设计目的
实现二、八、十和十六进制不同数制数据之间的相互转换。
2.设计要求
•输入一种数的数据及数制,输出这个数的其他三种数制的表示。
•输入的数包括整数和小数。
•基于vc++6.0平台,用C语言实现程序设计。
3.设计方案
用顺序栈实现数据的存入和读取
4.设计内容
4.1需求分析
1)输入的形式和输入值的范围
•先输入未转换前数的进制:
取值范围只能是2、8、10、16,输入其他数据则提示出错重输。
•再输入该进制的数:
取值范围可以是原进制的整数或小数,根据提供的原数据的数制,通过ASCII码判断每次输入的各个字符是否正确,如:
2进制只能输入1,0和小数点;
8进制只能输入0到7的数和小数点;
10进制只能输入0到9的数和小数点;
16进制只能输入输入0到9的数,A到F的字母和小数点;
输入其他字符则提示出错重输。
2)输出的形式
•分三行分别输出该数其他进制的表示。
3)程序所能达到的功能
•通过键盘输入、文本读取数据,检测输入的数与原进制是否有误;
•将输入的数(可以是整数或小数),转换成除本身的进制数外其他3种进制的数并输出;
•可以在数据转换后,选择是否退出或继续输入数据进行转换。
4)测试数据:
正确的输入及其输出,示例整数:
正确的输入及其输出,示例小数:
含错误的输入及其输出:
4.2概要设计
1)抽象数据类型的定义
typedefstruct{int*b,*top;intsize;}Stack;StackS;//定义栈
intInitS(Stack&S)//构造空栈
intClearS(Stack&S)//释放栈S
intIsEmpty(StackS)//判断栈是否为空,若空返回1,否则返回0
intPush(Stack&S,inte)//插入元素e为新的栈顶元素
intPop(Stack&S,int&e)//删除S的栈顶元素,用e返回其值
charc[1000];//c[]存入未转换的数
inte,m,n,r,i,j;//定义全局变量
//e为栈顶元素临时变量,m为要转的进制数,n为转换前数的个数
//r是十进制转M进制的余数,i为自增变量,j存小数点后有几位小数用
floatx,y,z;//定义全局变量
//x为要转换的十进制,y是转后的10进制数,z是十进制的小数部分
2)主控程序的流程
•首先接收未转换前数的进制m及数据,判断是否非法做出提示;
•用c[]数组接收数据,有小数得记下小数位数j。
当接收的数据为十进制则用float(atof(c))转成小数给全局变量x;
若接收的数据为其他进制数则逐个读取Push(S,c[i])入栈。
•根据全局变量m判断要调用的函数:
DtoM(floata,intb)十进制转换成其他进制的函数,
MtoD()其他进制转换为十进制的函数。
•在DtoM(float,int)函数中,接收形参为要转换的十进制数和要转成的数制。
先判断数据是否有小数,有小数则先转换小数部分的存入zz[]。
输出时先输出转换的整数部分,有小数再读取zz[]逐个输出小数部分。
•在MtoD()函数中,由j判断数据是否有小数,若有小数先转换小数部分。
输出时将转后的小数部分(若有)累加上整数部分输出。
•转换完成后,清除栈,由用户选择是否继续输入数据转换或退出。
3)各程序模块之间的层次关系
voidDtoM(floata,intb)//十进制转换成其他进制的函数
voidMtoD()//其他进制转换为十进制的函数
voidmain()//根据输入数据调用MtoD()和DtoM()函数对数据转换
注:
其他非十进制的数转换时,都先调用MtoD()转成十进制,得到float类型数存入全局变量y,再调用DtoM(y,m)转成需要的进制。
4.3详细设计
•流程图:
•伪代码:
//十进制转换成其他进制的函数DtoM()//
voidDtoM(floata,intb)
{
z=a-(int)a;//取小数部分
intzz[20];//存转后的小数部分
i=0;
if(z)//有小数
{
while(z)
{zz[i]=int(z*b);
i++;
z=z*b-int(z*b);
}
n=i;
}
while((int)a)
{
r=(int)a%b;
if(r>9)
r=r+55;
Push(S,r);//压入栈
a=a/b;//转换成b进制
}
printf("\t该数<%d>进制的结果是:
",b);
while(!
IsEmpty(S))
{
Pop(S,e);//弹出栈
if(e>=65)
printf("%c",e);
else
printf("%d",e);
}
if(i)//有小数
{printf(".");//小数点
for(i=0;i{printf("%X",zz[i]);}
}
printf("\n");
return;
}
//其他进制转换为十进制的函数MtoD()//
voidMtoD()
{
i=0;
y=0;
if(j)//有小数
{
while(j)
{
Pop(S,e);
if(e>=65)
e=e-55;//转字母
else
e=e-48;//转数字
y+=1/((float)pow(m,j))*e;
//1除(e乘(m的j次方))
j--;
}
Pop(S,e);//小数点抛出
}
while(!
IsEmpty(S))
{
Pop(S,e);
if(e>=65)
e=e-55;//转字母
else
e=e-48;//转数字
y+=(int)pow(m,i)*e;
//e乘(m的i次方)
i++;
}
printf("\t该数<10>进制的结果是:
");
if((int)y==y)
printf("%.0f\n",y);
else
printf("%f\n",y);//有小数
return;
}
//-------主函数main()-----//
voidmain()
{
freopen("DS1.in","r",stdin);
freopen("DS1.out","w",stdout);
//界面功能说明
printf("\n");printf("\n");
printf("\t▉▊▊▋▍▎▏=数制转换器=▏▎▍▋▊▊▉\n");printf("\n");
printf("-[实现2\\8\\10\\16进制数据之间的转换]-\n");
printf("\t|◆先输入未转换前数的数制类型|\n");
printf("\t|◆再输入未转换的数|\n");
printf("\t|<该数可以是整数或小数>|\n");
printf("\t|●程序将输出该数的其他进制形式|\n");
printf("\t||\n");
printf("-----------========");
printf("========------------\n");
printf("\n");
printf("\n");
First:
intf=1;//判断标识
InitS(S);//构造一个空栈
printf("\t请输入未转换前数的进制:
");
while(f)
{if(scanf("%d",&m)==EOF||m!
=2&&m!
=8&&m!
=10&&m!
=16)
printf("\t▲输入有误,请重新输入<2or8or10or16>:
");
else
f=0;
}
printf("\t请输入该数:
");
Second:
scanf("%s",c);
n=strlen(c);
f=0;//判断标识
for(i=0;i{
switch(m)
{case2:
{if(c[i]>49||c[i]<46||c[i]==47)f=1;break;}
case8:
{if(c[i]>55||c[i]<46||c[i]==47)f=1;break;}
case10:
{if(c[i]>57||c[i]<46||c[i]==47)f=1;break;}
case16:
{if(c[i]>70||(c[i]>57&&c[i]<65)||c[i]<46||c[i]==47)
f=1;break;}
default:
break;
}//有错f=1;
}
if(f)//检查输入格式是否有误
{
printf("\t▲输入有误,请重新输入:
");
gotoSecond;
}
if(m!
=10)//其他进制转换成十进制
{j=0;
for(i=0;i{Push(S,c[i]);
if(c[i]=='.')
j=n-1-i;//存小数位数
}
}
else//十进制转换成其他进制
{x=float(atof(c));//字符串转小数
}
printf("\n");
switch(m)//数制相互转换
{
case10:
{DtoM(x,2);DtoM(x,8);DtoM(x,16);break;}
case2:
{MtoD();DtoM(y,8);DtoM(y,16);break;}
case8:
{MtoD();DtoM(y,2);DtoM(y,16);break;}
case16:
{MtoD();DtoM(y,2);DtoM(y,8);break;}
default:
break;
}
ClearS(S);//释放栈S
printf("\n");
printf("-----------========");
printf("========------------\n");
printf("\t是否继续?
继续【1】or退出【0】:
");
scanf("%d",&f);
if(f)
{
printf("\n");gotoFirst;
}
}
4.4调试分析
⏹难点:
检查输入格式是否有误
⏹解决:
通过ASCII码判断每次输入的各个字符是否正确,如:
2进制只能输入1,0和小数点;
8进制只能输入0到7的数和小数点;
10进制只能输入0到9的数和小数点;
16进制只能输入0到9的数,A到F的字母和小数点;
用f判断标识,输入其他字符则将f=1提示出错重输。
⏹代码示例:
main()
{……
f=0;
for(i=0;i{
switch(m)
{
case2:
{if(c[i]>49||c[i]<46||c[i]==47)f=1;break;}
case8:
{if(c[i]>55||c[i]<46||c[i]==47)f=1;break;}
case10:
{if(c[i]>57||c[i]<46||c[i]==47)f=1;break;}
case16:
{if(c[i]>70||(c[i]>57&&c[i]<65)||c[i]<46||c[i]==47)
f=1;break;}
default:
break;
}//有错f=1;
}
……
}
⏹难点:
取未转换十进制的小数部分,并输出转换后的相应的进制格式
⏹解决:
使用强制转换,转义符号%X、%.0f
⏹代码示例:
voidDtoM(floata,intb)//十进制转换成其他进制的函数
{……
z=a-(int)a;//用强制转换取小数部分
intzz[10];//存转后的小数部分
i=0;
if(i)//有小数
{
printf(".");//小数点
for(i=0;i{printf("%X",zz[i]);
//用%X逐个输出即为输出相应进制转换后的数
}
}
……}
voidMtoD()//其他进制转换为十进制的函数
{
……
printf("\t该数<10>进制的结果是:
");
if((int)y==y)
printf("%.0f\n",y);
//小数部分没有有效数字,用%.0f去除小数点后的0
else
printf("%f\n",y);//有小数
return;
}
⏹难点:
求输入数据小数点后有几位
⏹解决:
用scanf("%s",c)将输入数存入数组中,
用n=strlen(c)得到长度,
用j存小数位数:
for(i=0;i4.5测试结果
●键盘输入输出结果:
•整数转换测试
•小数转换测试
•输入出错测试
●文本输入输出结果:
•//DS1.in整数转换测试
DS1.in
DS1.out
2
1101
1
8
765
1
10
11
1
16
4A3
0
▉▊▊▋▍▎▏=数制转换器=▏▎▍▋▊▊▉
-[实现2\8\10\16进制数据之间的转换]-
||
|◆先输入未转换前数的数制类型|
|◆再输入未转换的数|
|<该数可以是整数或小数>|
|●程序将输出该数的其他进制形式|
||
-----------================------------
请输入未转换前数的进制:
请输入该数:
该数<10>进制的结果是:
13
该数<8>进制的结果是:
15
该数<16>进制的结果是:
D
-----------================------------
是否继续?
继续【1】or退出【0】:
请输入未转换前数的进制:
请输入该数:
该数<10>进制的结果是:
501
该数<2>进制的结果是:
111110101
该数<16>进制的结果是:
1F5
-----------================------------
是否继续?
继续【1】or退出【0】:
请输入未转换前数的进制:
请输入该数:
该数<2>进制的结果是:
1011
该数<8>进制的结果是:
13
该数<16>进制的结果是:
B
-----------================------------
是否继续?
继续【1】or退出【0】:
请输入未转换前数的进制:
请输入该数:
该数<10>进制的结果是:
1187
该数<2>进制的结果是:
10010100011
该数<8>进制的结果是:
2243
-----------================------------
是否继续?
继续【1】or退出【0】:
•//DS2.in小数转换测试
DS2.in
DS2.out
2
1101.1011
1
8
765.2
1
10
11.125
1
16
4A3.2
0
▉▊▊▋▍▎▏=数制转换器=▏▎▍▋▊▊▉
-[实现2\8\10\16进制数据之间的转换]-
||
|◆先输入未转换前数的数制类型|
|◆再输入未转换的数|
|<该数可以是整数或小数>|
|●程序将输出该数的其他进制形式|
||
-----------================------------
请输入未转换前数的进制:
请输入该数:
该数<10>进制的结果是:
13.687500
该数<8>进制的结果是:
15.54
该数<16>进制的结果是:
D.B
-----------================------------
是否继续?
继续【1】or退出【0】:
请输入未转换前数的进制:
请输入该数:
该数<10>进制的结果是:
501.250000
该数<2>进制的结果是:
111110101.01
该数<16>进制的结果是:
1F5.4
-----------================------------
是否继续?
继续【1】or退出【0】:
请输入未转换前数的进制:
请输入该数:
该数<2>进制的结果是:
1011.001
该数<8>进制的结果是:
13.1
该数<16>进制的结果是:
B.2
-----------================------------
是否继续?
继续【1】or退出【0】:
请输入未转换前数的进制:
请输入该数:
该数<10>进制的结果是:
1187.125000
该数<2>进制的结果是:
10010100011.001
该数<8>进制的结果是:
2243.1
-----------================------------
是否继续?
继续【1】or退出【0】:
•//DS3.in输入出错测试
DS3.in
DS3.out
9
2
b
12
110
1
8
z.2
8
67
1
10
11.a
wd
90.25
1
16
89G
A6.5
0
▉▊▊▋▍▎▏=数制转换器=▏▎▍▋▊▊▉
-[实现2\8\10\16进制数据之间的转换]-
||
|◆先输入未转换前数的数制类型|
|◆再输入未转换的数|
|<该数可以是整数或小数>|
|●程序将输出该数的其他进制形式|
||
-----------================------------
请输入未转换前数的进制:
▲输入有误,请重新输入<2or8or10or16>:
请输入该数:
▲输入有误,请重新输入:
▲输入有误,请重新输入:
该数<10>进制的结果是:
6
该数<8>进制的结果是:
6
该数<16>进制的结果是:
6
-----------================------------
是否继续?
继续【1】or退出【0】:
请输入未转换前数的进制:
请输入该数:
▲输入有误,请重新输入:
▲输入有误,请重新输入:
该数<10>进制的结果是:
55
该数<2>进制的结果是:
110111
该数<16>进制的结果是:
37
-----------================------------
是否继续?
继续【1】or退出【0】:
请输入未转换前数的进制:
请输入该数:
▲输入有误,请重新输入:
▲输入有误,请重新输入:
该数<2>进制的结果是:
1011010.01
该数<8>进制的结果是:
132.2
该数<16>进制的结果是:
5A.4
-----------================------------
是否继续?
继续【1】or退出【0】:
请输入未转换前数的进制:
请输入该数:
▲输入有误,请重新输入:
该数<10>进制的结果是:
166.312500
该数<2>进制的结果是:
10100110.0101
该数<8>进制的结果是:
246.24
-----------================------------
是否继续?
继续【1】or退出【0】:
4.6用户使用说明
•第一次输入:
未转换前数的进制
(只能输入2或8或10或16,输入其他数据则提示出错重输)
•第二次输入:
该进制的数
(取值范围应当是原进制的整数或小数。
如:
2进制只能输入1,0和小数点;8进制只能输入0到7的数和小数点;10进制只能输入0到9的数和小数点;16进制只能输入0到9的数,A到F的字母和小数点;输入其他字符则提示出错重输。
)
•程序将自动分三行分别输出该数其他进制的表示。
【注】:
小数转换的算法不是互逆的。
输入非十进制(2、8、16进制)的小数可以成功转成其他进制的小数;
但不是任意的十进制的小数能完全转成非十进制(2、8、16进制)的小数。
程序目前仍然有Bug,对输入十进制的小数的判断还未完成。
5.总结
通过本次课程设计,我认识到熟练掌握基础算法的重要性,对栈的含义及其基本算法有了更好的理解和应用。
栈“先进后出”的算法加上Push()和Pop()方便了对要转换的数进行读取,和对转换后数倒置的输出。
在编写过程中常遇到的不少问题,例如:
变量类型的转换和ASCII码转义字符的应用,变量的定义和范围,算法循环语句的退出条件等,我通过不断调试,翻阅课本和网上搜索材料得到了解决,也认识到这些细节上的处理更当注意。
在调试时,学会了在有问题的地方注释并能经常使用printf()函数测试输出结果。
在测试时,对测试数据的选取更当考虑全面,能检测错误输入并进行提示。
通过这次实验,我学会运用课本和老师平时讲授知识进行切身实践,通过网络搜索学到了新的库函数,提高了我实际编写程序的能力。
参考文献
[1]宁正元,王秀丽.算法与数据结构[M].北京:
清华大学出版社,2006.01.
[2]宁正元,王秀丽,林大辉.算法与数据结构习题精解和实验指导[M].北京,2007.05.