课程
实验二 Linux 编程基础 题目整理
实验二 Linux 编程基础 题目整理
本文件根据原始实验题目材料整理,已统一为适合 GitHub 提交的 Markdown 版本。
题目材料 1:实验二 Linux 编程基础
一、实验目的
- 学习使用
vi编辑器建立、编辑、显示以及加工处理文本文件。 - 熟悉 Linux 下使用 C 语言编程的方法。
二、实验题目
- 使用
vi编辑 C 语言源程序 - 使用
gcc、make等工具进行编译;执行编译生成的执行文件并分析结果
三、背景材料
因实验用的 Linux 环境以字符界面为主,而 Linux 的字符界面并没有广泛使用的集成开发环境,经典的 C 语言开发模式还是使用文本编辑软件编写源程序,然后使用 gcc 和 make 工具进行编译链接,生成可执行文件。在编辑源程序环节,可以使用不同的文本编辑工具,例如在图形用户界面下可以使用 gedit 或者 kedit;字符界面下可以使用 vi、emacs、nano 等编辑器;甚至可以在其它环境下编辑。
(一)编辑器 vi 的使用
vi 或 vim 是 Linux 系统上经典的文本编辑工具,在字符界面下,广泛用于系统管理、程序开发。本实验要求熟悉 vi 基本操作,可以使用 vi 进行文本编辑。
1、调用 vi
最常用的命令模式是:vi filename
2、vi 的三种模式
- Command(命令)模式:用于输入命令
- Insert(插入)模式:用于插入文本
- Visual(可视)模式:用于可视化的高亮并选定正文
3、文件的保存和退出
Command 模式是 vi 的默认模式,如果处于其它模式时,要通过 ESC 键切换过来,接着再输入 : 号时,vi 会在屏幕的最下方等待输入命令:
:w保存:w filename另存为 filename:wq!保存退出:wq! filename以 filename 为文件名保存后退出:q!不保存退出:x保存并退出,功能和:wq!相同
4、光标移动
按 ESC 进入 Command 模式后,可以用下面的一些键位来移动光标:
j向下移动一行k向上移动一行h向左移动一个字符l向右移动一个字符Ctrl+B向上移动一屏Ctrl+F向下移动一屏- 向上箭头 向上移动
- 向下箭头 向下移动
- 向左箭头 向左移动
- 向右箭头 向右移动
对于 j、k、l 和 h 键,还能在这些命令的前面加上数字,比如 3j,表示向下移动 3 行。
5、进入插入模式
i在光标之前插入a在光标之后插入I在光标所在行的行首插入A在光标所在行的行末插入o在光标所在的行的上面插入一行O在光标所在的行的下面插入一行s删除光标后的一个字符,然后进入插入模式S删除光标所在的行,然后进入插入模式
6、文本内容的删除
x删除一个字符#x删除几个字符,#表示数字,比如3xdw删除一个单词#dw删除几个单词,#用数字表示,比如3dw表示删除三个单词dd删除一行#dd删除多个行,#代表数字,比如3dd表示删除光标行及光标的下两行d$删除光标到行尾的内容J清除光标所处的行与上一行之间的空格,把光标行和上一行接在一起
7、可视模式
在最新的 Linux 发行版本中,vi 提供了可视模式。按 ESC 键,然后按 v 就进入可视模式;退出可视模式,还是用 ESC 键。可视模式提供了友好的选取文本范围,以高亮显示。
8、复制和粘贴的操作
- 复制:对于可视模式下选中的文本,可以按
y进行复制;按yy可以复制当前光标所在行。此外,删除也带有剪切的意思,当我们删除文字时,相应内容会自动复制。 - 粘贴:可以把光标移动到某处,然后按
p或Shift+P键进行粘贴,其中p在光标之后粘帖,Shift+P在光标之前粘帖。
9、行号
可以在命令模式输入 :set number 来打开行号显示,输入 :set nonumber 来关闭行号显示。
10、查找功能
在命令模式下,输入 / 或 ? 就可以进行查找:
/SEARCH正向查找,按n键把光标移动到下一个符合条件的地方?SEARCH反向查找,按Shift+N键,把光标移动到下一个符合条件的地方
11、替换功能
按 ESC 键进入命令模式:
:s /SEARCH/REPLACE/g把当前光标所处的行中的 SEARCH 单词替换成 REPLACE,并把所有 SEARCH 高亮显示:%s /SEARCH/REPLACE把文档中所有 SEARCH 替换成 REPLACE:#,# s /SEARCH/REPLACE/g#号表示数字,表示从多少行到多少行,把 SEARCH 替换成 REPLACE
注:命令中
g表示全局查找,在指定的替换范围之外,也会把 SEARCH 高亮显示。
(二)gcc 和 make 的使用
Linux 下编辑好的 C 语言程序,需要使用 gcc 编译工具(Linux 系统上一般也可以通过 cc 别名调用)进行编译连接,生成可执行文件。对于复杂的应用,可能把多个源程序分别编译,最后连接形成执行文件;为了有效管理这类项目,make 代码维护工具可以用来定义一系列规则来管理编译连接过程。
【注】Linux 下的可执行文件没有特别的后缀名约定,而是通过设置”可执行”属性来区分;另外,Linux 默认的执行文件搜索路径也不包括当前目录,所以编译生成的执行文件需要显示指明文件路径来执行。
1、gcc 的使用
(1) 简单使用方法
假设一个 C 语言源程序名为 hello.c,根据该文件生成执行文件的最简单命令为:
$ gcc hello.c
该命令将生成默认名字为 a.out 的执行文件;如果希望生成执行文件的名字不同,可以在命令中通过参数指定:
$ gcc -o hello hello.c
该命令将生成名字为 hello 的执行文件。
(2) 分解使用
实际上,gcc 所做的工作包括预编译、编译、连接等多个环节,上述简单用法隐含了对这几个环节的调用,如果需要分开调用,可以通过不同的命令行参数指定:
$ gcc -E hello.c -o hello.i # -E 参数指定进行预编译,预处理的宏定义插入到 hello.i 中
$ gcc -c hello.i -o hello.o # -c 参数指定编译为目标代码 hello.o,也可以通过源文件直接生成 (gcc -c hello.c)
$ gcc hello.o -o hello # 将生成可执行文件,如果由多个源程序文件生成,一般需要在生成时指定多个目标代码模块
(3) 常用参数
gcc 命令行的常用参数如下:
| 参数 | 含义 |
|---|---|
-c | 通知 GCC 取消链接步骤,即编译源码并在最后生成目标文件 |
-Dmacro | 定义指定的宏,使它能够通过源码中的 #ifdef 进行检验 |
-E | 不经过编译预处理程序的输出而输送至标准输出 |
-g3 | 获得有关调试程序的详细信息,它不能与 -o 选项联合使用 |
-Idirectory | 在包含文件搜索路径的起点处添加指定目录 |
-llibrary | 提示链接程序在创建最终可执行文件时包含指定的库 |
-O、-O2、-O3 | 将优化状态打开,该选项不能与 -g 选项联合使用 |
-S | 要求编译程序生成来自源代码的汇编程序输出 |
-v | 启动所有警报 |
-Wall | 在发生警报时取消编译操作,即将警报看作是错误 |
-Werror | 在发生警报时取消编译操作,即把报警当作是错误 |
-w | 禁止所有的报警 |
2、make 的使用
(1) make 工具简介
make 是一种代码维护工具,在大中型项目中,根据程序各个模块的更新情况,自动的维护和生成目标。能很好的做到”不多、不重、不漏”:
- 不多:只更新那些需要更新的文件,而不动那些并不过时的东西
- 不重:是指当
make对某个文件进行更新时,即使有很多文件过时,也将只更新一次 - 不漏:是指他不会漏下任何应该更新的文件
make 在使用时有一系列的规则,将根据这些规则来解释其配置脚本,以达到设计目的。配置脚本的缺省名是 makefile 或 Makefile,也可在命令行指定其它文件名。使用形式为:
$ make [option] [macrodef] [target]
option 指出 make 的工作行为,具体参数可参考 man 手册页。
(2) makefile 文件编写
make 工具使用的关键是编写高效、简洁、正确的 makefile,这需要学习和实践。虽然 make 工具的使用有较高的门槛,但是一旦掌握,其带来的灵活和便捷远远超过一般 IDE 所能提供的管理功能。
实际 makefile 文件编写涉及的知识很多,有专著专门进行讲解。此处只是介绍概貌,借助一个简单的例子来说明:假设一个项目 hello,依赖于 hello.o、e1.o、e2.o,而 hello.o 依赖于 hello.c、hello.h,e1.o 依赖于 e1.c、hello.h,e2.o 依赖于 e2.c;这样形成一棵依赖关系树,父节点依赖于子节点。使用 make 进行维护时,会对这棵树进行一次遍历,如果发现子节点形成的时间晚于父节点形成的时间便开始调用 makefile 中指定的命令进行维护。针对此例子的 makefile 示例如下:
hello: hello.o e1.o e2.o
gcc -o hello hello.o e1.o e2.o
main.o: hello.c hello.h
gcc -c hello.c
e1.o: e1.c hello.h
gcc -c e1.c hello.h
e2.o: e2.c
gcc -c e2.c
makefile 放置在与项目源程序文件相同目录中,在该目录中执行 make hello 或者 make 命令(命令行未 target 时会默认使用 makefile 的第一个 target),将会根据 makefile 中定义的依赖关系依次执行编译、连接各个命令,生成 hello 执行文件。
实际项目的 makefile 因为会使用大量的宏、条件变量以及缺省规则,对初学者而言较难理解。对于一般的开源项目,在编写 makefile 时,target 的命名都会遵循一些约定俗成的规则,常见的用法包括:
make all编译项目中所有实际目标make install进行安装make clean清除所有中间文件
(3) 缺省规则和简单用法
make 的缺省规则是系统或者自定义的一些规则,在定义时不指出全名,而是根据文件扩展名定义一类依赖关系和相关命令。例如,与 C 语言相关的缺省规则包括:
.c:
$(CC) $(FLAGS) -o $@ $<
.c.o:
$(CC) $(FLAGS) -c $@ $<
两条规则的含义为:对于 .c 扩展名的文件,调用编译器(通过环境变量 CC 定义,默认为 gcc)生成与 .c 文件对应名字的执行文件;对于 .o、.c 扩展名配对的情况,调用编译器进行编译,生成与 .c 文件对应名字的 .o 目标文件。
根据这些缺省规则,可以在简单情况下不编写 makefile 使用 make 工具。例如,对于根据 hello.c 生成 hello 执行文件的情况,可以直接使用命令:
$ make hello
效果等同于:gcc -o hello hello.c













