《Linux应用技术》实验报告

本实验用到的软件为ubunto10.04,VMware Workstation8,也安装了VMtools。可以自行选择较高版本的软件。!!

实验一 Linux系统安装与简单配置

一、实验目的

1.掌握Linux系统安装的分区准备。

2.掌握Linux系统的安装步骤。

3.掌握Linux系统分区的挂载和卸载。

4.掌握Linux系统的启动和关闭操作。

二、实验内容

1.安装VMware虚拟机,设置光盘驱动器,为Linux系统安装做准备。

2.在虚拟机下安装Linux操作系统(如Ubuntu桌面版本)和VMwareTool,实现宿主机和虚拟机之间的文件拷贝。

3.配置Linux系统运行环境。

4.增加一块SCSI硬盘,请在新增的硬盘中给出系统6个分区的方案,并选择一种方案利用fdisk进行分区,并且学会使用命令建立和删除交换分区。

5.将新的Linux系统分区挂载到系统中;卸载新挂载的分区,重新挂载到目录树中的其他位置。

6. 修改配置文件将分区配置成开机自动挂载。

三、主要的实验步骤

1.制定安装系统的分区计划。

2.配置光驱引导镜像文件iso,启动系统,开始安装过程。

3.根据安装计划,对磁盘空间进行分区设置(一个主分区、一个swap分区,一个空闲分区)。

4.根据系统安装指导,完成Linux系统的安装过程。

5.安装成功后,退出系统,重新启动虚拟机,登陆Linux操作系统。

6.对Linux系统进行配置,如VMwareTool,网络设备等。

7.利用fdisk分区工具依据设计的将硬盘分成5个分区的方案,进行分配。并对分区采用mkfs命令对分区进行格式化。

8.利用partprobe命令重新加载分区表。利用df -h命令可查看分区挂载情况。

9.利用mkswap命令创建交换分区,并使用swapon命令激活交换分区。

10.利用磁盘使用工具和mount,将新创建的Linux系统分区挂载到系统中。将新挂载的分区卸载,并重新挂载到目录树的其他位置。观察挂载之前和之后的该目录下所存储的文件。

11.利用/ect/fstab配置文件进行分区的自动挂载,重启测试。

四、拓展实验

1. 设计方案,在计算机或虚拟机(二选一)中安装双系统?并通过实验验证自己的方案。

  1. 计算机(宿主机)上安装双系统:提示可能用到的工具:多系统启动维护工具EasyBCD,虚拟光驱(如:Daemon Tools)等。
  2. 虚拟机上安装双系统:可参考以下链接,

https://blog.youkuaiyun.com/GH_12138/article/details/123644520。

2. 新建一个虚拟机,安装另外一个版本的Linux系统,如:CentOS、Redhat等,体验Linux不同发行版的使用环境。

五、实验结果

1.在实验之前要先学会如何卸载VMware虚拟机。

(1)在服务或任务管理器中停止运行VMware相关的进程

(2)在控制面板中卸载VMware Workstation

图1-1 服务中的VMware相关程序

图1-2 任务管理器中的VMware相关程序

(3)清理VMware虚拟机在注册表中的信息和遗留在电脑中的文件

图1-3 注册表中的VMware相关文件

(4)清理我的电脑中的VMware文件

2.安装VMware虚拟机

图1-4 安装虚拟机—命名

图1-5 安装虚拟机—自定义硬件

3.分区操作

(1)新建主分区(10个G)挂载点为根

图1-5 新建主分区作为系统盘

(2)新建交换分区,分配2个G

图1-6 新建交换分区

图1-7 分区设置

4.安装VMware-tools

图1-8 VMware-tools安装成功

5.分区操作

(1)利用fdisk-p命令查看分区情况

(2)我们发现sda2和sda5的起始地址和结束地址分别都是柱面1216和柱面1459,说明了交换分区是在扩展分区下面扩展出来的,并且扩展分区的空间全部分配给了交换分区,因此无法在扩展分区上进一步划分新的分区。我们将两个分区全部删除,重新划分。

