电子科技大学 软件开发环境 实验报告55p.docx

上传人:b****6 文档编号:12959477 上传时间:2023-06-09 格式:DOCX 页数:68 大小:409.63KB
下载 相关 举报
电子科技大学 软件开发环境 实验报告55p.docx_第1页
第1页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第2页
第2页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第3页
第3页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第4页
第4页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第5页
第5页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第6页
第6页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第7页
第7页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第8页
第8页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第9页
第9页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第10页
第10页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第11页
第11页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第12页
第12页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第13页
第13页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第14页
第14页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第15页
第15页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第16页
第16页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第17页
第17页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第18页
第18页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第19页
第19页 / 共68页
电子科技大学 软件开发环境 实验报告55p.docx_第20页
第20页 / 共68页
亲,该文档总共68页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

电子科技大学 软件开发环境 实验报告55p.docx

《电子科技大学 软件开发环境 实验报告55p.docx》由会员分享,可在线阅读,更多相关《电子科技大学 软件开发环境 实验报告55p.docx(68页珍藏版)》请在冰点文库上搜索。

电子科技大学 软件开发环境 实验报告55p.docx

电子科技大学软件开发环境实验报告55p

电子科技大学

实验报告

学生姓名:

郭小明学号:

2011060100010

一、实验室名称:

主楼A2-412

二、实验项目名称:

软件开发环境试验-----Huffman编码实验

3、实验原理:

2.1分割函数的三项原则

分割函数的三项原则包括:

与其写注释,不如写函数;重复就是罪恶;函数不要超过50行至70行。

关于分割函数三原则的具体含义,请见教材和课堂教学PPT关于电话本的内容。

这里不再赘述。

2.2Huffman编码的基本原理

本实验要求使用Huffman编码算法,实现对文件的压缩和解压。

因此,我们首先介绍huffman的编码算法。

Huffman编码是一种可变长编码方式,是由美国数学家DavidHuffman创立的,是二叉树的一种特殊转化形式。

编码的基本原理是:

将使用次数多的代码转换成长度较短的编码,而使用次数少的代码则可以使用较长的编码,并且保持编码的唯一可解性。

指导书试验原理部分较多,在这里就不做粘贴复制了。

四、实验目的:

本实验总体目的是,通过使用huffman编码算法从而实现文件的压缩和解压,以达到使学生掌握并灵活运用分割函数的三项原则。

5、实验内容:

本实验要求实现一个exe程序。

这个程序按照huffman编码方式,同时包含了压缩功能和解压功能。

用户通过以下命令进行压缩:

C:

\>test.exe–cuncompress_filenamecompress_filename

上述命令中,test.exe是程序名,-c表示要进行压缩。

uncompress_filename是要压缩的文件名,可以包含路径信息,而compress_filename是压缩之后的文件名,同样可以包含路径信息。

用户可以通过如下命令进行解压:

C:

\>test.exe–ucompress_filenameuncompress_filename

上述命令中,-u表示要执行解压命令。

compress_filename是要解压的文件名,可以包含路径信息;uncompress_filename就是解压后所得到的文件,同样可以包含路径信息。

提示:

在实现test.exe程序时,需要考虑如何存储huffman树或者编码表或者词频表等等。

本实验要求实现两个版本的test.exe程序,一是C语言版本的,二是C++版本的。

对这两个版本的要求如下:

●对于每一个版本的程序,需要在实验报告中给出函数调用关系图、流程处理关系图以及它们的文字说明等内容;

●对于每一个版本的程序,都需要在实验报告中给出源代码。

为了便于查重,代码中注释的比例要占到总行数的20%;

●C++版本的程序,需要给出类关系图。

实验报告的评分标准,包括以下几个方面:

●实验报告是否规范

●实验报告内容是否详实

●实验报告中是否包含了函数调用图、流程图、类图以及它们的文字说明

●实验报告中的代码注释是否达到要求

●程序是否正确无误

●程序是否严格按照分函数的原则编写

●C++版本的程序类关系的耦合度如何

●程序实现是否考虑了大文件情况

六、实验器材(设备、元器件):

PC机,vs2008软件平台。

七、实验数据及结果分析:

代码见附件。

huffmanForC

文件中函数列表如下:

///统计词频时用于查找是否已经记录过,记录过的话返回下标,没有则返回0

intisInNode(intvalue)

//获取文件词频,记录在NodehuffmanNode[260]的节点数组当中

voidcalWeight(char*file)

/*得到待压缩文件的总字节数,权值为几就代表着有多少个字节*/

intgetSumBytes()

//获取压缩后文件的总bit数

intgetSumBits()

