第三次实验内容15.doc
, 第三次实验内容一、实验名称:Linux下C编程二、实验类型:设计三、实验目的:1 熟练掌握Linux下c的编译器gcc2 熟练掌握Linux下c的调试器gdb3 熟练掌握Linux下make用法4 熟悉Linux下使用c对进程操作5 熟悉Linux下使用c对文件操作四、实验准备参考教材、课件8章内容及笔记。五、实验内容1使用gcc调试如下程序,按要求完成任务l 任务1-单个程序reverse.c#include <stdio.h>#include <string.h>int reverse();main() char str100; reverse("cat",str); printf("reverse("cat")=%sn",str); reverse("noon",str); printf("reverse("noon")=%sn",str);int reverse(char *before,char *after) int i,j,len; len=strlen(before); for(j=len-1,i=0;j>=0;j-,i+) afteri=beforej; afterlen=0;l 任务2-多模块程序对reverse.c程序进行处理,将reverse()函数从原文件中移除,创建可重用函数。步骤:1) 创建一个源代码模块reverse-m.c,其中包含函数的源代码和包含函数原型的头文件reverse.h;2) 用gcc的-c选项把模块编译为目标模块。3) 连接编译主程序和目标模块生成可执行文件。文件reverse.c#include <stdio.h>#include <string.h>int reverse();main() char str100; reverse("cat", str); printf("reverse("cat")=%sn", str); reverse("noon", str); printf("reverse("noon")=%sn", str);文件reverse.hint reverse();文件reverse-m.c#include"reverse.h"#include<string.h>int reverse(char *before,char *after) int i,j,len; len=strlen(before); for(j=len-1,i=0;j>=0;j-,i+) afteri=beforej; afterlen=0;l 任务3-使用reverse函数构建回文程序palind,调试执行。包括:palind头文件、palind函数文件代码、palind主文件。提示:n palind.h头文件: int palind();n palind-m.c模块文件:#include “palind.h”#include “reverse.h”#include <string.h>int palind(char *str) char reversedStr100; reverse(str,reversedStr); return(strcmp(str,reversedStr)=0);n palind.c主程序代码:#include <stdio.h>#include “palind.h”main() printf(“palind(cat)=%dn”,palind(“cat”); printf(“palind(noon)=%dn”,palind(“noon”); n 编译各模块、连接生成可执行文件1) 编译模块gcc -c palind-m.c palind.c2) 连接生成可执行文件gcc reverse-m.o palind-m.o palind.o -o palindl 任务4-尝试创建静态库文件palind.a ,包括所有与回文有关的目标模块,归档后调用该库测试是否创建库成功。gcc -c palind-m.c reverse-m.c palind.car r palind.a palind-m.o reverse-m.ogcc palind.o palind.a -o palind./palind2 调试关于gdb的如下例题。#include <stdio.h>#include <stdlib.h>static void my_print (char *);static void my_print2 (char *);main ()char my_string = "hello world!"my_print (my_string);my_print2 (my_string);void my_print (char *string)printf ("The string is %s ", string);void my_print2 (char *string)char *string2;int size, i;size = strlen (string);string2 = (char *) malloc (size + 1);for (i = 0; i < size; i+)string2size - i = string i ;string2size+1 = n;printf ("The string printed backward is %s ", string2);添加头文件<string.h>3 编写palind的多模块程序的makefile。palind: reverse-m.o palind-m.o palind.o gcc -o palind reverse-m.o palind-m.o palind.opalind.o: palind.h palind.c gcc -c plind.cpalind-m.o: palind.h reverse.h palind-m.c gcc -c palind-m.creverse-m.o: reverse.h reverse-m.c gcc -c reverse-m.cclean: rm *.o4 调试课件关于进程创建、获取进程id,uid的程序。fork1.cfork2.cgetid.c将26行至32行中间的“:”删除。5调试如下程序,解释输出。#include <unistd.h>/符号常量的头文件,包含系统服务的函数原型#include <sys/types.h>/系统数据类型头文件#include <sys/wait.h>/进程控制的头文件#include <stdio.h>#include <errno.h>/错误代码定义头文件#include <math.h>void main(void) pid_t child; int status; printf("This will demostrate how to get child statusn"); if(child=fork()=-1) printf("Fork Error :%sn",strerror(errno); exit(1); else if(child=0) int i; printf("I am the child:%ldn",getpid(); for(i=0;i<1000000;i+) sin(i); i=5; printf("I exit with %dn",i); exit(i); while(child=wait(&status)=-1)&(errno=EINTR);if(child=-1) printf("Wait Error:%sn",strerror(errno);else if(!status) printf("Child %ld terminated normally return status is zeron",child);else if(WIFEXITED(status) printf("Child %ld terminated normally return status is %dn", child,WEXITSTATUS(status);else if(WIFSIGNALED(status) printf("Child %ld terminated due to signal %d znot caughtn", child,WTERMSIG(status);提示:EINTR:函数调用被信号处理函数中断.WIFEXITED:判断子进程退出值是非0,子进程正常结束则为非0.WEXITSTATUS:取得子进程的退出值(当子进程退出时非0).WIFSIGNALED:如果子进程由于信号而退出,值为真.WTERMSIG:取得子进程因信号而中止的信号代码(在WIFSIGNALED为真时,才有意义).6编写程序:教材P230页习题7#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(void) pid_t pid1,pid2; char *mes; int n; pid1=fork(); if(pid1<0) perror("forkl failed"); exit(1); if(pid1=0) mes=" sonn" n=50; else pid2=fork(); if( pid2<0) perror("fork2 failed"); exit(1); if(pid2=0) mes="daughtern" n=50; else mes=" fathern" n=50; for(; n>0; n-) printf("%s",mes); sleep(1); return 0;父进程每打印一条消息,就睡眠1秒,这时内核调度别的进程执行,在一秒期间子进程也可能被调度到。子进程同理,所以程序运行的结果为父进程与子进程的交叉输出。7. 调试课件文件操作相关(读、写、打开、关闭、实现字符、块复制)例题。copy_block.c simple_write.csimple_read.c将23行末尾的“:”改为“;”,将26行至32行中间的“;”去掉。六、实验总结通过本次实验,让我学会到了linux下c编程的很多操作,同时结合linux系统内核的调用,让我体会到linux的强大,同时以后编译c与cpp程序,也不会完全依赖集成开发环境和windows系统。