Linux 下C语言开发基础(gcc/gdb/make/文件IO)实验

目录

一、实验目的

二、实验设备

三、实验内容

1、Linux 下C 语言开发流程

2、GCC 编译器的使用

3、GDB 基本命令的使用

4、Make 工程管理器的使用

5、文件IO编程实验


 一、实验目的

  1. 熟悉Linux下C语言的开发环境
  2. 掌握GCC和GDB的使用
  3. 掌握Linux下C语言程序设计与开发流程
  4. 掌握Makefile的基本语法和应用
  5. 掌握Linux文件IO编程方法;
  6. 掌握标准I/O和基本I/O函数的调用方法;

二、实验设备

  1. 硬件:PC机。
  2. 软件:VMware Workstation虚拟机、Linux操作系统。

三、实验内容

1、Linux 下C 语言开发流程

(1)启动虚拟机,进入Linux操作系统,然后启动终端。

(2)使用Vim 编辑源程序,在终端中输入vi hello.c,然后输入源代码,编辑完成后存盘。

(3)编译源代码,在终端下输入gcc hello.c–o hello进行编译。

(4)运行程序,在终端中查看程序运行结果。

2、GCC 编译器的使用

 参考教材中gcc的命令和编译选项,自行构造实验,测试总体选项、警告和出错选项以及优化选项的编译效果。请自由选择3个编译选项进行对比试验,并描述该编译选项的效果是什么。

测试总体选项

-E: 仅做预处理,不进行编译、汇编和链接。

-S:编译到汇编语言,不进行汇编和链接。

-c: 编译到目标代码

测试警告选项

-w 禁止所有警告信息

测试出错选项

-Werror:所有的警告转化为错误信息,并在警告发生时终止编译过程。

首先打开hello.c,定义void main,但是通过return 0返回一个0,测试警告信息是否转化为错误信息。

首先是不带-Werror,可以看到只报了警告。

加入- Werror 选项,可以看到打印出的警告信息变为了错误信息。

测试优化选项

-O1:能减少目标文件大小以及执行时间。

-O2:包含-O1的优化并增加了不需要在目标文件大小和执行速度上进行优化。

可以看到使用-O1优化选项后,编译文件后大小减少,-O2选项文件大小也发生了变化。

3、GDB 基本命令的使用

使用Vim 编辑源程序,在终端中输入vi gdbtest.c,输入如下源代码,

编辑完成后存盘。此代码的功能为输出倒序main 函数中string[]数组中定义的字符串,但结果没有输出显示,现通过gdb调试的方式来解决程序中存在的问题。程序源代码如下:

#include <stdio.h>

int display1 (char *string)

int display2 (char *string1)

int main ()

{

char string[] = "Embedded Linux";

display1 (string);

display2 (string);

}

int display1 (char *string)

{

printf ("The original string is %s \n", string);

}

int display2 (char *string1)

{

char *string2;

int size,i;

size = strlen (string1);

string2 = (char *) malloc (size + 1);

for (i = 0; i < size; i++)

string2[size - i] = string1[i];

string2[size+1] = ' ';

printf("The string afterward is %s\n",string2);

}

  1. 用gcc 编译:gcc gdbtest.c -o gdbtest

编译是否会报错?如报错,请根据报错信息分析错误原因,修改编译错误,并把修改方法在此描述。修改编译通过后再进行后续实验。

会报错。

错误int display1 (char *string)int display2 (char *string1)后面缺少分号。

修改方法:加上分号,加上头文件包含

编译通过,可以看到警告信息,提示我们包含头文件。

添加头文件:

重新编译:

(2)运行gdbtest:./ gdbtest,分析程序运行的输出结果是?

请分析程序输出结果,分析其存在的问题。

问题:倒序的xuniL deddedbmE没有输出。

(3)启动Gdb 调试:gdb gdbtest

输入gdb命令l,查看源代码:观察是否可以正常查看到源代码?如不能请分析原因是什么并回答。使用q命令,退出gdb。

不能查看,因为没有在gcc编译时加入-g选项,可执行代码中没有包含调试信息,导致GDB无法载入该可执行文件。

(4)用gcc的-g选项重新编译:gcc -g gdbtest.c -o gdbtest

再次启动gdb调试:gdb gdbtest

输入gdb命令l,查看源代码:

 在20 行(for 循环处)设置断点:b 20

 在23 行(printf 函数处)设置断点:b 23。

 查看断点设置情况:info b

 运行代码:r

 单步运行代码:n

 查看暂停点变量值:p string2[size - i]

查看暂停点变量值:p i

 继续单步运行代码数次,并使用命令查看变量的值,发现string2[size-1]的值正确

 继续程序的运行:c

 程序在printf 前停止运行,此时依次查看string2[0]、string2[1]…,发现string[0]没