//建立huffman树根据huffman树的特性,具有n个节点的huffman树的具有2n-1个节点

//n值由全局变量count值来确定,该函数主要用来初始化Huffman树的所有节点信息

voidcreateHufmanTree(Node*huffmanTree)

/*字符编码,从构建好的Huffman树当中读取每个叶子节点的huffman编码,并将叶子节点的信息放入到code[]中*/

HCode*getHuffmanCode(Node*huffmanTree,HCode*HC,intcode[])

/*

将编码表写入默认文件当中,并在结尾存入叶子节点数(count)与压缩后文件的总bit数

111100027

...........

...........

#sum_bit##count#

*/

voidfreToFile(intcode[],HCode*HC)

//由于词频表是按照字符串方式存储的叶子节点信息,读取出来的字符串需要转换成int值再使用

intpowmy(inta,intb)

/*从编码表文件读取相应信息以用来解压文件,读取信息包括编码和叶子信息*/

HCode*freFromFile(intcode[],HCode*HC)

/*压缩文件*/

voidcompress_file(char*file1,char*file2)

/*用于在解压的时候将读取到的ASCII码转换为二进制数*/

intswap(intdata)

/*进行文件的解压*/

voiduncompress_file(char*file1,char*file2)

//主函数

intmain(intargc,char**argv)

函数关系调用图:

向下箭头为顺序依次调用,斜线为函数内调用

输入-cargv[2]argv[3]

输入-c命令

isInNode()

获取argv[2]文件中的词频信息

calWeight(argv[2])

 

根据词频信息建立Huffan树

createHufmanTree()

getSumBytes()

getHuffmanCode()

获取Huffman编码

getSumBits()

compress_file()

将argv[2]文件使用编码压缩成argv[3]

 

将编码信息写入编码表文件,以备解压使用

freToFile()

输入-uargv[2]argv[3]

输入-u命令

powmy()

freFromFile()

从词频表当中读取编码信息

 

swap()

将argv[2]文件解压为argv[3]文件

uncompress_file()

代码见附件。

上面操作实现了将file.txt压缩成out.txt(同时生成了默认词频表文件dic.txt),然后实现了解压缩功能。

实验文件列表:

file.txt为源文件,out.txt为压缩文件,out1.txt为解压出来的文件

下面是dic.txt的部分信息,存放的依次是Huffman编码,对应的ASCII码

压缩后产生的文件,确实是乱码

解压后的文件,与压缩前的文件,大小内容完全一致。

C++

Controll类

classControll//:

publicHuffmanTree

{

public:

voidcompress_file(constchar*,constchar*,constchar*);

voiduncompress_file(constchar*,constchar*,constchar*);

voidfreFromFile(constchar*,char**,char*,int*);

intpowmy(int,int);

};

 

HuffmanNode类

classHuffmanNode{

public:

charinfo;//结点信息

doubleweight;//结点权值

intparent,lchild,rchild;//父亲结点,左右孩子结点

HuffmanNode(){

parent=lchild=rchild=-1;

}

HuffmanNode(constchar&data,constdouble&wt,constint&pa=-1,constint&lch=-1,constint&rch=-1){

info=data;

weight=wt;

parent=pa;

lchild=lch;

rchild=rch;

}

};//classHuffmanNodeend

Code类

/*现在我把它调出来为的就是在controlll类当中使用这个类*/

classCode{

public:

Code():

length(10){ptr=newchar[length];}

~Code(){delete[]ptr;}

char*ptr;

constintlength;

};

HuffmanTree类

classHuffmanTree{

public:

HuffmanTree(constint&s=100){

maxSize=(s>100?

s:

100);

arrayTree=newHuffmanNode[maxSize];

currentSize=0;

codeArray=0;

}

~HuffmanTree(){

delete[]arrayTree;

if(codeArray!

=0)

delete[]codeArray;

}

voidrun(constchar*,constchar*);

intgetSumBytes();//定义待压缩文件的总bytes数

intcurrentSize;//当前数组大小

HuffmanNode*arrayTree;//哈夫曼结点数组

Code*codeArray;//数组大小为currentSize

intsum_bits;//定义压缩后文件的总bit数

private:

intmaxSize;//数组最大值

//intsum_bytes;

voidinsert(constchar&,constdouble&);//插入结点

voidcreateHuffmanTree();//创建哈夫曼树

voidcreateHuffmanCode();//创建哈夫曼编码

voidwriteCodeToFile(constchar*);//将Huffman编码写入到词频表文件当中

intfindPosition(constchar&)const;//返回字符在arrayTree[]中的位置

intisEqual(constchar*s)const;//判断s是否存在于编码系统中,若存在则返回s在编码系统中的位置,否则返回-1

voidreverse(chararr[]);

};//classHuffmanTreeend