(3)利用fdisk-n命令新建扩展分区2,如图1-11.

(4)创建扩展分区后由于只能有一个扩展分区,我们在扩展分区上新建5个逻辑分区。加上系统盘主分区,总共六个分区。最后利用fdisk-w命令保存分区,分区操作完成。如图1-12。重启系统,查看磁盘分区情况,如图1-13

图1-9 fdisk-p命令

图1-10 fdisk-d命令

 

图1-11 fdisk-n命令

图1-12 fdisk-w命令

图1-13 磁盘分区情况

(5)新创建五个分区还没有格式化,我们运用 sudo mkfs -c -t ext4 /dev/sda5 (mkfs是格式化命令,-c是检测磁盘非必要,-t必要,ext4指定格式化成ext4文件系统)。同时我们需要运用mount命令把分区挂载到目录树当中,使能够通过目录树访问磁盘。

图1-14 分区挂载情况

6.创建交换分区

我们的分区还有空闲部分,我们新建逻辑分区或者主分区,并把它转换成交换分区。

  1. 利用fdisk-n命令新建逻辑分区sda10
  2. 利用fdisk-t命令选择你想要转换的分区号(sda10),并通过L来查看可以转换成哪些分区,这里是82—交换分区

图1-15 fdisk-t 转换分区命令

(3)转换完毕之后用w命令保存,创建完或者说转换完交换分区我们应该如何使用?这就需要格式化它并且激活它。我们用sudo partprobe命令

重新读取分区表,再用sudo mkswap /dev/sda10 格式化swap交换分区,最后用sudo swapon /dev/sda10激活该分区。swapon -s 命令可以查看激活情况。

图1-16 创建并激活交换分区

图1-17 交换分区主要命令

  1. 激活了之后还需要自动挂载,不然再次重启后我们需要手动挂载。

我们使用 sudo gedit /etc/fstab 命令打开该配置文件并进行编辑。

图1-18 /etc/fstab介绍

图1-19 /etc/fstab配置文件

7.测试:利用磁盘使用工具和mount,将新创建的Linux系统分区挂载到系统中。将新挂载的分区卸载,并重新挂载到目录树的其他位置。观察挂载之前和之后的该目录下所存储的文件。

(1)在之前的步骤中我们已经将sda9挂载到/home/sda9这个文件夹下,我们在这个文件夹下面新写一个testfile.txt文件

图1-20 新写一个testfile.txt文件

(2)我们使用umonut命令将这个文件解挂(卸载)掉

图1-21 解挂

(3)上图可以看出已经解挂了,并且/home/sda9文件夹下面的全没了。

图1-22 重新挂载

这个时候挂载到新建的另一个文件夹上去,发现又有了。说明解挂只是将文件系统从目录树中移除,并不会删除分区或其中的数据。

拓展试验:

图1-23 三系统

Ubunto10.04

Windows XP

CentOS 7

实验二 Linux常用命令使用

一、实验目的

1.掌握Linux一般命令格式。

2.掌握有关文件和目录操作的常用命令。

3.熟练使用man命令。

二、实验内容

1.熟悉cd、date、pwd、cal、who、echo、clear、passwd等常用命令。

2.在用户主目录下对文件进行操作:复制一个文件、显示文件内容、查找指定内容、排序、文件比较、文件删除等。

3.对目录进行管理:创建和删除子目录、改变和显示工作目录、列出和更改文件权限等。

4.利用man命令显示date、echo等命令的手册页。

5.利用ps命令显示系统中的进程信息。

三、主要实验步骤

1.登陆系统,使用passwd命令修改密码为123456,并重新登录系统。

2.使用简单命令:date、cal、who、echo、clear等,了解Linux命令格式。

3.浏览文件系统:

  1. 运行pwd命令,确定当前工作目录。
  2. 运行ls –l命令,理解各字段含义。
  3. 运行ls –ai命令,理解各字段含义。
  4. 使用cd命令,将工作目录改到根(/)上。运行ls –l命令,结合教材中图2.2,了解各个目录的作用。
  5. 直接使用cd,通过pwd指令验证目录位置。
  6. 用mkdir建立一个子目录subdir。
  7. 将工作目录更改到subdir。