有被正确赋值,而后面的复制都是正确的,这时,定位程序第31 行,发现程序运

行结果错误的原因在于“size-1”。由于i 只能增到“size-1”,这样string2[0]就永远

不能被赋值而保持NULL,故输不出任何结果。

 退出gdb:q

 重新编辑gdbtest.c,把其中的“string2[size - i] = string1[i]”改为“string2[size – i - 1] =

string1[i];”即可。

使用Gcc 重新编译,查看运行结果:

这时,输出结果正确。

4、Make 工程管理器的使用

(1)编辑源代码,利用文本编辑器vi 创建MakeTest.c 文件,vi MakeTest.c

#include <stdio.h>

int main()

{

printf("Welcome to Test makefile!\n");

return 1;

}

(2)编写Makefile 文件。

利用文本编辑器创建一个makefile 文件,并将其保存到与MakeTest.c 相同的目录下

CC=gcc

CFLAGS=

all: MakeTest

MakeTest: MakeTest.o

$(CC) $(CFLAGS) MakeTest.o –o MakeTest

MakeTest.o: MakeTest.c

$(CC) $(CFLAGS) –c MakeTest.c –o MakeTest.o

clean:

       rm *.o

  1. 使用Make 编译项目。执行make,查看并记录所生成的文件,对生成可执行程序进行运行,查看运行的结果。

5、文件IO编程实验

(1)基本IO(非缓冲)操作编程:编写一个基本IO操作的源代码,要求使用到基本IO操作的5个函数:打开、读取、写入、定位和关闭。编译上述源代码并调试通过,最后对运行结果予以分析验证。

首先新建了一个testIO.c文件用于测试。内容如下:

在底行写入“I am the content that has been written\n”

验证testIO.c是否真的有新添加的内容:

源代码:

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

int main()

{

       int fd,size,offest;

       char s[]="I am the content that has been written\n";

       char buffer1[200],buffer2[200];

       /* open */

       fd = open("testIO.c",O_RDWR|O_CREAT);

       if(-1 == fd) {

              printf("Open or create file named \"testIO.c\"failed.\n");

              return -1;

       }else {

              printf("Open or create file named \"testIO.c\"success!.\n\n");

       }

       /* read */

       size = read(fd,buffer1,sizeof(buffer1));

       printf("The content is:\n%s\n",buffer1);

       /* lseek */

       offest = lseek(fd,0,SEEK_END);

       /* write */

       write(fd,s,sizeof(s));

       printf("The file named \"testIO.c\" has been update!\n");

       /* close */

       close(fd);

       fd = open("testIO.c",O_RDWR|O_CREAT);

       if(-1 == fd) {

              printf("Open or create file named \"testIO.c\"failed.\n");

              return -1;

       }else {

              printf("Open or create file named \"testIO.c\"success!.\n\n");

       }

       size = read(fd,buffer2,sizeof(buffer2));

       printf("The new content is:\n%s\n",buffer2);

       /* close */

       close(fd);

       return 0;

}

(2)标准IO(缓冲)操作编程:编写一个标准IO操作的源代码,要求使用到标准IO操作的5个函数:打开、读取、写入、定位和关闭。编译上述源代码并调试通过,最后对运行结果予以分析验证。

#include <stdio.h>

#include <stdlib.h>

struct record {

       char name[10];

       int age;  

};

void main()

{

       struct record array[2] = {{"ZhangSan",20},{"LiSi",23}};

       /* fopen */

       FILE *fp = fopen("testSTDIO.txt","w");

       if(fp == NULL){

              printf("Open file named \"testSTDIO.txt\"failed.\n");

              return;

       }else{

              printf("Open file named \"testSTDIO.txt\"success!.\n\n");

       }

       /* fwrite */

       fwrite(array,sizeof(struct record),2,fp);

       printf("The file named \"testSTDIO.txt\" has been update!\n");

       /* fclose */

       fclose(fp);

       /* fseek */

       fseek(fp,0,SEEK_SET);

       /* fopen */

       fp = fopen("testSTDIO.txt","r");

       if(fp == NULL){

              printf("Open file named \"testSTDIO.txt\"failed.\n");

              return;

       }else{

              printf("Open file named \"testSTDIO.txt\"success!.\n\n");

       }

       /* fread */

       fread(array,sizeof(struct record),2,fp);

       printf("The content is:\n");

       printf("Name1:%s\tAge1:%d\n",array[0].name,array[0].age);

       printf("Name2:%s\tAge2:%d\n",array[1].name,array[1].age);

       /* fclose */

       fclose(fp);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值