第一篇:C语言课程设计大数加减实验报告
《C语言程序设计》课程设计
大数加减
一、目的
因为C语言中的int类型和long 类型的大小范围仅为(-32767~32767和-2147483647~2147483647),在某些较大型计算中,数据长度不能满足需要。本实验目的是用C设计一个足够大的整数类型,实现两个大整数的加减运算。
二、需求分析
1、输入的形式和输入值的范围
运行程序时,按照提示将依次输入一个整数、一个‘+’或‘-’号和另一个整数;输入值最小为0,最大可达100位,但当输入的两个数都是100位且相加时,可能会发生溢出,所以为了保险起见,最大输入为99位。
2、输出的形式
输入的两个数进行加法或减法运算后,结果将以一个整型数输出。
3、程序所能达到的功能
在某些较大型计算中,C语言中的int类型和long 类型的长度不能满足需要,本程序借助字符数组来储存这两个大数,然后根据0-9的ASCII码进行加减并转换成数字输出,从而实现两个大整数的加减运算。
4、初步的测试计划
(1)两个正整数相加,结果分发生进位和未发生进位两种情况;(2)两个正整数相减,分大数减小数和小数减大数两种情况。
三、概要设计
1、主函数模块
int mian(){ 定义变量; Do {
定义字符数组并初始化;
调用函数读入两个数据和从键盘输入‘+’或‘-’; 给变量赋值;
中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名: 1
《C语言程序设计》课程设计
使用switch结构来实现加减运算并输出结果; 提示是否继续计算;
} while();return 0;}
2、子函数功能
int read(char str[N]);
用数组读入整数并返回数位;
void increase(char str1[N],char str2[N],char str[N],int m,int n,int a,int b);对两个整数进行加法运算 ; void output(char str[N],int m);输出两个整数相加后的结果 ;
void calculate(char str1[N],char str2[N],char str[N],int m,int n,int a,int b);比较两个整数的大小,调用其它函数执行减法运算,输出结果;
void decrease(char str1[N],char str2[N],char str[N],int m,int n,int a,int b);对两个整数进行减法运算 ; void print(char str[N],int m);输出两个整数相减后的结果。
3、数据类型及含义
int a,b,m,n;定义整型变量,a是第一个整数的位数,b是第二个整数的位数,m是a、b中较大值再加上1,n是a、b中较小值;
char op,ans;定义字符变量,op代表‘+’或‘-’,ans代表你的选择(完成此次计算后是否继续下一次计算);
char number1[N]={0},number2[N]={0},number[N]={0};定义三个字符数组,分别储存两个输入值和一个结果,并进行初始化。
中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名: 2
《C语言程序设计》课程设计
四、详细设计
1、伪码算法
/* 函数功能:输入两个大正整数,利用字符数组对其进行加法运算或减法运算,并输出结果*/ /*头文件*/ #include
void increase(char str1[N],char str2[N],char str[N],int m,int n,int a,int b);void output(char str[N],int m);void decrease(char str1[N],char str2[N],char str[N],int m,int n,int a,int b);void print(char str[N],int m);void calculate(char str1[N],char str2[N],char str[N],int m,int n,int a,int b);/*主函数*/ int main(){ int a,b,m,n;
/*用于字符串的处理*/ char op,ans;/* 定义变量*/ do { char number1[N]={0},number2[N]={0},number[N]={0};/* 定义三个字符数组并进行初始化 */
a=read(number1);
/*调用函数读入数据 */ printf(“请输入'+'或'-': ”);中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名: 3
《C语言程序设计》课程设计
scanf(“%c”,&op);/* 读入'+'或'-' */
getchar();
/* 读入回车符 */
b=read(number2);
m=(a>=b?a:b)+1;
n=(a<=b?a:b);
switch(op)
{
case '+':
increase(number1,number2,number,m,n,a,b);
output(number,m);
break;
case '-':
calculate(number1,number2,number,m,n,a,b);
break;
default:
printf(“输入错误!n”);
}
printf(“你想继续吗?输入y表示继续,输入n表示放弃:”);
scanf(“%c”,&ans);getchar();}while((ans=='Y')||(ans=='y'));return 0;}
int read(char str[N]){ int i;使用循环读入数据,储存到字符数组
return i;
/* 用i返回字符串长度即大正整数位数 */ 中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名:4
《C语言程序设计》课程设计
}
void increase(char str1[N],char str2[N],char str[N],int m,int n,int a,int b){ 利用字符‘0’到‘9’的ASCII码进行加法运算,注意进位;
当a、b不同时,要考虑a、b的大小,当较小的那个数累加完后,仔细思考另一个数剩余位上的数与进位的数相加后是否进位及进位后该位数字;
return;}
void output(char str[N],int m){ 逐个输入每位数字,考虑第一位是否为0,如果是0,则不能输出改为数字;
return;}
void calculate(char str1[N],char str2[N],char str[N],int m,int n,int a,int b){ printf(“结果是: ”);if(a>b){
} else if(a
decrease(str2,str1,str,m,n,b,a);printf(“-”);/*考虑到结果可能是负数*/ print(str,m);中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名:
decrease(str1,str2,str,m,n,a,b);/*调用函数计算*/ print(str,m);/*调用函数输出*/
《C语言程序设计》课程设计
} else /* a=b */ {
} return;}
void decrease(char str1[N],char str2[N],char str[N],int m,int n,int a,int b){ 减法运算,考虑借位,分a、b相等和不等进行讨论;
return;}
void print(char str[N],int m)if(strcmp(str1,str2)>0){
} else if(strcmp(str1,str2)<0){
} else /* strcmp(str1,str2)==0 */ { } printf(“0n”);decrease(str2,str1,str,m,n,b,a);printf(“-”);print(str,m);decrease(str1,str2,str,m,n,a,b);print(str,m);中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名: 6
《C语言程序设计》课程设计
{ 输出结果;
return;}
2、整个程序流程图如下: 开始输入数据和运算符加法判断运算符减法计算算运计算它其输出输入错误!输出是否继续YESON结束
五、调试分析
中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名:
《C语言程序设计》课程设计
1、关于用字符数组来储存输入的数据
我最初的想法是用整型数组来储存数据,将数据一次输入,但在执行时无法用strlen来计算数据位数,所以我使用字符数组,但现在想想用整型数组也是可以的,只要将一个数的相邻两位之间都加入空格,而且计算时会简单很多,但这样的输入很不方便。
2、关于加减时出现的问题
(1)利用字符0-9的ASCII进行计算、转化,再输出字符0-9,需要掌握其中规律,容易出错;
(2)需要注意加减运算可能出现的进位和退位的问题;(3)需要考虑两个数据长度不同时,其中每个循环的控制条件;
3、关于输出的问题
(1)需要考虑两个整数相加时结果的位数是否增加,如果没有增加,如何在输出时消除首位的0;
(2)需要考虑两个整数相减时,结果的正负,输出时结果前的0。
六、测试结果
1、加法运算
(1)位数增加
(2)位数不增加
中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名:
《C语言程序设计》课程设计
2、减法运算
(1)结果为正
(2)结果为负
(3)结果为0
3、运算符输入错误 中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名: 9
《C语言程序设计》课程设计
七、用户使用说明
本程序的算法简单明确,但在实际的编码过程中却遇到了不少细节问题,分多种情况讨论,导致程序相对较长和复杂,还好的是实际操作简单,用户只需要根据提示进行输入便可得到结果,而且可以根据用户的选择重复计算。
八、课程设计总结
1、本次课程设计难度较大,是我学习C语言以来用时最长、代码最长的一次编程。
2、本次的课程设计加深了我对C语言的了解,强化了相关知识,也提高了我对自己专业的学习兴趣。
3、本次课程设计的所有内容均为自己独立思考完成的,一定程度上加强了自己的实践能力和思考能力。
4、本次课程设计加强了我对文档排版的重视,在准备材料时首次使用绘图软件,也算是一种收获。
中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名:
《C语言程序设计》课程设计
源代码:
/* 函数功能:输入两个大正整数,利用字符数组 对其进行加法运算或减法运算,并输出结果 */
#include
#define N 100 int read(char str[N]);/* 用数组读入大正整数 */ void increase(char str1[N],char str2[N],char str[N],int m,int n,int a,int b);/* 对两个大正整数进行加法运算 */ void output(char str[N],int m);/* 输出两个大正整数相加后的结果 */ void decrease(char str1[N],char str2[N],char str[N],int m,int n,int a,int b);/* 对两个大正整数进行减法运算 */ void print(char str[N],int m);/* 输出两个大正整数相减后的结果 */ void calculate(char str1[N],char str2[N],char str[N],int m,int n,int a,int b);/* 比较两个大正整数的大小,分别执行不同的操作 */ int main(){ int a,b,m,n;char op,ans;do { 中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名: 11
《C语言程序设计》课程设计
char number1[N]={0},number2[N]={0},number[N]={0};/* 定义三个字符数组并进行初始化 */
a=read(number1);
/* 读入第一个大正整数 */
printf(“请输入'+'或'-': ”);
scanf(“%c”,&op);/* 读入'+'或'-' */
getchar();
/* 读入回车符 */
b=read(number2);/* 读入第二个大正整数 */
m=(a>=b?a:b)+1;
n=(a<=b?a:b);
switch(op)
{
case '+':
increase(number1,number2,number,m,n,a,b);
output(number,m);
break;
case '-':
calculate(number1,number2,number,m,n,a,b);
break;
default:
printf(“输入错误!n”);
}
printf(“Do you want continue?Y for yes,N for no:”);
scanf(“%c”,&ans);getchar();}while((ans=='Y')||(ans=='y'));return 0;}
int read(char str[N])中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名:12
《C语言程序设计》课程设计
{ int i;printf(“请输入一个正整数: ”);for(i=0;;i++){
} return i;}
void increase(char str1[N],char str2[N],char str[N],int m,int n,int a,int b){ char c,d='0';int i;for(i=1;i<=n;i++){
c=str1[a-i]+str2[b-i]-48;/* 利用ASCII码对字符进行处理 */ c=c+d-48;d='0';if(c>'9'){
} str[m-i]=c;c=c-10;d=d+1;/* 用i返回字符串长度即大正整数位数 */ scanf(“%c”,&str[i]);if(str[i]=='n'){ } break;中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名: 13
《C语言程序设计》课程设计
} if(a>=b){ for(i=n+1;i<=a;i++){
c=str1[a-i]+d-48;
d='0';
if(c>'9')
{
c=c-10;
d=d+1;
}
str[m-i]=c;} str[0]=d;} else { for(i=n+1;i<=b;i++){
c=str2[b-i]+d-48;
d='0';
if(c>'9')
{
c=c-10;
d=d+1;
}
str[m-i]=c;} 中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名:14
《C语言程序设计》课程设计
str[0]=d;} return;}
void output(char str[N],int m){ int i;printf(“结果是: ”);if(str[0]=='1'){
for(i=0;i { printf(“%c”,str[i]); } printf(“n”);} else { for(i=1;i { printf(“%c”,str[i]); } printf(“n”);} return;} 中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名:15 《C语言程序设计》课程设计 void calculate(char str1[N],char str2[N],char str[N],int m,int n,int a,int b){ printf(“结果是: ”);if(a>b){ decrease(str1,str2,str,m,n,a,b); print(str,m);} else if(a decrease(str2,str1,str,m,n,b,a); printf(“-”); print(str,m);} else /* a=b */ { if(strcmp(str1,str2)>0) { decrease(str1,str2,str,m,n,a,b); print(str,m); } else if(strcmp(str1,str2)<0) { decrease(str2,str1,str,m,n,b,a); printf(“-”); print(str,m); } else /* strcmp(str1,str2)==0 */ 中南民族大学计算机科学学院计算机科学与技术专业 学号:姓名: 16 《C语言程序设计》课程设计 } { } printf(“0n”);return;} void decrease(char str1[N],char str2[N],char str[N],int m,int n,int a,int b){ char c;int i;for(i=1;i<=n;i++){ } for(i=n+1;i<=a;i++){ if(str1[a-i]<'0'){ } str[m-i]=str1[a-i];str1[a-i]=str1[a-i]+10;str1[a-i-1]=str1[a-i-1]-1;c=str1[a-i]-str2[b-i]+48;if(c<'0'){ } str[m-i]=c;c=c+10;str1[a-i-1]=str1[a-i-1]-1;中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名: 17 《C语言程序设计》课程设计 } return;} void print(char str[N],int m){ int i;for(i=1;;i++){ if(str[i]!='0') { break; } } for(i;i printf(“%c”,str[i]);} printf(“n”);return;} 中南民族大学计算机科学学院计算机科学与技术专业 学号: 姓名:18 扩频实验报告 学 院: 电子信息工程学院 专 业: 通信工程 组员: 12211008 吕兴孝 12211010 牟文婷 12211096 郑羲 12211004 冯顺 任课教师: 姚冬萍 1实验四 扩频实验 一、实验目标 在本实验中你要基于labview+usrp平台实现一个扩频通信系统,你需要在对扩频技术有一定了解的基础上编写程序,完成所有要求的实验任务。在这一过程中会让你对扩频技术有更直接和感性的认识,并进一步掌握在labview+usrp平台上实现通信系统的技巧。 二、实验环境与准备 软件环境:labview 2012(或以上版本); 硬件环境:一套usrp和一台计算机; 实验基础:了解labview编程环境和usrp的基本操作; 知识基础:了解扩频通信的基本原理。 三、实验介绍 1、扩频通信技术简介 扩频通信技术是一种十分重要的抗干扰通信技术,可以大大提高通信系统的抗干扰性能,在电磁环境越来越恶劣的情况下,扩频技术在诸多通信领域都有了十分广泛的应用。 扩频技术简单来讲就是将信息扩展到非常宽的带宽上——确切地说,是比数据速率大得多的带宽。在扩频系统中,发端用一种特定的调制方法将原始信号的带宽加以扩展,得到扩频信号;然后在收端对接收到的扩频信号进行解扩处理,把它恢复为原始的窄带信号。 扩频系统之所有具有较强的抗干扰能力,是因为接收端在接收到扩频信号后,需要通过相关处理对接收信号进行带宽的压缩,将其恢复成窄带信号。对于干扰信号而言,由于与扩频信号不相关,所以会被扩展到很宽的频带上,使之进入信号带宽内的干扰功率大幅下降,即增加了相关器输出端的信号/干扰比。因此扩频系统对大多数人为干扰都具有很强的抵抗能力。 22、发射端程序简介 本实验包括发射端和接收端两个主程序,其中发射端主程序top_tx的前面板如图1所示。 图1 发射端程序前面板 前面板上部的选项卡控件中可以配置各项参数。在硬件参数部分中可以配置usrp的ip地址、载波频率等参数;在信号参数部分中可以配置调制方式、设配采样速率、成型滤波器等参数;在信道模型参数部分中你可以选择不同的信道模型并设置噪声功率;在右侧你可以设置扩频码的长度。在前面板下方为显示界面,包括发送信号的时域/频域波形以及星座图和眼图。 发射端的程序框图主要由两部分组成。 主程序框图左侧的transmitter子程序完成发射信号的生成、扩频、调制等功能,程序框图如图2所示。 3图2 transmitter的程序框图 3、接收端程序简介 接收端主程序top_rx的前面板如图3所示。 图3 接收端程序前面板 与发射端程序类似,接收端主程序前面板上部为各项参数的输入,例如硬件参数、扩频参数、同步参数等。前面板下部显示生成的图形,包括星座图、眼图、信噪比/误码率曲线等。接收端端的程序框图也主要由两部分组成。 主程序框图右侧的receiver.vi子程序主要完成发射信号的接受、同步、解扩和解调等功能,程序框图如图3所示。4 图3 receiver.vi 的程序框图 matched filter子程序完成匹配滤波;其中rx init子程序是接收机的初始化; synch子程序使同步模块,完成收发同步;channel estimated子程序完成信道估计;equalize子程序的作用是信道均衡;strip control子程序用来删除控制信息,即训练序列;decode子程序实现信号的解调;de-dsss子程序用来实现解扩;error detect子程序的作用是计算误码率。 接收端主程序框图的其他部分主要用来完成usrp的配置、计算信噪比/误码率曲线以及生成所需的图形。 四、实验任务 1、ds-ss.vi子程序 ds-ss子程序的作用是对信源进行直接扩频(direct sequence spread spectrum)。其原理是利用10个以上的chips来代表原来的0或1,使得原来较高功率、较窄的频谱变成具有较宽频的低功率频谱,这种特性类似于噪声功率谱,因此接收端只有知道正确的扩频码才能进行正确的接收,进而增加了传输的可靠性。它是一种数字调制方法,具体说,就是将信源与一定的pn码(伪随机码、chip)进行同或运算。例如,在发射端用11000100110代替1,用00110010110代替0,这个过程就实现了扩频。上述过程如图4所示。 图4 扩频的实现过程 前面板: 图6 ds-ss前面板 ds-ss程序框图: 图7 ds-ss程序框图 实验步骤: 1、首先产生所需长度的伪随机序列(pn序列): pn序列(pseudo-noise sequence)即伪噪声序列,这类序列具有类似随机噪声的一些统计特性,但和真正的随机信号不同,它可以重复产生和处理,故称作 pn码最见的用途是在扩频系统中用来扩展信号频谱;伪随机噪声序列。此外pn 码也可以用来作为信源信息。 图8 mt generate bits输入输出 其中total bits为生成的伪随机序列的总长度、pn sequence order用来设定pn序列的循环周期(如果pn sequence order设为n,则周期为)、seed in指定pn序列生成器移位寄存器的初始状态(默认为0xd6bf7df2);output bit stream为伪随机序列的输出。 此外mt generate bits函数还有user defined模式,在此模式下函数可以 根据用户自定义的输入序列生成所需长度的循环序列。其输入输出如图9所示: 图9 user defined模式的输入输出 其中user base bit pattern为用户指定的序列,控件会不断循环用户指定的序列output bit stream为生成序列的直到输出序列的长度达到total bits所设定的值。输出。 本例中用到了三个mt generate bits函数,分别用来生成保护序列、同步序列和信息序列。 2、利用产生的序列对信源序列进行扩展: 图10 扩频模块 输入信源bit码、pn扩频码、误差;输出扩频码、误差。 72、de-dsss.vi子程序 de-dsss子程序的作用是在接收端实现对信号的解扩。解扩操作即扩频操作的逆过程。继续使用上面的例子,当你在发射端用11000100110代替1,而用00110010110代替0后,在接收机处只要把收到的序列是11000100110恢复成1,而00110010110恢复成0,这就是解扩。上述过程如图0所示。 图11 解扩的实现过程 前面板: 图12 de-dsss前面板 de-dsss程序框图: 图13 de-dsss程序框图 五、实验步骤: 1、产生所需长度的并与发射端相同伪随机序列(pn序列),同ds-ss; 2、然后利用产生的序列对接收信号进行解扩: 输入:将信源与pn序列通过“数组大小”模块返回其长度,相除得到的商作为搜索深度;输入经信道传输后的扩频码、与发送端同步的扩频序列以及误差。输出得解扩后码序列以及误差。 3、实验验证 在ds-ss子程序中,你可以手动输入一串0/1作为信源序列,并设置好pn序列的长度(设为n)。单独运行ds-ss子程序,观察输出的序列长度是否扩展了n倍,并注意输出序列中pn码是否与相应的0或者1对应。验证成功的话便表明你的ds-ss子程序编写正确。并利用类似的方法验证de-dsss子程序的正确性。 然后验证发射端主程序是否能正确的发射我们想要的扩频信号。首先正确的连接usrp并合理的配置发射端的各项参数,运行程序。 然后你可能会看到如图 9至图所示的发射信号时域波形和频域波形。 图14不扩频的时域信号 图16扩频后的时域信号 图17扩频后的频域信号 图15不扩频的频域信号 10可以看出经过扩频的发射信号与不经过扩频的发射信号相比,在频域上进行 了展宽,在时域上变得更加密集。这与扩频的基本原理相符,说明发射端的设计基本正确。 在接收端,我们需要使得参数能够与发射端匹配,这样才能正常的接收。特 别需要注意capture time、packet length和rx sample rate这几个参数,你首先需要理解它们的意义,这样才能够正确的配置它们。如果你在发射端没有修改默认参数的话,接收端的默认参数恰好能够与发射端匹配。你需要同时运行发射端和接收端程序,在发射端正确运行时观察接收端能否正确接收。程序会计算当前信噪比下的误码率,并逐渐增大信噪比、最终得出一条信噪比/误码率曲线,如图3-4-11所示。你可能需要稍等一段时间才能够看到程序运行完成的结果。在接收端程序运行的同时,你可以进入receiver子程序中的ber detected子程序,在里面观察当前信噪比接收到的数据数和误码数,如图3-4-12所示。 图18误码率曲线 图19运行时的数据显示 然后你可以尝试改变收发端的各项参数,观察不同参数对运行结果的影响。最后你需要按照要求完成实验报告。 六、实验结果 qpsk: 将usrp连接电脑,更改ip地址等参数。频率使用915mhz避免干扰。如下图20: 11 发送端前面板调制参数以及发送星座图发送时域波形如下图21: 发送端眼图和发送端频域波形如下,眼图的尖锐程度和发送频率有关,如图22: 接收端的硬件参数和误码率如下图,如图23: 接收端眼图如图24所示: bpsk: 调制参数如下: 14bpsk:发送端硬件参数 发送端星座图: 接收端眼图: 接收端星座图及误码率曲线(信噪比较低): 五、实验扩展 1、解释接收端同步模块的具体实现方式及其利用的基本原理。 (1)初始同步,或称粗同步、捕获。它主要解决载波频率和码相位的不确定性,保 证解扩后的信号能通过相关器后面的中频滤波器,这是所有问题中最难解决的问题。 (2)跟踪,或称精同步。 接收机对接收到的信号,首先进行搜索,对收到的信号与本地码相位差的大小进行判断,若不满足捕获要求,即收发相位差大于一个码元,则调整时钟再进行搜索。直到使收发相位差小于一个码元时,停止搜索,转入跟踪状态。图3-4-5同步流程图 图3-4-6跟踪流程图 2、扩频通信技术除了有较强的抗干扰能力外,还具有哪些优点?逐一例举出来并简述扩频技术具有这些优点的原因。 (1)易于重复使用频率,提高了无线频谱利用率 无线频谱十分宝贵,虽然从长波到微波都得到了开发利用,仍然满足不了社会 17的需求。在窄带通信中,主要依靠波道划分来防止信道之间发生干扰。为此,世界各国都设立了频率管理机构,用户只能使用申请获准的频率。扩频通信发送功率极低,采用了相关接收技术,且可工作在信道噪声和热噪声背景中,易于在同一地区重复使用同一频率,也可与各种窄道通信共享同一频率资源。所以,在美国及世界绝大多数国家,扩频通信无须申请频率,任何个人与单位都可以无执照使用。 (2)抗干扰性强,误码率低 扩频通信在空间传输时所占用的带宽相对较宽,而接收端又采用相关检测的办法来解扩,使有用宽带信息信号恢复成窄带信号,而把非所需信号扩展成宽带信号,然后通过窄带滤波技术提取有用的信号。这样,对于各种干扰信号,因其在接收端的非相关性,解扩后窄带信号中只有很微弱的成分,信噪比很高,因此抗干扰性强。在商用的通信系统中,扩频通信是唯一能够工作在负信噪比条件下的通信方式。 (3)隐蔽性好,对各种窄带通信系统的干扰很小 由于扩频信号在相对较宽的频带上被扩展了,单位频带内的功率很小,信号湮没在噪声里,一般不容易被发现,而想进一步检测信号的参数如伪随机编码序列就更加困难,因此说其隐蔽性好。再者,由于扩频信号具有很低的功率谱密度,它对使用的各种窄带通信系统的干扰很小。 (4)可以实现码分多址 扩频通信提高了抗干扰性能,但付出了占用频带宽的代价。如果让许多用户共用这一宽频带,则可大大提高频带的利用率。由于在扩频通信中存在扩频码序列的扩频调制,充分利用各种不同码型的扩频码序列之间优良的自相关特性和互相关特性,在接收端利用相关检测技术进行解扩,则在分配给不同用户码型的情况下可以区分不同用户的信号,提取出有用信号。这样一来,在一宽频带上许多对用户可以同时通话而互不干扰。 (5)抗多径干扰 这两种技术在扩频通信中都易于实现。利用扩频码的自相关特性,在接收端从多径信号中提取和分离出最强的有用信号,或把多个路径来的同一码序列的波形相加合成,这相当于梳状滤波器的作用。另外,在采用频率跳变扩频调制方式的扩频系统中,由于用多个频率的信号传送同一个信息,实际上起到了频率分集的作用。 (6)能精确地定时和测距 电磁波在空间的传播速度是固定不变的光速,人们自然会想到如果能够精确测 18量电磁波在两个物体之间的传播时间,也就等于测量两个物体之间的距离。在扩频通信中如果扩展频谱很宽,则意味着所采用的扩频码速率很高,每个码片占用的时间就很短。当发射出去的扩频信号在被测量物体反射回来后,在接收端解调出扩频码序列,然后比较收发两个码序列相位之差,就可以精确测出扩频信号往返的时间差,从而算出两者之间的距离。测量的精度决定于码片的宽度,也就是扩展频谱的宽度。码片越窄,扩展的频谱越宽,精度越高。 (7)适合数字话音和数据传输,以及开展多种通信业务 扩频通信一般都采用数字通信、码分多址技术,适用于计算机网络,适合于数据和图像传输。 (8)安装简便,易于维护 扩频通信设备是高度集成,采用了现代电子科技的尖端技术,因此,十分可靠、小巧,大量运用后成本低,安装便捷,易于推广应用。 3、伪随机序列有许多种,例如m序列、gold序列、m序列等。尝试使用不同的方法来产生伪随机序列,并用其实现对信号的扩频。 (1)m序列是目前广泛应用的一种伪随机序列,m序列每一周期中 1 的个数比 0 的个数多 1 个。状态“0”或“1”连续出现的段称为游程。游程中“0”或“1” m序列的一个周期(p=2^n-1)中,的个数称为游程长度。游程总数为 2^n-1,“0”、“1” 各占一半。2个彼此移位等价的相异m序列,按模2相加所得的序列仍为m序列,并与原m序列等价。 (2)gold序列gold码序列是一种基于m序列的码序列,具有较优良的自相关和互相关特性,产生的序列数多。gold码的自相关性不如m序列,具有三值自相关特性;互相关性比m序列要好,但还没有达到最佳。是由两个码长相等、码时钟速率相同的m序列优选对通过模2相加而构成的。 4、适当的在系统中添加干扰,以验证扩频的良好的抗干扰能力。 强扩频通信系统扩展的频谱越宽,处理增益越高,抗干扰能力就越强。简单 地说,如果信号频谱展宽10倍,那么干扰方面需要在更宽的频带上去进行干扰,分散了干扰功率,从而在总功率不变的条件下,其干扰强度只有原来的1/10。另外,由于接收端采用扩频码序列进行相关检测,空中即使有同类信号进行干扰,如果不能检测出有用信号的码序列,干扰也起不了太大作用,因此抗干扰性能强是扩频通信的最突出的优点。19 20 C语言课程设计报告——刘显安 C语言课程设计 姓名:刘显安 学号:09041131 班级:090411 专业:计算机科学与技术 学院:信息工程学院 设计题目:学生通讯录管理系统 指导教师:宋文琳 提交时间:2010年9月4日 第1页(共25页) C语言课程设计报告——刘显安 课程题目:学生通讯录管理系统 要求:学生通讯录信息包括:学号、姓名、班机、联系电话、E-mail、宿舍等 主要功能:1、2、3、4、5、通讯录信息录入功能 通讯录信息删除功能 通讯录信息浏览功能 通讯录信息查询功能 按学号排序功能 一、总体设计 首先,整个系统必须有一个主函数,为了尽量提高程序的易修改性,且不至于相互干扰,将每一个功能分成不同的模块,用不同的函数来实现,例如在我写的这个程序中,一共用了11个函数,分别是: 主菜单函数menu()、关于函数gaunyu()、帮助函数help()、输出单个学生信息函数shuchu()、输入函数shuru()、输出所有学生信息函数findall()、按姓名查找函数findname()、按学号查找函数findnum()、删除函数shanchu()、排序函数paixu()、主函数main(),这样在整个程序的设计过程中也就一目了然,写起来也相对轻松了不少。 这个程序我只是总体上参考了一下网上程序的架构,具体的各个函数是参照课本上《链表》那一章的内容的,比如结构体的建立、查找和排序等功能,这些书上都有类似的,其中排序功能虽没有原版的,第2页(共25页) C语言课程设计报告——刘显安 但是在第六章中有一个用冒泡法排序的例题,我就是仿照这个模式来对结构体进行排序的,总之整个程序中蕴含了我很多的汗水。 二、具体设计 关于这个程序的具体设计,也不是一两句话就能说完的,所以我也不想再在这里赘述了,因为程序里都可以看的到,几乎每个函数都倾注了我的大量汗水,我在这上面花了不少的时间,不过从中也收获了很多,因为不停地修改不停的调试,总之还是直接看源程序吧,因为也没必要在这里重复地说废话。 三、源代码 以下是整个程序的源代码,其中我的主菜单函数是很美观的,但由于这里字体和板式的限制,不能很好的显现,可以看我下面程序运行的截图就知道了。—————————————————— #include struct student{ 第3页(共25页) C语言课程设计报告——刘显安 long num;char name[20];int banji;char tel[11];char Email[20];int sushe;struct student *next;}; struct student *stu;int n; void menu(void){ /*主菜单函数*/ system(“cls”);puts(“****************************************************************************”);puts(“** ^_^学生通讯录管理系统^_^ **”);puts(“****************************************************************************”);puts(“******** 计 ********”); 第4页(共25页) C语言课程设计报告——刘显安 puts(“******* *******”);puts(“****** 算 ******”);puts(“***** 0 1=录入学生通讯录信息 *****”);puts(“**** 9 机 ****”);puts(“*** ***”);puts(“** 科 **”);puts(“* *”);puts(“** 1 学 **”);puts(“*** ***”);puts(“**** 与 ****”);puts(“***** *****”);0 4 刘 2= 显 安 6= 第5页(共25页) 列出所有学生通讯录 3=按姓名查询信息 4=按学号查询信息 5=删除学生信息 按学号将通讯录排序 7=关于 8=帮助 0=退出 C语言课程设计报告——刘显安 puts(“****** 技 ******”);puts(“******* *******”);puts(“******** 术 ********”);puts(“****************************************************************************”);} void guanyu()/*关于函数*/ { system(“cls”);puts(“n ************************** ”);puts(“ *** 版权所有,翻版必究!***”);puts(“**** copyright◎刘显安!****”);puts(“ *** 2009~2010 ***”);puts(“ **************************”);puts(“n返回主菜单请按【9】”);if(getche()=='9')menu();} struct student *shuru(void)/*输入函数*/ 第6页(共25页) C语言课程设计报告——刘显安 { system(“cls”);struct student *s1,*s2;n=1;int num;puts(“请输入学生个数(提示:个数不能输入0!):”);scanf(“%d”,&num);s1=s2=(struct student *)malloc(sizeof(struct student));puts(“*************************************************”);puts(“请输入学号:”);scanf(“%ld”,&s1->num);puts(“请输入学生姓名:”);scanf(“%s”,s1->name);puts(“请输入班级:”);scanf(“%d”,&s1->banji);puts(“请输入电话号码:”);scanf(“%s”,s1->tel);puts(“请输入电子邮件:”);scanf(“%s”,s1->Email);puts(“请输入学生宿舍号:”);scanf(“%d”,&s1->sushe);stu=s1; 第7页(共25页) C语言课程设计报告——刘显安 while(n 第8页(共25页) C语言课程设计报告——刘显安 s2=s1;s2->next=NULL;return(stu);//system(“cls”);} void shuchu(struct student *s){ /*输出单个学生信息*/ printf(“* %-8ld”,s->num);printf(“%-15s”,s->name);printf(“%-8d”,s->banji);printf(“%-15s”,s->tel);printf(“%-15s”,s->Email);printf(“%-5d *n”,s->sushe);} void findall()/*输出所有学生信息*/ { system(“cls”);struct student *s;//if(n=2)//printf(“n现在有%d个学生信息,分别是:n”,n);//else 第9页(共25页) C语言课程设计报告——刘显安 printf(“n现在有%d个学生信息,分别是:n”,n);puts(“________________________________________________________________________”);puts(“* 学号 姓名 班级 电话 电子邮件 宿舍 *”);s=stu;while(s!=NULL){ shuchu(s);s=s->next;} puts(“________________________________________________________________________”);puts(“返回主菜单请按【9】”);if(getche()=='9')menu();} void findname(){ /*按姓名查找函数*/ system(“cls”);struct student *s;char name[20];printf(“n请输入你要查询的学生姓名:n”); 第10页(共25页) C语言课程设计报告——刘显安 scanf(“%s”,name);s=stu;while(strcmp(s->name,name)!=0){ s=s->next;} if(s==NULL){ puts(“查无此学生姓名!”);goto end;} else { puts(“该学生的信息为:”);puts(“* 学号 姓名 电子邮件 宿舍 *”);shuchu(s);} end:;puts(“返回主菜单请按【9】”);if(getche()=='9')menu();} 第11页(共25页) 班级 电话 C语言课程设计报告——刘显安 void findnum()/*按学号查找函数*/ { system(“cls”);struct student *s;puts(“请输入你要查询的学生学号:”);long i;scanf(“%ld”,&i);s=stu; while(s->num!=i){ s=s->next;} if(s==NULL){puts(“查无此学生学号!”);goto end;} else { puts(“该学生的信息为:”);puts(“* 学号 姓名 班级 邮件 宿舍 *”);shuchu(s); 第12页(共25页) 子电话 电C语言课程设计报告——刘显安 } end:;puts(“返回主菜单请按【9】”);if(getche()=='9')menu();} struct student *shanchu(struct student*stu)/*删除函数*/ { system(“cls”);long num;char s;struct student *s1,*s2;if(stu==NULL){ puts(“傻冒!没有任何学生信息,还删个屁啊,删删删!”);goto end;} puts(“请输入你要删除的学生学号:”);scanf(“%ld”,&num);s1=stu;puts(“警告:你确定要删除这个学生的信息吗(Y/N)?”);scanf(“%s”,&s); 第13页(共25页) C语言课程设计报告——刘显安 if((s=='Y')||(s=='y')){ while((num!=s1->num)&&(s1->next!=NULL)){s2=s1;s1=s1->next;} if(num==s1->num){ puts(“该学生的信息为:”);puts(“* 学号 姓名 班级 电话 电子邮件 宿舍 *”);shuchu(s1);if(s1==stu)stu=s1->next;else s2->next=s1->next;puts(“注意哟,该学生的信息已经删除了!剩下的学生通讯录信息如下:”);n=n-1;} } findall();return(stu);end:; 第14页(共25页) C语言课程设计报告——刘显安 puts(“返回主菜单请按【9】”);if(getche()=='9')menu();} void paixu(){ /*排序函数*/ struct student *p, *p1,*p2;int i,j;int temp;char b[20];if(stu==NULL){printf(“n学生信息不存在n”);goto end;} for(i=0;i {temp=p1->num;p1->num=p2->num;p2->num=temp; strcpy(b,p1->name);strcpy(p1->name,p2->name);strcpy(p2->nam 第15页(共25页) C语言课程设计报告——刘显安 e,b); temp=p1->banji;p1->banji=p2->banji;p2->banji=temp; strcpy(b,p1->tel);strcpy(p1->tel,p2->tel);strcpy(p2->tel,b); strcpy(b,p1->Email);strcpy(p1->Email,p2->Email);strcpy(p2->Email,b);temp=p1->sushe;p1->sushe=p2->sushe;p2->sushe=temp; } p1=p1->next;} } p=stu;puts(“已按学生学号顺序排序完毕!重新排序如下:”); puts(“****************************************************************************”);puts(“* 学号 姓名 班级 电话 电子邮件 宿舍 *”); while(p!=NULL) 第16页(共25页) C语言课程设计报告——刘显安 { printf(“* %-8ld”,p->num);printf(“%-15s”,p->name);printf(“%-8d”,p->banji);printf(“%-15s”,p->tel);printf(“%-15s”,p->Email);printf(“%-5d *n”,p->sushe);p=p->next;} end:;puts(“返回主菜单请按【9】”);if(getche()=='9')menu();} void help()/*帮助函数*/ { system(“cls”);puts(“n1、请按提示操作,第一次进入本系统时请按“1”录入学生信息,”);puts(“ 否则有可能造成程序运行错误!”);puts(“ 2、添加、修改功能本系统暂不提供,还有待以后完善,谢谢 第17页(共25页) C语言课程设计报告——刘显安 合作!”);puts(“ 3、请注意查看“Num Lock”是否打开,如果没有打开,则按数字n 键可能导致程序错误!”);puts(“ 4、版权所有,翻版必究!请按“7”键查看关于。”);puts(“n返回主菜单请按【9】”);if(getche()=='9')menu();} void main()/*主函数*/ { char a;menu();puts(“n您为首次使用本系统,强烈建议您按1开始录入学生信息,”);puts(“否则有可能导致程序运行错误!您可以按8查看帮助.”);a=getche();while(a){ puts(“");switch(a){case'0':goto end;break;case '1': puts(”n好了,您可以开始向本系统录入学生通讯录信息了: 第18页(共25页) C语言课程设计报告——刘显安 “);stu=shuru();system(”cls“);menu();puts(”n学生信息录入完毕,请输入你的选择(0~6):n“); break;case '2':findall();puts(”n请输入你的选择(0~6):“);break;case '3':findname();puts(”n请输入你的选择(0~6):“);break;case '4':findnum();puts(”n请输入你的选择(0~6):“);break;case '5':stu=shanchu(stu);puts(”n请输入你的选择(0~6):“);break;case '6':paixu();puts(”n请输入你的选择(0~6):“);break;case '7':guanyu();puts(”n请输入你的选择(0~6):“);break;case '8':help();puts(”n请输入你的选择(0~6):“);break;default:puts(”输错了!笨蛋!快点按数字1键录入学生信息吧!“);break;} a=getche();} end:;puts(”谢谢您使用本系统,欢迎再次使用!"); 第19页(共25页) C语言课程设计报告——刘显安 } ————————————————————————— 四、调试 主要是通过截图来显示运行过程 以下是程序运行的主界面: 按1后,开始录入信息,程序会提示你输入学生个数(例如本例中输入4个),当输完4个学生的信息时,程序会提示你已输入完毕: 第20页(共25页) C语言课程设计报告——刘显安 学生信息录入完毕,提示输入(0到6)进行选择: 第21页(共25页) C语言课程设计报告——刘显安 这时我选择按2输出所有学生信息,按9返回: 按3按姓名查询信息: 按4按学号查询信息: 第22页(共25页) C语言课程设计报告——刘显安 按5删除学生信息,这是按学号删除学生信息,本例中,删除学号为41212的学生信息: 删除成功后,系统自动将剩下的学生信息列出: 按6按学号从小到大进行排序,可以发现,排序成功: 第23页(共25页) C语言课程设计报告——刘显安 按8查看帮助函数: 呵呵,这是我设置的关于函数,满足一下敝人的虚荣心嘛^_^,版权所有,翻版必究哦! 最后按0退出系统: 第24页(共25页) C语言课程设计报告——刘显安 呵呵,怎么样?我写的程序还行吧。嘿嘿…… 三、总结 这个程序我只是总体上参考了一下网上程序的架构,具体的各个函数是参照课本上《链表》那一章的内容的,比如结构体的建立、查找和排序等功能,这些书上都有类似的,其中排序功能虽没有原版的,但是在第六章中有一个用冒泡法排序的例题,我就是仿照这个模式来对结构体进行排序的,总之整个程序中蕴含了我很多的汗水。 第25页(共25页) 汇编语言课程设计要求 1.设计的目的和任务 (1)目的:课程设计是本科教学全过程中重要环节。其目的是培养计算机专业学生运用所学知识解决计算机应用领域内实际问题能力,进一步提高学生汇编语言综合编程能力,程序调试技能。 (2)任务:能够按照设计题目完成相应设计;撰写设计报告。 2.设计要求 完成设计任务,撰写设计报告,上交源程序和可执行程序,源程序加注释 3.设计地点 学院计算机实验室或自己的计算机 4.主要仪器设备(实验用的软硬件环境) 普通微机一台;汇编语言环境(基于DOS环境:EDIT、MASM、LINK、DEBUG;基于Windows环境) 5.设计内容 5.2 汇编程序设计的内容 题目自拟(每人单独一题),但必须有一定的难度和一定的设计工作量,可参考课本内容和设计辅导书内容,也可参考其它参考书。 6.问题讨论与分析 根据自己设计和调试过程出现的问题进行分析的讨论,并进行小结。 参考文献 1、詹仕华等编.《汇编语言程序设计》.北京:中国电力出版社.2008.2 2、詹仕华等编.《汇编语言程序设计习题解答及课程实验、设计辅导》.北京:中国电力出版社.2008.2 3、王爽编.《汇编语言》.北京:清华大学出版社,2003.5 4、曹加恒等编.《新一代汇编语言课程设计》.北京:高等教育出版社,2003.6 5、杨路明等编.《汇编语言程序设计》.长沙:中南大学出版社,2005.8 实验室观看设计结果时间和上交设计报告时间:6月24日,地点:学院机房。 附课程设计大纲 《汇编语言》课程设计 课程名称(中文):汇编语言 课程名称(英文):Assembly Language 总周数:1周学分数:1分 1.目的及任务 (1)目的:课程设计是本科教学全过程中重要环节。其目的是培养电子信息专业学生运用所学知识解决计算机应用领域内实际问题能力,进一步提高学生汇编语言综合编程能力,程序调试技能。 (2)任务:能够按照设计题目完成相应设计;撰写设计报告。2.要求 完成设计任务,撰写设计报告,上交源程序和可执行程序,源程序加注释。3.面对专业 电子信息工程、计算机科学与技术 4.成绩评定 设计过程和结果自述占50%,课程设计报告占50%。5.主要仪器设备、工具书、参考文献资料 主要仪器设备:通用PC机 工具书:课程教材 参考文献资料: 沈美明、温冬蝉编著,《IBM-PC汇编语言程序设计》清华大学出版社; 王爽编著《汇编语言》 清华大学出版社 长整数加减的运算 一、需求分析 问题描述: 设计一个实现任意长的整数进行加法运算的演示程序 基本要求: 利用双向循环链表实现长整数的存储,每个结点含一个整型变量。任何整型变量的范围是 -(2 15 -1)~(2 15 -1)。输入输出形式:按照中国对于长整数的表示习惯,每四位是一组,组间用逗号隔开 更高要求: (1)长整数的减法 (2)多个长整数的连续加减法,并带括号等。具体方式可以参见表达式的求值部分,利用栈 测试数据: (1)0;0;应输出“0” (2)-2345,6789;-7654,3211;应输出“-1,0000,0000” (3)-9999,9999;1,0000,0000,0000;应输出“9999,0000,0001”(4)1,0001,0001;-1,0001,0001;应输出“0”(5)1,0001,0001;-1,0001,0000;应输出“1” (6)-9999,9999,9999;-9999,9999,9999;应输出“-1,9999,9999,9998”(7)1,0000,9999,9999;1;应输出“1,0001,0000,0000” 一、概要设计 1.数据结构 此实验采用的数据结构是双向循环链表。这样可以很容易的找到他的前驱以及它的后继。节点采用结构体类型,代码如下:typedef struct Node // 双向链表的结构体定义 { int data; struct Node *prior;struct Node *next;}DLNode; 2.使用函数 1)void ListInitiate(DLNode **head) 操作结果:初始化一个头结点为head的双向循环链表; 2)int ListLength(DLNode *head) 操作结果:计算以head为头结点的链表的长度 3)int ListInsert(DLNode *head,int i,int x) 操作结果:将节点数据为x的节点插到第i个位置上去。4)int abs(int x) 操作结果:绝对值函数,返回x的绝对值。5)int InputNumber(DLNode *head) 操作结果:将从键盘中接收数据并把得到的数据存入以head为头结点的链表中。四位一存,中间以逗号区分,结束符为分号。6)void OutputNumber(DLNode *head,int sign) 操作结果:将以head为头结点的链表中的所有数据输出到显示屏上,7)void add(DLNode *head1,DLNode *head2,DLNode *head3)操作结果:实现正数加正数的加法操作。8)int change(DLNode *head1,DLNode *head2) 操作结果:判断存在俩个链表中的数的大小,如何head1中的数大于head2中的数那么返回值为0,反之返回值为1,相等时返回值为2; 9)void method(DLNode *head1,DLNode *head2,int x) 操作结果:计算正数乘以正数的乘法运算。 10)void minus(DLNode *head1,DLNode *head2,DLNode *head3)操作结果:计算正数减正数的减法运算。 11)void yunsuan(DLNode *head1,DLNode *head2,DLNode *head3,char ch) 操作结果:正数,负数,加法,减法。计算式共分为八种运算,在这之前我已经实现了二种运算,那么这个函数就是把这八种运算按照一定的规则转化成已经实现的二种运算来实现完整的加减法运算。 12)void chengfa(DLNode *head1,DLNode *head2) 操作结果:在乘法中我只是实现了正数乘以正数的运算,那么这个函数就是通过调用method函数按照一定的规则来实现完整的乘法运算。13)void main() 操作结果:主函数。调用以上的各个函数来引导用户进行长整数的加法运算,加法运算,乘法运算。 二、详细设计 1.数据结构详细设计 typedef struct Node // 双向链表的结构体定义 { int data;struct Node *prior;struct Node *next;}DLNode;双向循环链表的节点由三个部分组成,第一是数据部分data存储此节点的数据,第二是此节点的前驱指针部分*prior指向此节点的前驱,第三是此节点的后继指针部分*next指向此节点的后继。数据部分我们约定它为整形变量,前驱后继指针均为结构体Node类型。2.链表初始化函数: void ListInitiate(DLNode **head)//双向链表的初始化 { } if((*head=(DLNode *)malloc(sizeof(DLNode)))==NULL)exit(0);(*head)->prior=*head;(*head)->next=*head; 初始化之前需要定义一个类型为Node型的头结点变量,经过函数后完成链表的初始化即:头节点的前驱指针指向自己,同时他的后继指针也指向自己。3.计算已知的链表长度: int ListLength(DLNode *head)//双向链表的表长 { DLNode *p=head;int size=0;while(p->next!=head){ } p=p->next;size++;return size;} 此函数计算的是已知链表的长度。主要思想:从头结点开始寻找下一个节点,找到计数器加一。直到再次寻找到头结点时停止,计算完毕。 4.插入函数: int ListInsert(DLNode *head,int i,int x)//双向链表的数据插入,i表示是插入的第几个元素 { DLNode *p,*s;int j;p=head->next;j=0;while(p!=head&&j } if(j!=i){ } if((s=(DLNode *)malloc(sizeof(DLNode)))==NULL)exit(0);s->data=x;s->prior=p->prior;//插入 p->prior->next=s;s->next=p;p->prior=s;return 1;printf(“n插入位置不合法!”);return 0;p=p->next;j++; } 此函数是已知一双向链表实现在第i个位置插入data为x的节点。函数需要注意的是在什么位置插入才是合法的,在就是在该节点指针时的顺序不要搞错。5.绝对值函数: int abs(int x){ } if(x<0)return-x;else return x;此函数是实现求一个整数的绝对值。设计这么一个函数主要是考虑到在存储负数的时候头结点应该变为正整数,然后通过其他手段变相实现那种运算。6.读入数据并插入对应的链表函数: int InputNumber(DLNode *head)//读入输入的数据 { int input,i=0;//第i个节点 char c;scanf(“%d%c”,&input,&c);while(1){ if(input<0&&i==0)//输入数为负且是第一个节点 { } else if(input>=0&&i==0)//输入数为正且是第一个节点 { } else { } if(head->next->data>=0){ } //input=-1*input;ListInsert(head,i,input);ListInsert(head,i,input);//非第一个节点 else head->data=1;//将长整数的符号保存在头结点中 ListInsert(head,i,input);//插入数据 head->data=0;//将长整数的符号保存在头结点中 //input=abs(input);//取输入数字的绝对值 ListInsert(head,i,input);//插入数据 } } return 1;i++;if(c==';')break;//遇到数据输入完成标志,跳出循环 scanf(“%d%c”,&input,&c);此函数实现的是从键盘上得到数据根据三种情况进行不同的处理,判断是否是头结点,判断是否是整数,判断输入的字符是否是“;”分号。并且如果是正整数它的头结点data等于1否则为0。 7.输出函数 void OutputNumber(DLNode *head,int sign){ DLNode *r=head->next;while(r->data==0&&r!=head->prior){ r=r->next;} if(sign==1){ printf(“结果是:”);} else { printf(“结果是:-”);} printf(“%d”,r->data); r=r->next; while(r!=head) { if(r->data<10) { printf(“,000”); printf(“%d”,r->data); } else if(r->data<100) { printf(“,00”); printf(“%d”,r->data); } else if(r->data<1000){ //从表尾输出数据元素 } } printf(“n”); } else { } r=r->next; printf(“,%d”,r->data);printf(“,0”);printf(“%d”,r->data);此函数实现的是将最后的结果输出到显示屏上,经过判断数据的正负和数据的范围来进行不同的处理,以保证在显示屏上显示的是正确的格式。 8.不完整加法函数(只可实现正数加上正数) void add(DLNode *head1,DLNode *head2,DLNode *head3){ int z=0; if(p1==head1&&p2!=head2){ while(p2!=head2){ e=p2->data+z;if(e>=10000){ z=1;int e;DLNode *p1,*p2;p1=head1->prior;p2=head2->prior;while(p1!=head1&&p2!=head2){ e=p1->data+p2->data+z; } if(e>=10000){ } else z=0;ListInsert(head3,0,e);p1=p1->prior;p2=p2->prior;z=1;e=e%10000; } else z=0;ListInsert(head3,0,e);p2=p2->prior;e=e%10000;} if(z==1)ListInsert(head3,0,z);} else if(p1!=head1&&p2==head2){ while(p1!=head1){ e=p1->data+z; if(e>=10000){ } z=1;e=e%10000;else z=0;p1=p1->prior;ListInsert(head3,0,e);} if(z==1)ListInsert(head3,0,z);} else{ if(z==1)ListInsert(head3,0,z);} } 此函数实现的是两个正数之间的相加运算,主要的算法和我们手算加法是一样的,首先设置一个进位计数的变量,根据存储的特点从低位开始相加带上进位即可得出相应的位和,最后更新进位变量。处理边界状况:如果两个链表一样长同时他们最高位在计算完成时仍然会有进位,那么应该考虑到在数据的更高位插入一个1表示最后的计算结果,这样才可以保证数据的完整性。9.判断俩正数大小函数: int change(DLNode *head1,DLNode *head2){ int length1,length2,r=2;length1=ListLength(head1);DLNode *p1,*p2;p1=head1->next;p2=head2->next;length2=ListLength(head2); if(length1>length2){ } else if(length1 } else { } return r;} int i=0;for(i=0;i } if(p1->data>p2->data){ } else if(p2->data>p1->data){ } else { } p1=p1->next;p2=p2->next;r=2;r=1;return r;break;r=0;return r;break;r=1;return r;r=0;return r;此函数实现的是判断俩个正数的大小。考虑俩正数的在链表中所占存储单元的多少,多的一定大,当他们一样长时,一位一位的比较直到找到一个节点中的data比另一个链表的对应节点的data大为止。如果最后仍是一样大那么这两个数就是一样大的。返回值为自己约定的参数r等于2表示俩数一样大,等于1表示第二个数大,等于 0表示第一个数大。 10.乘法函数: void method(DLNode *head1,DLNode *head2,int x){ void minus(DLNode *head1,DLNode *head2,DLNode *head3);DLNode *temp1;DLNode *temp2;DLNode *temp3;DLNode *temp4;DLNode *temp5;int e,z=0,i,j;ListInitiate(&temp1);ListInitiate(&temp2);ListInitiate(&temp3);ListInsert(temp2,0,0);DLNode *p1,*p2;p1=head1->prior;p2=head2->prior;for(i=0;i while(p1!=head1){ } if(z!=0)ListInsert(temp1,0,z);for(j=0;j } else z=0;ListInsert(temp1,0,e);p1=p1->prior;z=e/10000;e=e-z*10000;ListInitiate(&temp4);ListInsert(temp4,0,0);ListInitiate(&temp5); } p1=head1->prior;p2=p2->prior;}OutputNumber(temp2,x);此函数实现的是俩个整数的乘法运算。模仿手算乘法,乘数的每一位分别和被乘数相乘得到的结果相加,注意的是在每次乘完相加时注意把低位的空缺补上0,以保证数据可以按位相加。在每一位乘法时需要注意一定要加上低位的进位以及改变进位的值,这样才能保证每一位诚出来的结果是正确的。11.减法函数: void minus(DLNode *head1,DLNode *head2,DLNode *head3){ int z=0,x=-1;int e;DLNode *p1,*p2;p1=head1->prior;p2=head2->prior;x=change(head1,head2);if(x==0){ while(p1!=head1&&p2!=head2){ } p1->data=p1->data+z;p1->data=p1->data+z;if(p1->data>=p2->data){ } else { } e=10000+p1->data-p2->data;ListInsert(head3,0,e);z=-1;e=p1->data-p2->data;ListInsert(head3,0,e);p1=p1->prior;p2=p2->prior;z=0;p1=p1->prior;p2=p2->prior;while(p1!=head1){ e=p1->data; ListInsert(head3,0,e); p1=p1->prior;} else if(x==1){ p2=head1->prior;while(p1!=head2&&p2!=head1){ } p1->data=p1->data+z;p1->data=p1->data+z;if(p1->data>=p2->data){ } else { } e=10000+p1->data-p2->data;ListInsert(head3,0,e);z=-1;e=p1->data-p2->data;ListInsert(head3,0,e);p1=p1->prior;p2=p2->prior;z=0;p1=head2->prior;} p1=p1->prior;p2=p2->prior;while(p1!=head2){ e=p1->data;p1=p1->prior;ListInsert(head3,0,e);} head3->next->data=-1*head3->next->data;} else { } } head3->next->data=0;此函数实现的是两个正数的减法运算。整个函数分为俩大部分,第一部分处理第一个数大于第二个数,第而部分是处理第二个数大于第一个数。在这个为题上我自己想了好长 时间,感觉俩部分可以 结合成一部分,但是由于本人的知识所限没有想出更好的办法,这使得代码量增加了足足一倍之多。仍然模仿手算减法,先找到俩数字中最大的那个,用大的减去小的。最后判断符号位。12.整合八种情况函数: void yunsuan(DLNode *head1,DLNode *head2,DLNode *head3,char ch){ DLNode *p1,*p2;p1=head1->next;p2=head2->next;if(head1->data==1&&head2->data==1){ } else if(head1->data==1&&head2->data==0){ } else if(head1->data==0&&head2->data==1){ } if(ch=='+'){ } else { } head1->next->data*=-1;head2->next->data*=-1;add(head1,head2,head3);head3->next->data*=-1;head1->next->data*=-1;minus(head2,head1,head3);if(ch=='+'){ } else { } head2->next->data*=-1;add(head1,head2,head3);head2->next->data*=-1;minus(head1,head2,head3);if(ch=='+')add(head1,head2,head3);else minus(head1,head2,head3); else { } } 此函数实现的是八种情况的整合。八种情况分别是正数加正数、正数加负数、正数减正数、正数减负数、负数加负数、负数加正数、负数减正数、负数减负数。此函数调用已经做好的正数加正数和正数减正数函数判断符号位,根据一定的规则实现八种运算。if(ch=='+'){ } { } head1->next->data*=-1;head2->next->data*=-1;minus(head2,head1,head3);head1->next->data*=-1;head2->next->data*=-1;add(head1,head2,head3);head3->next->data*=-1;else 13.整合乘法运算函数: void chengfa(DLNode *head1,DLNode *head2){ int i;if((head1->next->data*head2->next->data)<0){ } else { } } 此函数实现的是乘法运算的完整运算。调用已经实现的正数乘以正数的函数来计算函数值,在判断最head1->next->data=abs(head1->next->data);head2->next->data=abs(head2->next->data);i=1;method(head1,head2,i);head1->next->data=abs(head1->next->data);head2->next->data=abs(head2->next->data);i=0;method(head1,head2,i); 终的函数符号,得到最和的结果。 14.主函数: void main(){ } 此函数是主函数。主要的作用是为用户做一个提示,如何完成自己想要的运算。同时调用各个函数实现运算。char ch,ch1;while(1){ } //int w=-1;DLNode *a,*b,*c;ListInitiate(&a);ListInitiate(&b);ListInitiate(&c);printf(“请输入数A(以分号结束):”);InputNumber(a);//printf(“n”);printf(“请输入数B(以分号结束):”);InputNumber(b);//w=change(a,b);printf(“请选择操作符:<+,-,*>:n”);scanf(“%s”,&ch1);if(ch1=='+'||ch1=='-'){ } else if(ch1=='*')chengfa(a,b);else printf(“此版本不支持%c运算”,ch1);printf(“要继续吗?(y/n):”);scanf(“%s”,&ch);if(ch=='Y'||ch=='y'){ } else exit(0);printf(“n”);continue;yunsuan(a,b,c,ch1);OutputNumber(c,1); 三、调试分析 1.调试过程中遇到的问题 在函数编写之前我首先写出了所有函数的框架以及各个函数之间的关系,根据逐步求精的思想来完善整个程序。即使是这样我仍然遇到了不少错误。 例如:在实现正数减正数时,我一开始没有分为以上所说的俩个部分,而是把俩个部分整合到一起实现一个大函数,但是在我运行调试时结果大不如人意,出现的都是匪夷所思的数字,我根本就推算不出这些数字是怎么来的。没有办法我只好在另辟途径来完成函数的实现。于是我就分作两个部分来实现,这样逐步追踪可以使思绪更加清晰,所付出的代价是代码量增加。 四、使用说明和测试结果 1.使用说明 用户在使用该程序时,只需按照程序中的规定进行即可实现长整数的加减运算,具体使用步骤如下: 1)点击运行按钮,在DOS窗口下按照规定输入的数字需要从低位开始数四位一组用逗号隔开。输入第一个数字。2)同上输入第二个数; 3)选择要对这两个长整数进行的运算。 4)两个操作数与运算符选择完毕后,按回车键即可得到运算结果。2.测试结果 1)考虑边界数字,输入0和0做加法运算,输出“0”,结果如下图: 2)考虑加法进位(包括低位向高位的进位以及高位仍有进位情况),结果如下图: 3)考虑减法进位并且数A小于数B以及数A大于数B,结果如下图: 4)乘法结果为正数以及负数两种情况,结果如下图: 5)本试验要求的数据 0、0; 输出“0”(已证明) 2345,6789、-7654,3211; 输出“1,0000,0000” 1,0000,0000,0000、9999,9999; 输出“9999,0000,0001” 1,0001,0001、;1,0001,0001; 输出“0” 五、心得体会 本次试验是我感觉到了理论应用与实践的意义,以前我们也做过类似的题目,所以在试验中我感觉还是比较顺利的但是还是花了我十七个小时左右才完成。根据模块化思想来把握整体结构会使自己的思路更加清晰,更加明了。得到的东西往往是说不出来的只有自己心理面最清楚。 六、附录 程序的完整代码清单: #include int data;struct Node *prior;struct Node *next;}DLNode;void ListInitiate(DLNode **head)//双向链表的初始化 { if((*head=(DLNode *)malloc(sizeof(DLNode)))==NULL)exit(0);(*head)->prior=*head; } int ListLength(DLNode *head)//双向链表的表长 { } int ListInsert(DLNode *head,int i,int x)//双向链表的数据插入,i表示是插入的第几个元素 { } int abs(int x){ if(x<0)return-x;DLNode *p,*s;int j;p=head->next;j=0;while(p!=head&&j } if(j!=i){ } if((s=(DLNode *)malloc(sizeof(DLNode)))==NULL)exit(0);s->data=x;s->prior=p->prior;//插入 p->prior->next=s;s->next=p;p->prior=s;return 1;printf(“n插入位置不合法!”);return 0;p=p->next;j++;DLNode *p=head;int size=0;while(p->next!=head){ } p=p->next;size++;(*head)->next=*head;return size; } int InputNumber(DLNode *head)//读入输入的数据 { } void OutputNumber(DLNode *head,int sign)//从表尾输出数据元素 { DLNode *r=head->next;while(r->data==0&&r!=head->prior){ r=r->next;int input,i=0;//第i个节点 char c;scanf(“%d%c”,&input,&c);while(1){ } return 1;if(input<0&&i==0)//输入数为负且是第一个节点 { } else if(input>=0&&i==0)//输入数为正且是第一个节点 { } else { } i++;if(c==';')break;//遇到数据输入完成标志,跳出循环 scanf(“%d%c”,&input,&c);if(head->next->data>=0){ } //input=-1*input;ListInsert(head,i,input);ListInsert(head,i,input);//非第一个节点 else head->data=1;//将长整数的符号保存在头结点中 ListInsert(head,i,input);//插入数据 head->data=0;//将长整数的符号保存在头结点中 //input=abs(input);//取输入数字的绝对值 ListInsert(head,i,input);//插入数据 else return x; } void add(DLNode *head1,DLNode *head2,DLNode *head3){ int z=0;int e;DLNode *p1,*p2;} if(sign==1){ } else { } printf(“%d”,r->data);r=r->next;while(r!=head){ } printf(“n”); if(r->data<10){ } else if(r->data<100){ } else if(r->data<1000){ } else { } r=r->next; printf(“,%d”,r->data);printf(“,0”);printf(“%d”,r->data); printf(“,00”);printf(“%d”,r->data);printf(“,000”);printf(“%d”,r->data);printf(“结果是:-”);printf(“结果是:”); p1=head1->prior;p2=head2->prior;while(p1!=head1&&p2!=head2) if(p1==head1&&p2!=head2){ while(p2!=head2){ e=p2->data+z;if(e>=10000){ } else z=0;ListInsert(head3,0,e);p2=p2->prior;z=1;e=e%10000;{ e=p1->data+p2->data+z; } if(e>=10000){ } else z=0;ListInsert(head3,0,e);p1=p1->prior;p2=p2->prior;z=1;e=e%10000;} if(z==1)ListInsert(head3,0,z);} else if(p1!=head1&&p2==head2){ while(p1!=head1){ e=p1->data+z; if(e>=10000){ } z=1;e=e%10000;else z=0;p1=p1->prior;ListInsert(head3,0,e);} if(z==1)ListInsert(head3,0,z);} else{ } int change(DLNode *head1,DLNode *head2){ int length1,length2,r=2;length1=ListLength(head1);DLNode *p1,*p2;p1=head1->next;p2=head2->next;if(length1>length2){ } else if(length1 } else { int i=0;for(i=0;i if(p1->data>p2->data){ } else if(p2->data>p1->data){ } else { p1=p1->next;p2=p2->next;r=1;return r;break;r=0;return r;break;r=1;return r;r=0;return r;if(z==1)ListInsert(head3,0,z);} length2=ListLength(head2); } void method(DLNode *head1,DLNode *head2,int x){ void minus(DLNode *head1,DLNode *head2,DLNode *head3);DLNode *temp1;DLNode *temp2;DLNode *temp3;DLNode *temp4;DLNode *temp5;int e,z=0,i,j;ListInitiate(&temp1);ListInitiate(&temp2);ListInitiate(&temp3);ListInsert(temp2,0,0);DLNode *p1,*p2;p1=head1->prior;p2=head2->prior;for(i=0;i while(p1!=head1){ } if(z!=0)ListInsert(temp1,0,z);for(j=0;j } else z=0;ListInsert(temp1,0,e);p1=p1->prior;z=e/10000;e=e-z*10000;ListInitiate(&temp4);ListInsert(temp4,0,0);ListInitiate(&temp5); } return r; } } r=2; } void minus(DLNode *head1,DLNode *head2,DLNode *head3){ int z=0,x=-1;int e;DLNode *p1,*p2;p1=head1->prior;p2=head2->prior;x=change(head1,head2);if(x==0){ while(p1!=head1&&p2!=head2){ } p1->data=p1->data+z;p1->data=p1->data+z;if(p1->data>=p2->data){ } else { } e=10000+p1->data-p2->data;ListInsert(head3,0,e);z=-1;e=p1->data-p2->data;ListInsert(head3,0,e);p1=p1->prior;p2=p2->prior;z=0; add(temp1,temp2,temp3);temp1=temp4;temp2=temp3;temp3=temp5;z=0;p1=head1->prior;p2=p2->prior;}OutputNumber(temp2,x);p1=p1->prior;p2=p2->prior;while(p1!=head1){ e=p1->data;p1=p1->prior;ListInsert(head3,0,e);} } } void yunsuan(DLNode *head1,DLNode *head2,DLNode *head3,char ch){ DLNode *p1,*p2;p1=head1->next;p2=head2->next;if(head1->data==1&&head2->data==1)else if(x==1){ p2=head1->prior;while(p1!=head2&&p2!=head1){ } p1->data=p1->data+z;p1->data=p1->data+z;if(p1->data>=p2->data){ } else { } e=10000+p1->data-p2->data;ListInsert(head3,0,e);z=-1;e=p1->data-p2->data;ListInsert(head3,0,e);p1=p1->prior;p2=p2->prior;z=0;p1=head2->prior;p1=p1->prior;p2=p2->prior;while(p1!=head2){ e=p1->data;p1=p1->prior;ListInsert(head3,0,e);} head3->next->data=-1*head3->next->data;} else { } head3->next->data=0; { } else if(head1->data==1&&head2->data==0){ } else if(head1->data==0&&head2->data==1){ } else { if(ch=='+'){ } { head1->next->data*=-1;head1->next->data*=-1;head2->next->data*=-1;add(head1,head2,head3);head3->next->data*=-1;if(ch=='+'){ } else { } head1->next->data*=-1;head2->next->data*=-1;add(head1,head2,head3);head3->next->data*=-1;head1->next->data*=-1;minus(head2,head1,head3);if(ch=='+'){ } else { } head2->next->data*=-1;add(head1,head2,head3);head2->next->data*=-1;minus(head1,head2,head3);if(ch=='+')add(head1,head2,head3);else minus(head1,head2,head3);else } void chengfa(DLNode *head1,DLNode *head2){ } void main(){ char ch,ch1;while(1){ //int w=-1;DLNode *a,*b,*c;ListInitiate(&a);ListInitiate(&b);ListInitiate(&c);printf(“请输入数A(以分号结束):”);InputNumber(a);//printf(“n”);printf(“请输入数B(以分号结束):”);InputNumber(b);//w=change(a,b);printf(“请选择操作符:<+,-,*>:n”);scanf(“%s”,&ch1);if(ch1=='+'||ch1=='-'){ yunsuan(a,b,c,ch1);int i;if((head1->next->data*head2->next->data)<0){ } else { } head1->next->data=abs(head1->next->data);head2->next->data=abs(head2->next->data);i=1;method(head1,head2,i);head1->next->data=abs(head1->next->data);head2->next->data=abs(head2->next->data);i=0;method(head1,head2,i); } } head2->next->data*=-1;minus(head2,head1,head3); } } } else if(ch1=='*')chengfa(a,b);else printf(“此版本不支持%c运算”,ch1);printf(“要继续吗?(y/n):”);scanf(“%s”,&ch);if(ch=='Y'||ch=='y'){ } else exit(0);printf(“n”);continue;OutputNumber(c,1);第二篇:无线课程设计实验报告
第三篇:学生通讯录管理系统(C语言课程设计实验报告)
第四篇:语言课程设计要求
第五篇:长整数加减运算实验报告