课程设计报告系统软件实践.docx

上传人:b****3 文档编号:4743511 上传时间:2023-05-07 格式:DOCX 页数:15 大小:903.15KB
下载 相关 举报
课程设计报告系统软件实践.docx_第1页
第1页 / 共15页
课程设计报告系统软件实践.docx_第2页
第2页 / 共15页
课程设计报告系统软件实践.docx_第3页
第3页 / 共15页
课程设计报告系统软件实践.docx_第4页
第4页 / 共15页
课程设计报告系统软件实践.docx_第5页
第5页 / 共15页
课程设计报告系统软件实践.docx_第6页
第6页 / 共15页
课程设计报告系统软件实践.docx_第7页
第7页 / 共15页
课程设计报告系统软件实践.docx_第8页
第8页 / 共15页
课程设计报告系统软件实践.docx_第9页
第9页 / 共15页
课程设计报告系统软件实践.docx_第10页
第10页 / 共15页
课程设计报告系统软件实践.docx_第11页
第11页 / 共15页
课程设计报告系统软件实践.docx_第12页
第12页 / 共15页
课程设计报告系统软件实践.docx_第13页
第13页 / 共15页
课程设计报告系统软件实践.docx_第14页
第14页 / 共15页
课程设计报告系统软件实践.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

课程设计报告系统软件实践.docx

《课程设计报告系统软件实践.docx》由会员分享,可在线阅读,更多相关《课程设计报告系统软件实践.docx(15页珍藏版)》请在冰点文库上搜索。

课程设计报告系统软件实践.docx

课程设计报告系统软件实践

北京化工大学北方学院

课程设计报告

课程名称系统软件实践

设计题目LinuxC程序设计

专业、班级软件1003班

学号100220071

姓名李超

指导教师马睿

设计时间2013年10月12日--2013年11月7日

2013年10月27日

一、引言(简要说明设计题目的目的、意义、内容、主要任务等)

a)目的

i.巩固和复习c语言的基础知识,进一步加深对c语言的理解和掌握

ii.课程设计提供了一个既动脑又动手,独立实践的机会,将课本上得理论知识和实际

iii.有机的结合起来,锻炼学生的分析解决实际问题的能力,提高学生适应实际,实践编程的能力;

iv.熟悉linux的基本操作,并且能够在linux环境下编写c语言程序、

v.培养在项目开发中团队合作精神,创新意识及能力

b)意义

i.综合应用c程序设计课程的理论基础和知识,掌握程序设计的一般方法,树立正确的设计思想,培养了分析问题和解决问题的能力

ii.学会了从实际的要求出发,合理的选择算法,正确的使用测试方法,培养了程序设计能力

iii.学会运用帮助和查阅有关技术资料的能力。

c)内容

程序一:

有一个已经从小到大排列好的数组,先输入一个数,要求按照原来的规律将它插入到数组中。

并用make工程管理器编译。

(注意分割文件,可参考第一题的提示。

)编写makefile文件。

程序二:

设计两个程序,要求一个程序把三个人的姓名和帐号余额信息,通过一次流文件I/O操作写入文件“file”,另一个格式输出帐号信息,把每个人的帐号和余额一一对应显示输出。

程序三:

设计一个程序,要求复制进程,子进程显示自己的进程号(PID)后暂停一段时间,父进程等待子进程正常结束,打印显示等待的进程号(PID)和等待的进程退出状态。

程序四:

设计一个程序,要求创建一个管道,复制进程,父进程往管道中写入字符串,子进程从管道中读取并输出字符串

d)主要任务

程序一:

要求按照原来的规律将它插入到数组中。

并用make工程管理器编译。

(注意分割文件,可参考第一题的提示。

)编写makefile文件。

程序二:

要求设计两个程序,要求一个程序把三个人的姓名和帐号余额信息,通过一次流文件I/O操作写入文件“file”,另一个格式输出帐号信息,把每个人的帐号和余额一一对应显示输出。

总结程序过程所用的相关知识(例如:

语法,函数调用……),分析解决程序运行过程出现的问题。