Code类

类关系图

HuffmanTree类类

HuffmanNode类

Control类

C++版本的实验过程总体类似C语言的实验过程,截图类似上面。

两程序总体程序设计思想:

压缩文件命令:

(1)首先读取待压缩文件,建立词频信息的存储。

(2)然后根据存储的词频信息,建立Huffman树。

(3)然后根据建立后的Huffman树,生成编码表信息。

(4)根据编码表信息再次逐字节的的读取带压缩文件并且压缩文件。

(5)最后将编码表信息和相关文件信息写进存储文件,以备解压使用。

解压命令

(1)从编码表存储文件当中读出编码信息。

(2)根据相关编码信息对压缩文件进行解码,生成解压缩文件。

两份源代码打包一并交到了系统里面,以备老师查看!

电子科技大学

实验报告

学生姓名:

郭小明学号:

2011060100010

一、实验室名称:

主楼A2-412

二、实验项目名称:

软件开发环境实验二:

流程控制语句反汇编

三、实验原理:

VS2008的反汇编调试和反汇编代码规律。

四、实验目的:

本实验总体目的是,通过使用VisualStudio2008查看if、if/else、do/while/for等类型语句的反汇编代码,以达到掌握流程控制语句识别的目的。

五、实验器材(设备、元器件):

PC机,VS2008反汇编编码调试软件

六、实验步骤:

2.2if语句的反汇编

在实验报告中需要给出代码清单2的解释。

代码清单2

int_tmain(intargc,_TCHAR*argv[])

{

inti=3;

if(i>3)

{

i=4;

}

return0;

}

反汇编代码

inti=3;

00DD138Emovdwordptr[ebp-8],3

if(i>3)

00DD1395cmpdwordptr[ebp-8],3

00DD1399jle00DD13A2

{

i=4;

00DD139Bmovdwordptr[ebp-8],4

}

return0;

00DD13A2xoreax,eax

反汇编代码清单2,下面进行解释:

inti=3;

00DD138Emovdwordptr[ebp-8],3

由课上讲述的结论:

在使用了EBP寻址的函数中,ebp-偏移量就是局部变量的地址。

我们在程序当中定义了一个局部变量inti=3。

int_tmain(intargc,_TCHAR*argv[])

{

00DD1370pushebp

00DD1371movebp,esp

以上是该程序入口处的反汇编代码,看得出来程序首先将ebp压栈,然后将现在的栈顶指针esp赋值给ebp(由于栈是由高到低的顺序生长的,所以此时ebp-n就可以表示ebp后面n字节的地址了),然后我们再定义inti=3;刚好压栈后存储在ebp的后面,,并且由于VS2008为了防止溢出攻击,在ebp后面空出了4个字节,然后再分配四个字节存放i变量,于是i变量的地址就变成了ebp-8,并且int类型变量是4个字节,所以就在[ebp-8]

加上dwordptr用来指明数据的字节数

00DD1395cmpdwordptr[ebp-8],3

同上dwordptr[ebp-8]是指明数据字节数,获取i数据值,cmp是将i值与3进行比较,其实就是执行i-3,然后在标志寄存器(PSW----ProgramStatusWord)的各位反应比较的结果。

00DD1399jle00DD13A2

jle(jle,jumpiflightorequal)的含义是第一个操作数小于或等于第二个操作数时跳转(当然此时就是通过标志寄存器(PSW----ProgramStatusWord)中的数值来判断)。

然后我们观察跳转地址00DD13A2其实就是00DD13A2xoreax,eax最后一句return0的代码。

i=4;

00DD139Bmovdwordptr[ebp-8],4

这是if条件语句里面的代码,将i值赋值为4,同理,dwordptr[ebp-8]是通过ebp-8找寻到i的地址单元,然后dwordptr说明字节数,mov指令将4赋给这个地址(就是i的存放地址);

return0;

00DD13A2xoreax,eax

程序返回0

eax清零

代码清单3

int_tmain(intargc,_TCHAR*argv[])

{

inti=3;

if(i<3)

{

i=4;

}

return0;

}

下面是代码清单3的反汇编代码和解释。

inti=3;

0122138Emovdwordptr[ebp-8],3

if(i<3)

01221395cmpdwordptr[ebp-8],3

01221399jge012213A2

{

i=4;

0122139Bmovdwordptr[ebp-8],4

}

return0;

012213A2xoreax,eax

*******************************************************************

inti=3;

0122138Emovdwordptr[ebp-8],3

定义一个int型的变量i,赋值为3,[ebp-8]ebp-8是i变量地址,[ebp-8]是i变量,dwordptr是指明该地址数据由4字节构成,然后通过mov指令将3赋值给i。

if(i<3)

01221395cmpdwordptr[ebp-8],3

dwordptr[ebp-8]是指明数据字节数,获取i数据值(ebp-8是i变量的地址,[ebp-8]是i变量),cmp是将i值与3进行比较,其实就是执行i-3,然后在标志寄存器(PSW----ProgramStatusWord)的各位反应比较的结果。

01221399jge012213A2

通过与代码清单2的比较我们可以得出,jge(jge,jumpifgreaterorequal)是当第一个操作数大于或者等于第二个操作数的时候进行跳转。

且跳转地址就是return0代码的地址。

i=4;

0122139Bmovdwordptr[ebp-8],4

这是if条件语句里面的代码,将i值赋值为4,同理,dwordptr[ebp-8]是通过ebp-8找寻到i的地址单元,然后dwordptr说明字节数,mov指令将4赋给这个地址(就是i的存放地址);

012213A2xoreax,eax

程序返回0

eax清零

 

代码清单4

int_tmain(intargc,_TCHAR*argv[])

{

inti=3;

if(i==3)

{

i=4;

}

return0;

}

下面是代码清单4的反汇编代码及解释

inti=3;

002B138Emovdwordptr[ebp-8],3

if(i==3)

002B1395cmpdwordptr[ebp-8],3

002B1399jne002B13A2

{

i=4;

002B139Bmovdwordptr[ebp-8],4

}

return0;

002B13A2xoreax,eax

}