4.文件操作:

  1. 验证当前工作目录在subdir。
  2. 运行date>file1,然后运行cat file1,看到什么信息?
  3. 运行cat subdir,会出现什么结果?为什么?
  4. 利用man命令显示date命令的使用说明。
  5. 运行man date>>file1,看到什么信息?运行cat file1,看到什么信息?
  6. 显示file1的当前10行,后19行。
  7. 运行cp 文件名1  文件名2,然后ls –l,看到什么信息?运行mv 文件名2  文件名3,然后ls –l,看到什么信息?运行cat 文件名,结果如何?
  8. 运行rm 文件名3,然后ls –l,结果如何?
  9. 在/etc/passwd文件中查找合适你的注册名的行。
  10. 运行ls –l,理解各文件的权限是什么?
  11. 用两种方式改变file1的权限。
  12. 统计file1文件的行数、字数。
  13. 运行cat 文件名|wc -l,结果如何?

5.权限管理

假设目前要开发一个项目叫做LinuxDemo,参与人包括:zhao, qian, sun, li, zhou, wu六人,这六人的分组为如图1所示。请利用所学命令构造满足如下要求的用户权限模型。

具体要求如下:

0) 使用图1中的分组创建组,并将相应的学生添加到相应分组

1) 所有目录都保存在同一的文件夹下/LinuxDemo

2) 每个分组拥有独立的文件夹

3) 不同组之间不可访问各自的文件夹

4) 每个学生在所在组的文件夹下拥有一个所属的文件夹

5) 同组不同学生之间可以查看各自文件夹的内容,但不可以修改,学生只能修改自己的文件内容

6) 请设计测试用例,查看所设计的权限模型是否满足要求。

分组

学生

designing

zhao

qian

coding

sun

li

testing

zhou

wu

图1 LinuxCourse

6.进程管理

开启多个终端程序,使用ps命令是查看进程状态,并用kill命令结束其中一个终端程序。

7.文件压缩和解压

利用gzip命令对某个文件或文件夹进行压缩,然后再对其解压。使用unzip命令对Windows下生成的zip格式的压缩文件进行解压缩。

四、实验结果

1. 登陆系统,使用passwd命令修改密码为123456,并重新登录系统。(如图2-1)

2. 使用简单命令:date、cal、who、echo、clear等,了解Linux命令格式。(如图2-2)

图2-1 修改密码

图2-2 简单命令

3.浏览系统文件

(1)运行pwd命令,确定当前工作目录。

图2-3 pwd

(2)运行ls -l命令,理解各字段含义

       图2-4 ls -l

就拿第一行来说:(从左到右)

“-”表示普通文件

权限:所有者可读可写(rw-),组、其他用户只读(r--)

1代表硬链接数为1(硬链接是多个文件名指向同一个inode的不同目录条目)

两个rc分别代表所有者和所有组

文件大小是60215221字节(差不多57.4MB)

最后修改时间是2011年11月14日 12:05

文件名是VMwareTools-8.8.1-528969.tar.gz

(读是r,写是w,x是执行,d开头说明该项为目录)

  • 可列出内容(r)
  • 可创建/删除文件(w)
  • 可进入目录(x)

(3)运行ls –ai命令,理解各字段含义。

521264 .gnome2_private 

前面的数字是当前目录的inode号 后面的是文件名或目录名,如果加上一个点说明该文件或目录是隐藏的         

图2-5 ls -ai

(4)使用cd命令,将工作目录改到根(/)上。运行ls –l命令,结合教材中图2.2,了解各个目录的作用。

图2-6 根目录

bin 目录存放着基础命令的二进制文件

boot目录存储着系统启动文件

dev是设备文件接口

etc是全局配置文件中心

lib是核心共享库文件

home是普通用户主目录

root是超级用户root的主目录

lost+found 是文件系统修复后的碎片恢复区

mnt/media 是临时挂载点