写出程序代码的设计与运行结果。

程序三:

要求子进程显示自己的进程号,然后暂停一段时间,等正常结束后,父进程打印显示等待的进程号以及等待的进程的退出状态。

总结程序过程所用的相关知识(例如:

语法,函数调用……),分析解决程序运行过程出现的问题。

写出程序代码的设计与运行结果。

程序四:

此题目要求先创建一个管道,父进程往管道内写入一段字符串,子进程读取父进程写入的字符串并且输出。

总结程序过程所用的相关知识(例如:

语法,函数调用……),分析解决程序运行过程出现的问题。

写出程序代码的设计与运行结果。

二、正文(课程设计的主要内容,包括实验与观测方法和结果、仪器设备、计算方法、编程原理、数据处理、设计说明与依据、加工整理和图表、形成的论点和导出的结论等。

正文内容必须实事求是、客观真切、准确完备、合乎逻辑、层次分明、语言流畅、结构严谨,符合各学科、专业的有关要求。

程序一:

程序描述:

主程序调用其他程序的方法进行数组的插入。

先定义一个排好序的数组,然后输入一个数排序。

程序应用makefile文件进行了文件的分割。

Makefile文件的作用:

Makefile文件Makefile一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

源程序:

4.c

#include

intmain()

{

paixu();

}

 

4_1.c

#include

voidpaixu()

{

inta[8]={1,23,34,38,56,67,89};

inti,m;

printf("原数组顺序:

");

for(m=0;m<7;m++)

printf("%d",a[m]);

printf("\n请输入一个数字");

scanf("%d",&i);

for(m=0;m<8;m++)

if(i

{

intj;

j=a[m];

a[m]=i;

i=j;

}

a[7]=i;

printf("\n得到数组:

");

for(m=0;m<8;m++)

printf("%d",a[m]);

printf("\n");

}

Makefile文件

main:

4_1.o4.o

gcc4_1.o4.o-oa

isDelta.o:

4_1.c

gcc4_1.c-c

main.o:

4.c

gcc4.c–c

运行结果:

图1排序

程序二:

程序描述:

程序主要实现了文件流的操作,分别调用了fwrite和fread函数,两个函数的定义详细介绍如下:

Fwrite函数和fread函数:

直接输入输出操作是以记录为单位进行读写,相应的库函数如下:

表头文件:

#include

定义函数:

size_tfread(void*ptr,size_tsize,size_tnmemb,FILE*fp);

size_tfwrite(constvoid*ptr,size_tsize,size_tnmemb,FILE*fp);

fread函数用于执行直接输出操作。

参数ptr是指向读取数据的缓冲区的指针。

参数size是读记录的大小。

参数nmemb是所读记录的个数。

参数fp是指向要读取的流的FILE结构指针。

fwrite函数用于执行直接输入操作。

参数这ptr是指向存放要输入数据的缓冲区的指针。

参数size是写入记录的大小。

参数nmemb是所写记录的个数。

参数fp是指向要写入数据的流的FILE结构指针。

调用函数fread和fwrite的返回值是实际读取或写入的记录数目。

这个返回值应当同nmemb的预设值相同。

只有当到达文件的末尾(只有在读取操作时有此情况)或出现读写错误时,会造成返回值比设定的nmemb值小,甚至是负值的情况。

这时系统内的文件结束标志或文件错误标志会被置为相应的值。

源程序:

2.c

#include

#defineset_s(x,y,z){strcpy(s[x].name,y);s[x].pay=z;}

#definenmemb3

structtest

{

charname[20];

intpay;

}s[nmemb];

intmain()

{

FILE*fp;

set_s(0,"赵普",1);

set_s(1,"赵国庆",0);

set_s(2,"吕玉彬",23);

fp=fopen("yinhang","a+");

fwrite(s,sizeof(structtest),nmemb,fp);

fclose(fp);

return0;

}

3.c

#include

#definenmemb3

structtest

{

charname[20];

intpay;

}s[nmemb];

intmain()

{

FILE*fp;

inti;

fp=fopen("yinhang","r");

fread(s,sizeof(structtest),nmemb,fp);

fclose(fp);

for(i=0;i

printf("账号[%d]:

%-20s余额[%d]:

%d\n",i,s[i].name,i,s[i].pay);

return0;

}

运行结果:

图2读取

程序三:

程序描叙:

要创建一个进程,最基本的系统调用是fork。

fork的作用是根据一个现有的进程复制出一个新进程,原来的进程称为父进程(ParentProcess),新进程称为子进程(ChildProcess)。

在Shell下输入命令可以运行一个程序,是因为Shell进程在读取用户输入的命令之后会调用fork复制出一个新的Shell进程,然后新的Shell进程调用exec执行新的程序

#include

#include

pid_tfork(void);

pid_tvfork(void);

调用fork时,系统将创建一个与当前进程相同的新的进程。

它与原有的进程具有相同的数据、连接关系和在程序同一处执行的连续性。

将原有的进程称为父进程,而把新生成的进程称为子进程。

子进程是父进程的一个复制,子进程获得同父进程相同的数据,但是同父进程使用不同的数据段和堆栈段。

流程图:

源程序:

#include

#include

#include

#include

intmain()

{

pid_tpid,vpid;

intstatus,i;

pid=fork();

if(pid==0)

{

printf("zheshizijinchengjinchenghaoshi:

%d\n",getpid());

sleep(5);

exit(6);

}

else

{

printf("zheshifujinchengzhengzaidengdaizijincheng........\n");

vpid=wait(&status);

i=WEXITSTATUS(status);

printf("dengdaidejinchengdejinchenghaoshi:

%d,jieshuzhutai:

%d\n",vpid,i);

}

}

运行结果:

图3存款

程序四:

程序描述:

此程序主要实现了管道的创建,管道的读写操作。

(1)管道的创建:

表头文件:

#include

定义函数:

intpipe(intfiledes[2]);

此函数用于创建一个管道。

参数filedes是一个两元整型数组,用于存放调用该函数所创建管道的两个文件描述符。

filedes[0]存放管道读取端的文件描述符;filedes[1]存放管道写入端的文件描述符。

调用成功时,返回值为0;调用失败时,返回值为-1。

(2)、管道的读写操作:

read(由已打开的文件读取数据) 

表头文件:

#include 

定义函数:

ssize_tread(intfd,void*buf,size_tcount); 

函数说明:

read()会把参数fd所指的文件传送count个字节到buf指针所指的内存中。

若参数count为0,则read()不会有作用并返回0。

返回值为实际读取到的字节数,如果返回0,表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动。

附加说明:

如果顺利read()会返回实际读到的字节数,最好能将返回值与参数count作比较,若返回的字节数比要求读取的字节数少,则有可能读到了文件尾、从管道(pipe)或终端机读取,或者是read()被信号中断了读取动作。

当有错误发生时则返回-1,错误代码存入errno中,而文件读写位置则无法预期。

错误代码:

EINTR此调用被信号所中断。

EAGAIN当使用不可阻断I/O时(O_NONBLOCK),若无数据可读取则返回此值。

EBADF参数fd非有效的文件描述词,或该文件已关闭。

write(将数据写入已打开的文件内) 

表头文件:

#include 

定义函数:

ssize_twrite(intfd,constvoid*buf,size_tcount); 

函数说明:

write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。

当然,文件读写位置也会随之移动。

返回值如果顺利write()会返回实际写入的字节数。

当有错误发生时则返回-1,错误代码存入errno中。

 

错误代码:

EINTR此调用被信号所中断。

EAGAIN当使用不可阻断I/O时(O_NONBLOCK),若无数据可读取则返回此值。

EADF参数fd非有效的文件描述词,或该文件已关闭。

 

程序源代码:

Fuzhi.c:

#include

#include

#include

intmain(void)

{

intn,fd[2];

pid_tpid;

charline[80];

if(pipe(fd)<0)

{

printf("pipeerror\n");

exit

(1);

}

pid=fork();

if(pid<0)

{

printf("forkerror\n");

exit

(1);

}

elseif(pid==0)

{

close(fd[1]);//关闭写入端

if(n=read(fd[0],line,80)>0)

printf("子进程从管道读取%d个字符,读取的字符串是:

%s\n",n,line);

close(fd[0]);

}

else

{

close(fd[0]);//关闭读取端

if(write(fd[1],"mynameis吕钰彬!

",80)!

=-1)

printf("父进程向管道写入mynameis吕钰彬!

\n");

close(fd[1]);

waitpid(pid,NULL,0);

}

exit(0);

}

运行结果:

图4父写子读

三、结论(应当准确、完整、明确精练;也可以在结论或讨论中提出建议、设想、尚待解决问题等。

Makefile介绍

make命令执行时,需要一个Makefile文件,以告诉make命令需要怎么样的去编译和

链接程序。

信号是进程之间通信的一种方式。

它包括3部分操作:

1.设置信号处理函数。

系统调用signal。

内核调用sys_signal(),设置当前进程对

某信号的处理函数。

2.发送信号.系统调用kill。

内核调用sys_kill()。

向目标进程发送信号。

3.接收并处理信号。

目标进程调用do_signal()处理信号。

从用户态的角度看,目标进程在执行用户态的代码时突然“中断”,转而去执行对应的信号处理函数(同样在用户态)。

等到信号处理函数执行完后,又从原来被中断的代码开始执行。

如何达到这样的效果呢?

由前面的几种内核的伪装现场的手段,我们可以猜出它这次

使用的手段。

比如,要让目标进程执行信号处理函数,在内核态中当然不可能直接调用,但

是可以通过设置pt_regs中的eip来达到这种效果。

但是,要使目标进程在执行完信号处理

函数后,又恢复到被中断的现场继续执行,那得花些技巧。

不过,不外乎设置堆栈。

这一次

还包括了用户态堆栈。

由于恢复的任务比较艰巨,系统干脆提供了一个系统调用sigreturn

既然内核希望用户在执行完信号处理函数后,调用sigreturn。

接下去的思路就比较

简单了。

就是先把用户态的eip设置为signal_handler(通过修改pt_regs中的eip来实

现),然后把堆栈中的返回地址改成调用sigreturn的一段代码的入口(当然原来的返回地

址也还是要保存的)并且把相关参数“压入”用户态堆栈。

这样,在源进程发送信号后不久,目标进程被调度到,然后执行到do_signal。

对信

号一一作处理.

pram——指定了RAM起始的物理地址,必须始终存在,并应等于PHYS_OFFSET。

pio——是供arch/arm/kernel/debug-armv.S中的调试宏使用的,包含IO的8MB区域的物理地址。

vio——是8MB调试区域的虚拟地址。

这个调试区域将被位于代码中(通过MAPIO函数)的随后的构架相关代码再次进行初始化。

lFⅨUP(func)——机器相关的修正,在存储子系统被初始化前运行。

lMAPIO(func)——机器相关的函数,用于IO区域的映射(包括上面的调试区)。

lINITIRQ(func)——用于初始化中断的机器相关的函数。

四、参考文献

[1]贾宗璞,许合利.C语言程序设计[M].江苏:

中国矿业大学出版社,2007.

[2]谭浩强.C程序设计(第二版)[M].北京:

清华大学出版社,2001.

[3]谭浩强,张基温,唐永炎编著.C语言程序设计教程[M].北京:

高等教育出版社,1992. 

[4]秦友淑,曹化工编著.C语言程序设计教程[M].武汉:

华中理工大学出版社,1996.

[5]曹衍龙,林瑞仲,徐慧编著.C语言实例解析精粹[M].北京:

人民邮电出版社,2005.

[6]黄明等编著.C语言程序设计[M].大连。

大连理工大学出版,1996.

五、指导教师评语

签名:

年月日

课程设计成绩(五级分制)

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

当前位置:首页 > PPT模板 > 商务科技

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

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