***************************************************************

inti=3;

002B138Emovdwordptr[ebp-8],3

定义一个int型的变量i,赋值为3,[ebp-8]ebp-8是i变量地址,[ebp-8]是i变量,dwordptr是指明该地址数据由4字节构成,然后通过mov指令将3赋值给i。

if(i==3)

002B1395cmpdwordptr[ebp-8],3

dwordptr[ebp-8]是指明数据字节数,获取i数据值(ebp-8是i变量的地址,[ebp-8]是i变量),cmp是将i值与3进行比较,其实就是执行i-3,然后在标志寄存器(PSW----ProgramStatusWord)的各位反应比较的结果。

002B1399jne002B13A2

通过与代码清单2的比较我们可以得出,jne(jne,jumpifnotequal)是当第一个操作数不等于第二个操作数的时候进行跳转。

且跳转地址就是return0代码的地址。

i=4;

002B139Bmovdwordptr[ebp-8],4

这是if条件语句里面的代码,将i值赋值为4,同理,dwordptr[ebp-8]是通过ebp-8找寻到i的地址单元,然后dwordptr说明字节数,mov指令将4赋给这个地址(就是i的存放地址);

002B13A2xoreax,eax

程序返回0

eax清零

实验有要求:

另外,还可以自行实验<=、>=时的情况。

在实验报告中,给出这些情况的反汇编代码及解释。

最后,在实验报告中,总结出条件判断语句的反汇编代码规则。

下面是在>=情况下的反汇编代码:

inti=3;

00CF138Emovdwordptr[ebp-8],3

//if(i==3)

if(i>=3)

00CF1395cmpdwordptr[ebp-8],3

00CF1399jl00CF13A2

{

i=4;

00CF139Bmovdwordptr[ebp-8],4

}

return0;

00CF13A2xoreax,eax

*********************************************

下面只是解释这句不同的代码:

00CF1399jl00CF13A2

通过与代码清单2的比较我们可以得出,jl(jne,jumpifless)是当第一个操作数小于第二个操作数的时候进行跳转。

且跳转地址就是return0代码的地址。

下面是<=代码的反汇编代码:

inti=3;

008C138Emovdwordptr[ebp-8],3

//if(i==3)

//if(i>=3)

if(i<=3)

008C1395cmpdwordptr[ebp-8],3

008C1399jg008C13A2

{

i=4;

008C139Bmovdwordptr[ebp-8],4

}

return0;

008C13A2xoreax,eax

********************************************************

008C1399jg008C13A2

通过与代码清单2的比较我们可以得出,jg(jne,jumpifgreater)是当第一个操作数大于第二个操作数的时候进行跳转。

且跳转地址就是return0代码的地址。

条件判断语句的反汇编代码规则:

由两条汇编指令构成:

cmp操作数1操作数2和jXX地址

cmp用于条件判断比较

Jxx用于在不符合判断的情况下跳转到后面的代码处

jg(jn

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2