proc是内核与进程的虚拟文件系统

sys是硬件设备的配置接口

tmp是存储临时文件

var是存储可变数据

opt是第三方独立软件安装目录

usr是用户级程序与文档

sbin是系统管理命令(需要root权限)

selinux存放着SELinux的安全策略文件

srv 存储服务数据

cdrom是为传统挂载点

  1. 直接使用cd,通过pwd指令验证目录位置

图2-7 home目录

(6)用mkdir建立一个子目录subdir,并将工作目录更改到此。

图2-8 mkdir命令

4. 文件操作:

(1)验证当前工作目录在subdir。

(2)运行date>file1,然后运行cat file1,看到什么信息?

(3)运行cat subdir,会出现什么结果?为什么?

如上图所示,出现了没有这个文件或者目录。这个原因是因为date命令的作用是显示或设置系统日期和时间,重定向到file1文件当中,文件内容会是当前的日期时间信息。而date命令只是输出日期时间信息,它不会创建目录,只是创建文件。如果用户想要保存到某个目录下的文件,需要确保该目录存在,或者使用正确的路径。而cat命令是用来查看文件内容的而不是目录。目录需要用ls命令查看。为什么系统报错是因为cat无法处理目录,是因为你在subdir里面查subdir当然找不到了你又没有再创建一个subdir目录,真的这个查了我半天,我退回到上一级才发现是有这个文件。

(4)利用man命令显示date命令的使用说明。

图2-8 man date命令

(5)运行man date>>file1,看到什么信息?运行cat file1,看到什么信息?

前者啥都没看见,后者看到了date命令的使用说明。(在终端命令行里没在文件里)

(6)显示file1的当前10行,后19行。

图2-9 head tail命令

(7)运行cp 文件名1  文件名2,然后ls –l,看到什么信息?运行mv 文件名2  文件名3,然后ls –l,看到什么信息?运行cat 文件名,结果如何?

Cat文件名看到的是file1里面的所有内容。

运行rm 文件名3,然后ls –l,结果如何?

删掉了呗,没了呗。

(8)在/etc/passwd文件中查找合适你的注册名的行。

(9)运行ls –l,理解各文件的权限是什么?同上

(10)用两种方式改变file1的权限。

分别是数值模式和符号模式

chmod 755 file1

作用:

通过 ​八进制数字模式 将文件 file1 的权限设置为:

  • 所有者 (u):rwx(读、写、执行)
  • 所属组 (g):r-x(读、执行,​无写权限
  • 其他用户 (o):r-x(读、执行,​无写权限

chmod u+x,g-w file1

作用:

通过 ​符号模式 进一步调整权限:

  1. ​**u+x:给文件所有者添加执行权限**​(即使已有)
  2. ​**g-w:从文件所属组移除写权限**​(如果存在)

权限变更解析:

  • 所有者 (u):确保执行权限存在(可能无实际变化)
  • 所属组 (g):若组有写权限(如 rw-),会变成 r--;若原本无写权限(如 r-x),则保持不变

(11)统计file1文件的行数、字数。

行、词数、字节

(12)运行cat 文件名|wc -l,结果如何?、

只统计行数

5.权限管理

假设目前要开发一个项目叫做LinuxDemo,参与人包括:zhao, qian, sun, li, zhou, wu六人,这六人的分组为如图1所示。请利用所学命令构造满足如下要求的用户权限模型。

具体要求如下:

0) 使用图1中的分组创建组,并将相应的学生添加到相应分组

1) 所有目录都保存在同一的文件夹下/LinuxDemo

2) 每个分组拥有独立的文件夹

3) 不同组之间不可访问各自的文件夹

4) 每个学生在所在组的文件夹下拥有一个所属的文件夹

5) 同组不同学生之间可以查看各自文件夹的内容,但不可以修改,学生只能修改自己的文件内容

6) 请设计测试用例,查看所设计的权限模型是否满足要求。

分组

学生

designing

zhao

qian

coding

sun

li

testing

zhou

wu

图1 LinuxCourse

 

图2-10 权限管理创建

su zhao

ls /LinuxDemo/designing          # 应该可访问

ls /LinuxDemo/coding             # 应该被拒绝

touch /LinuxDemo/designing/qian/test # 应该被拒绝

图2-11 权限管理验证成功

6.进程管理

开启多个终端程序,使用ps命令是查看进程状态,并用kill命令结束其中一个终端程序。

(三个终端在进行kill命令之后只剩下两个终端)

图2-12 终端4138被终止

7.文件压缩和解压

利用gzip命令对某个文件或文件夹进行压缩,然后再对其解压。使用unzip命令对Windows下生成的zip格式的压缩文件进行解压缩。

       图2-13 file文件压缩再解压

       图2-14 folder文件夹压缩再解压

sudo apt-get install unzip -y --allow-unauthenticated

安装完unzip

rc@rc-desktop:~$ unzip archive.zip

Archive:  archive.zip

replace file1? [y]es, [n]o, [A]ll, [N]one, [r]ename: y

inflating: file1 

                                           实验三 vi编辑器的使用

一、实验目的

1.学习使用vi编辑器建立、编辑、显示及加工处理文本文件。

二、实验内容

1.进入和退出vi编辑器。

2.利用文本插入方式建立一个文件。

3.在新建的文本文件上移动光标位置。

4.对该文件执行删除、复原、修改、替换等操作。

三、主要实验步骤

1.进入vi编辑器。

2.建立一个文件,如file.c。进入插入方式,输入一个C语言程序的各行内容,故意少写几个字符和几行内容。最后,将该文件存盘。回到shell状态下。

3.利用a,i,o等命令,将少写的内容填补到文件正确的位置,并且保存退出。

4.运行man date > file10,然后vi file10。使用x,dd等命令删除某些文本行。使用u命令复原此前的情况。使用c、r、s等命令修改文本内容。使用检索命令进行给定模式的检索。

四、拓展实验

1. 检查当前系统中是否存在Vim和Visual Studio Code编辑器?如果没有,请在系统里安装Vim和Visual Studio Code,并比较Vi、Vim和Visual Studio Code三个编辑器的使用差异。

五、实验结果    

X删除光标下的字母,dd删除整行,o加行并书写,p是粘贴,a是在行尾附加,hjkl左下上右,U撤销行内命令,u撤销命令,c整行删除并可书写,r是替换光标所指某一字符,s是删除光标所指字符并用占位符$替代等待输入替换的字符(替换字符),例如/DATE搜索DATE项,并按n跳转到下一个匹配项。

实验三主要实验步骤不作图片展示,已按照要求做完。

拓展试验:

sudo apt-get update 更新软件源缓存

sudo apt-get install vim 安装vim

vim –version 验证安装

在Ubunto10.04版本上难以下载VS Code,已安装Vim。

图3-2 多角度三者区别

VS Code更多是图形化界面带来的好处,就跟以前的DOS到后来的Windows质的飞跃一样,Vi/Vim学习成本要求很高,就算Vim增强了Vi的功能对于我小白来说,也是不友好的。VS Code美观,也适合大型项目开发。但是vim和vi有其不可替代性,例如终端环境下的唯一选择,具有轻量性与高效性,键盘驱动效率高于鼠标,系统兼容性好(比如10.04就很难安装VSCode)

图3-3 应用场景与缘由

图3-4 vi/vim键位图

实验四 shell编程

一、实验目的

1.了解shell的作用和主要分类。

2.掌握bash的建立和执行方式。

3.掌握bash的基本语法。

4.学会编写shell脚本。

二、实验内容

1.shell脚本的建立和执行。

2.shell变量和位置参数、环境变量。

3.bash的特殊字符。

4.一般控制结构。

5.算术运算及bash函数。

三、主要实验步骤

1.利用vi建立一个脚本文件,其中包括date、cal、pwd、ls等常用命令。然后以不同方式执行该脚本。

2.运行history命令。

3.体会bash的命令补全功能。

4.对教材例题4.9 (P108)进行编辑,然后执行。

5.对教材例题4.19 (P132)进行编辑,然后执行。

6.对习题4.8 (P141)进行编辑,然后执行。

7.对习题4.9进行设计,然后调试、执行。

8.对习题4.11进行设计,然后调试、执行。

9.对习题4.13进行设计,然后调试、执行。

10.对习题4.14进行设计,然后调试、执行。

四、拓展实验

1. Shell编程实现指定输入的加法,比如输入100,计算1+2+3+…+100的和。

2. Shell编程判断指定文件夹下文件的数量。

3. Shell编程判断给定年份是否为闰年。

4. Shell编程实现9×9乘法表。

5. Shell编程实现批量修改文件扩展名,比如将.txt文件修改为.doc文件。

五、实验结果

1. 利用vi建立一个脚本文件,其中包括date、cal、pwd、ls等常用命令。然后以不同方式执行该脚本。

图4-1 步骤一

2.运行history命令。

    图4-2 history命令

3.tab补全

(1)基本补全:(已测试)

输入命令前几个字母(如 his),按一次 Tab 自动补全为 history

若存在多个匹配项(如输入 ls 后按两次 Tab),会列出所有可能的补全选项( lsb_release、lsblk )

(2)路径和文件名补全:(已测试)

输入部分路径(如 cd /e 后按 Tab),自动补全为 /etc/

输入 ls /u 后按 Tab,补全为 /usr/

4.例题4.9

图4-2 例题4.9

5.例题4.19,见图4-3.

6.习题4.8

图4-3习题4.8

在做习题4.8的时候遇到了报错:

Line 3: [: 3-1: integer expression expected 2025

多番尝试后报错原因是expr语法“+”“-”符号前后要有空格

图4-4 例题4.19

7.习题4.9

首先创建3个目录,并且将三个目录地下分别创建各自的文件,然后执行命令。

/home/rc/file3' ->`/home/rc/file2/file3' # 复制目录

/home/rc/file3/file3' ->`/home/rc/file2/file3/file3' # 复制内部文件

Copied /home/rc/file3 to /home/rc/file2 # 完成提示

图4-5 习题4.9代码

结果:

代码:(见下页)

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

#!/bin/bash

if [ "$#" -lt 2 ]; then

    echo "Usage: $0 <destination_directory> <file_or_dir1> [file_or_dir2] ..."

    exit 1

fi

DEST_DIR="$1"

if [ ! -d "$DEST_DIR" ]; then

    echo "Error: Destination directory '$DEST_DIR' does not exist."

    exit 1

fi

shift  # 移除目标目录参数

for ITEM in "$@"; do

    if [ -e "$ITEM" ]; then

        cp -rv "$ITEM" "$DEST_DIR"  # -r 允许复制目录

        echo "Copied $ITEM to $DEST_DIR"

    else

        echo "Error: '$ITEM' does not exist."

    fi

done

File4目录里面的文件file4,File3目录里面的file3文件都放入到目录file2当中。实现结果。

8.习题4.11

代码:

1

2

3

4

5

6

#!/bin/bash

dir="$1"

shift

for file in "$@"; do

  cat "$dir/$file"  # file 应为目标目录下的文件名

done

结果:

rc@rc-desktop:~$ ./ex3 /home/rc/file2 file2 file3 file4

22

33

44

9.习题4.13

代码:

1

2

3

#!/bin/bash

cities=(北京 上海 广州 深圳 南京 苏州)

for city in "${cities[@]}"; do echo "$city"; done

结果:

10.习题14

代码:

1

2

3

4

5

6

7

a=1 b=1 sum=2;

for _ in {3..10};

 do c=$((a+b));

 sum=$((sum+c));

 a=$b; b=$c;

 done;

 echo $sum

结果:

11.拓展1 Shell编程实现指定输入的加法,比如输入100,计算1+2+3+…+100的和。

代码:

1

2

3

4

5

6

#!/bin/bash

n=$1; sum=0;

for i in $(seq 1 $n);

do ((sum+=i));

done;

echo $sum

结果:

12.Shell编程判断指定文件夹下文件的数量

代码:

1

2

#!/bin/bash

echo $(find "${1:-.}" -maxdepth 1 -type f | wc -l)

结果:

13.shell编程判断给定年份是否是闰年。

代码:

1

2

#!/bin/bash

(($1%4==0&&$1%100!=0||$1%400==0))&&echo Leapyear||echo NoLeapyear

结果:

14. 用shell编程实现9*9乘法表

代码:

1

2

3

4

5

6

7

#!/bin/bash

for i in {1..9};

do for j in $(seq 1 $i);

do echo -ne "$j×$i=$((i*j))\t";

done;

echo;

done

输出结果:

15.shell 编程将当前目录下所有.txt文件扩展名批量修改为.doc

代码:

1

2

#!/bin/bash

for f in *.txt; do mv -- "$f" "${f%.txt}.doc"; done

结果:

实验五 常用开发工具

一、实验目的

1.掌握C语言编译的基本用法。

2.掌握gdb调试工具的基本用法。

3.理解make工具的功能,学会编制makefile的方法。

二、实验内容

1.利用gcc编译C语言程序,使用不同的选项,观察并分析显示结果。

2.用gdb调试一个编译后的C语言程序。

3.编写一个由多个文件构成的C语言程序,编制makefile,运行make工具进行维护。

三、主要实验步骤

1.按照教学视频“Gcc编程和Gdb调试范例”和“静态链接库和动态链接库的创建和调用”,掌握视频中的内容,熟悉下列选项在编译过程中的作用:-c,-o,-l,-L。

2.按照教学视频“程序维护工具make的使用”,重写做一遍,要掌握依赖关系图的画法、makefile文件的编写、及make工具的使用。

3.完成对习题6.9的编制,并使用make进行维护(参考教学视频,自己制作动态链接库文件libm.so)。

四、实验结果

1.步骤一

1)编写源代码

1

2

3

4

5

6

#include<stdio.h>

int main()

{

        puts("Haha,I am RC");

        return 0;

}

2)代码编译完整过程

预处理->编译->汇编->链接

3)编译源代码:

gcc -o output example.c

-o用于指定生成的可执行文件的名称,output是输出文件的名称,example.c是源代码文件的名称。

也可以写做:gcc example.c -o output

4gcc常用选项

-c:只编译源代码,生成目标文件(xx.o)而不进行链接。

-E:只进行预处理,生成预处理后的源代码文件。

-O:优化生成的代码,可以使用-O1、-O2或-O3进行不同级别的优化

-g:生成调试信息,以便进行源代码级调试。

-Wall:显示编译时的警告信息。

-std:指定所使用的C语言标准,如-std=c11。

-I:指定包含头文件的目录。

-L:指定链接库文件的目录。

-l:链接指定的库文件。

5)使用GDB调试

1)参数:

-g:在可执行文件中包含调试信息,以便GDB能够进行源代码级别的调试。

-tui:以文本用户界面(TUI)模式启动GDB,该模式提供了源代码窗口和调试器命令窗口。

-b:指定调试器使用的调试文件格式,如ELF、COFF等。

-ex:在启动GDB后立即执行指定的命令。

-core <core文件>:指定要调试的核心转储文件。

-x <脚本文件>:从指定的文件中读取GDB命令,可以用于自动执行一系列的调试命令。

-args <可执行文件> <参数>:指定要调试的可执行文件及其命令行参数。

-p <进程ID>:连接到指定的正在运行的进程进行调试。

2)编译源代码:

1

gcc -g -o exp example.c

3)启动gdb

1

gdb exp

4)设置断点break 运行程序run

*在程序执行过程中,可以使用以下常用命令来调试程序: 

run:从头运行程序(简写r)。

break:继续设置断点(简写b)。

next:执行下一行代码(简写n)。

step:进入函数调用,逐行执行函数内部的代码(简写s)。

print variable:打印变量variable的值(简写p)。

watch variable: 监视变量variable的值,当变量的值发生改变时,停止程序的执行(简写w)。

continue:继续执行程序直到下一个断点或程序结束(简写c)。

backtrace:显示当前函数调用的堆栈跟踪信息(简写bt)。

quit:退出GDB调试器(简写q)。

finish: 执行到当前函数返回为止(简写fin)。

2.主要实验步骤二

1)撰写4.c文件 1.h文件 一个makefile文件

2)创建共享库

3)最后make编译

*依赖关系图的理解:

假设当前工程目录为prj/,该目录下有6个文件,分别是:main.c、abc.c、xyz.c、abc.h、xyz.h和Makefile。其中main.c包含头文件abc.h和xyz.h,abc.c包含头文件abc.h,xyz.c包含头文件xyz.h,而abc.h又包含了xyz.h。

                                                                              

  1. 主要步骤三

defs.h​(公共头文件)

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#ifndef DEFS_H

#define DEFS_H

// 公共函数声明

void common_function();

int calculate_value(int base);

#endif

a.c(主程序)

#include <stdio.h>

#include "defs.h"

// 声明汇编函数

extern int assembly_add(int a, int b);

int main() {

    common_function();

     

    // 调用汇编函数

    int sum = assembly_add(10, 20);

    printf("Assembly result: %d\n", sum);

     

    // 调用数学库函数

    double root = sqrt(25.0);

    printf("Custom sqrt(25) = %.2f\n", root);

     

    return 0;

}

b.c​(模块B

1

2

3

4

5

6

7

8

#include <stdio.h>

#include "defs.h"

 

void common_function() {

    printf("Module B: Common function called\n");

    int val = calculate_value(5);

    printf("Calculated value: %d\n", val);

}

c.c​(模块C

1

2

3

4

5

#include <stdio.h>

 

void module_c_function() {

    printf("Module C: Additional functionality\n");

}

d.c​(模块D

1

2

3

4

5

6

#include <stdio.h>

#include "defs.h"

int calculate_value(int base) {

    return base * 2 + 10;

}

math.c​(数学库实现)

01

02

03

04

05

06

07

08

09

10

11

12

13

#include <math.h>

 

// 修改循环变量声明方式

double sqrt(double x) {

    int i;  // 将变量声明移到循环外

    if(x < 0.0) return NAN;

     

    double guess = x / 2.0;

    for(i = 0; i < 20; i++) {  // 移除循环内的变量声明

        guess = 0.5 * (guess + x / guess);

    }

    return guess;

}

assmb.s​(汇编模块)

01

02

03

04

05

06

07

08

09

10

11

12

13

.section .text

.global assembly_add

 

assembly_add:

    push %ebp

    mov %esp, %ebp

     

    mov 8(%ebp), %eax

    add 12(%ebp), %eax

     

    mov %ebp, %esp

    pop %ebp

ret

编译和运行:

make       # 编译项目

./prog     # 运行程序

make clean # 清理构建文件

结果:

Makefile(见下页)

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

# 编译配置

CC = gcc

AS = as

CFLAGS = -Wall -I.

LDFLAGS = -L./lib -lm -Wl,-rpath='$$ORIGIN/lib'

 

# 文件设置

C_SRCS = a.c b.c c.c d.c

ASM_SRC = assmb.s

OBJS = $(C_SRCS:.c=.o) $(ASM_SRC:.s=.o)

TARGET = prog

LIB_DIR = lib

LIB_NAME = libm.so

 

.PHONY: all clean

 

all: $(LIB_DIR)/$(LIB_NAME) $(TARGET)

 

$(TARGET): $(OBJS)

    $(CC) $^ -o $@ $(LDFLAGS)

 

%.o: %.c

    $(CC) $(CFLAGS) -c $< -o $@

 

%.o: %.s

    $(AS) $< -o $@

 

# 修改后的动态库规则

$(LIB_DIR)/$(LIB_NAME): math.c

    @mkdir -p $(LIB_DIR)

    $(CC) -std=c99 -shared -fPIC $< -o $@

 

b.o d.o: defs.h

 

clean:

    rm -f $(OBJS) $(TARGET)

    rm -rf $(LIB_DIR)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值