南京晓庄学院网络编程 实验2

南京晓庄学院网络编程  实验2
南京晓庄学院网络编程  实验2

VI VIM文本编辑器

1、关于文本编辑器;

文本编辑器有很多,比如图形模式的gedit、kwrite、OpenOffice ... ... ,文本模式下的编辑器有vi、vim(vi 的增强版本)和nano ... ... vi和vim是我们在Linux中最常用的编辑器。我们有必要介绍一下vi(vim)最简单的用法,以让Linux入门级用户在最短的时间内学会使用它。

nano 工具和DOS操作系统下的edit操作相似,使用简单,我们不作介绍了,如果您有兴趣,不妨尝试一下;

vi编辑器是Linux环境下提供的重要的文本编辑工具。vi功能强大,不逊色于任何编辑器。大多在Linux环境下的源程序是使用vi书写的。

应重点掌握如下内容:

q 了解vi编辑器的工作方式;

q 掌握vi编辑器常用的编辑功能;

q 能够使用vi编辑器灵活地进行文件编辑操作

2、vi 编辑器;

为什么要学会简单应用vi

vi或vim是Linux最基本的文本编辑工具,vi或vim虽然没有图形界面编辑器那样点鼠标的简单操作,但vi编辑器在系统管理、服务器管理中,永远不是图形界面的编辑器能比的。当您没有安装X-windows桌面环境或桌面环境崩溃时,我们仍需要字符模式下的编辑器vi;

vi或vim 编辑器在创建和编辑简单文档最高效的工具;

3、vi 编辑器的使用方法;

一、用vi filename打开文件:

二、基本知识:vi 可以分三种状态:命令模式(command)、插入模式(insert)和末行模式(last line)

(1)命令模式:打开文件时默认是命令模式,控制屏幕光标的移动、字符、字或者行的删除,移动复制;进入insert (按i:在光标位置插入;按a在光标所在位置的后一个字符开始增加;按o 插入新的一样从行首开始输入)或者last line 模式(按shift + :)

(2)插入模式:只有insert模式可以做文字输入,按esc退回command 模式。

(3)末行模式:将文件保存或者退出vi。也可以执行找字符、列行号等命令。

三、各种命令(请注意在何种模式下和大小写):

1 定位某一行:

(1)set number:(末行模式)可以给文本加行号。

(2)跳至某一行:(末行模式),直接输入行号,按enter。如100行,:100 (3)nu:(末行模式)可以输入命令nu(number缩写)来获得光标当前行的行号与该行内容。

(4)#G:(命令模式)按#G跳至#行行首,如15G即跳到15行行首。

(5)ctrl+g:(命令模式)列出光标所在的行号。

2 查找关键字(末行模式):

(1)? 在当前位置向上查找,输入?关键字。如?authorize。如果第一次找的不是你要的关键字,可以按n在同一方向继续查找,按N 往反方向执行上一次搜索。

(2)/ 在当前位置向下查找,输入/关键字。如/authorize。如果第一次找的不是你要的关键字,可以按n在同一方向继续查找,按N 往反方向执行上一次搜索

3 移动光标:

(1)在insert模式下,可直接使用键盘上的四个方向键移动光标。

(2)在命令模式下,可以使用四个方向键来移动光标,还可以用h、j、k、l这四个键代替四个方向键来移动光标,

(3)-: (command模式)光标上移之后,光标位于该行的行首,则可以使用命令“-”。

(4)0: (末行模式)输入数字0,移动到文章开头。

(5)G: (command模式)按G,移动到文章末尾。

(6)$: (command模式)输入符号$,移动到本行行尾。

(7)^: (command模式)输入符号^,移动到本行行首。

(8)e:(command模式)到下一行行尾。

(9)b:(command模式)到上一行行首

(10)

4 退出vi(末行模式):

(1)q 然后enter(不保存直接退出)

(2)wq 然后enter(保存后退出)

(3)q! 然后enter(不保存强制退出)

(4)wq! 然后enter(强制保存后退出)

5 浏览换页(命令模式):

(1)ctrl + b 屏幕往后移动一页

(2)ctrl + u 屏幕往后移动半页

(3)ctrl + f 屏幕往前移动一页

(4)ctrl + d 屏幕往前移动半页

6 删除文字:

(1)x:每按一次x,删除光标所在位置后的一个字符。#x (#是指数字),即删除光标后#个字符。

(2)X: 每按一次X,删除光标所在位置前的一个字符。#X (#是指数字),即删除光标前#个字符。

(3)dd:删除光标所在行。#dd(#是只数字):从光标所在行开始删除#行。

(4)cw:改变光标所在位置的“单词”。

(5)dw:删除光标所在位置的“单词”。

(6)*,*d: 如20,100d。表示删除20到100行。(末行模式)

7 复制与粘贴:

(1)yw:将光标所在之处到字尾的字符复制到缓冲区。#yw:将#个字符复制到缓冲区。

(2)yy:复制光标所在行到缓冲区。#yy:将光标所在行往下数#行复制。

(3)p:将缓冲区内的字符贴到光标所在位置。所有与y有关的复制都要与p配合用才完成复制粘贴

8 恢复上一次操作:u (相当于windows的撤销)

9 替换与更改:

(1)r:替换光标所在处的字符

(2)R:替换光标所到之处的字符,直到按下ESC退出为止。

(3)cw:更改光标所在处的字到字尾处。

(4)c#w:如c3w表示更改3个字。

(5):3,$s/^/some string/在文件的第一行到最后一行的行首插入"some string"

(6):%s/$/some string/g 在整个文件每一行的行尾添加“some string”

(7):%s/string1/string2/g 在整个文件替换“string1”为“string2”

(8):3,7%s/string1/string2/g 替换文件中3-7行“string1”为“string2”

s---substitute,%表示所有行,g表示global。

10 同时编辑2个文件:

(1)vi file1 file2

(2)yy 在file1光标处拷贝

(3):n 切换到file2 (n=next)

(4):n 切换回file1

11 替换文件中的路径:

使用命令“:%#/usr/bin#/bin#g”可以把文件中所有路径/usr/bin切换为/bin。也可以用“:%//usr/bin//bin/g”

12 移动、拷贝和删除行(末行模式):

(1):n1,n2 co n3 将n1到n2行之间的内容拷贝到第n3行下

(2):n1,n2 m n3 将n1到n2行之间的内容移至到第n3行下

(3):n1,n2 d 将n1行到n2行之间的内容删除

还有一些移动光标的命令。下面对它们的工作方

式介绍如下:

(r) (均称为右向键)

右向键的作用是将光标向右移动一个位置。若在向右键前先输入一个数字n,那么光标就

向右移动n个位置。例如5l表示光标向右移动5个位置。需要注意的是,光标移动不能超

过当前行的末尾。若给定的n超过光标当前位置至行尾的字符个数,如果用右向键,光标

只能移到行尾;如果用,光标移到下面一行或几行的适当位置。

h、、- (向左键)

执行一次向左键,光标向左移动一个位置。同向右键一样,也可以在向左键的前面输入

一个数字n,那么光标就向左移动n个位置。需要注意的是,如果用左向键,光标左移不

能超出该行的开头;如果用,光标移到上面一行或几行的适当位置。

j、、ˉ(向下键)

执行一次向下键光标向下移动一个位置(即一行),但光标所在的列不变。当这些命令

前面加上数字n,则光标下移n行。

Vi除了可以用向下键将光标下移外,还可以用键和“+”键将光标下移一行或n 行(不包

括本行在内),但此时光标下移之后将位于该行的第一个字符处。例如:

3j 光标下移3行,且光标所在列的位置不变。

3+或3 光标下移3行,且光标位于该行的行首。

k、、(向上键)

执行一次向上键光标向上移动一个位置(即一行),但光标所在的列不变。同样在这些

命令前面加上数字n,则光标上移n行。

若希望光标上移之后,光标位于该行的行首,则可以使用命令“- ”。

L (移至行首)

L 命令是将光标移到当前行的开头,即将光标移至当前行的第一个非空白处(非制表符

或非空格符)。

$(移至行尾)

该命令将光标移到当前行的行尾,停在最后一个字符上。若在$命令之前加上一个数字n

,则光标下移n-1行并到达行尾。

[行号] G(移至指定行)

该命令将光标移至指定行号所指定的行的行首。这种移动称为绝对定位移动。

环境变量:

进入vi的命令vi filename :打开或新建文件,并将光标置于第一行首vi +n filename :打开文件,并将光标置于第n行首vi + filename :打开文件,并将光标置于最后一行首vi +/pattern filename:打开文件,并将光标置于第一个与pattern匹配的串处vi -r filename :在上次正用vi编辑时发生系统崩溃,恢复filenamevi filename....filename :打开多个文件,依次编辑。

实例

用vi 建个文件test.c,输入下面的内容

#include

int main()

{

printf("Hello World C!\n");

return 0;

}

三、编译

用命行$ gcc test.c -o test进行编译链接

用命令行$ ./test运行

GCC系统

一、GCC简介

通常所说的GCC是GUN Compiler Collection的简称,除了编译程序之外,它还含其他相关工具,所以它能把易于人类使用的高级语言编写的源代码构建成计算机能够直接执行的二进制代码。GCC是Linux平台下最常用的编译程序,它是Linux平台编译器的事实标准。同时,在Linux平台下的嵌入式开发领域,GCC也是用得最普遍的一种编译器。GCC之所以被广泛采用,是因为它能支持各种不同的目标体系结构。例如,它既支持基于宿主的开发(简单讲就是要为某平台编译程序,就在该平台上编译),也支持交叉编译(即在A平台上编译的程序是供平台B使用的)。目前,GCC支持的体系结构有四十余种,常见的有X86系列、Arm、PowerPC等。同时,GCC还能运行在不同的操作系统上,如Linux、Solaris、Windows等。

除了上面讲的之外,GCC除了支持C语言外,还支持多种其他语言,例如C++、Ada、Java、Objective-C、FORTRAN、Pascal等。

本系列文章中,我们不仅介绍GCC的基本功能,还涉及到一些诸如优化之类的高级功能。另外,我们还考察GCC的一些映像操作工具,如size和objcopy等,这将在后续的文章中加以介绍。

二、程序的编译过程

对于GUN编译器来说,程序的编译要经历预处理、编译、汇编、连接四个阶段,如下图所示:

从功能上分,预处理、编译、汇编是三个不同的阶段,但GCC的实际操作上,它可以把这三个步骤合并为一个步骤来执行。下面我们以C语言为例来谈一下不同阶段的输入和输出情况。

在预处理阶段,输入的是C语言的源文件,通常为*.c。它们通常带有.h之类头文件的包含文件。这个阶段主要处理源文件中的#ifdef、#include和#define命令。该阶段会生成一个中间文件*.i,但实际工作中通常不用专门生成这种文件,因为基本上用不到;若非要生成这种文件不可,可以利用下面的示例命令:

在编译阶段,输入的是中间文件*.i,编译后生成汇编语言文件*.s 。这个阶段对应的GCC命令如下所示:

在汇编阶段,将输入的汇编文件*.s转换成机器语言*.o。这个阶段对应的GCC命令如下所示:

最后,在连接阶段将输入的机器代码文件*.s(与其它的机器代码文件和库文件)汇集成一个可执行的二进制代码文件。这一步骤,可以利用下面的示例命令完成:

上面介绍了GCC编译过程的四个阶段以及相应的命令。下面我们进一步介绍常用的GCC的模式。

三、GCC常用模式

这里介绍GCC追常用的两种模式:编译模式和编译连接模式。下面以一个例子来说明各种模式的使用方法。为简单起见,假设我们全部的源代码都在一个文件test.c中,要想把这个源文件直接编译成可执行程序,可以使用以下命令:

这里test.c是源文件,生成的可执行代码存放在一个名为test 的文件中(该文件是机器代码并且可执行)。-o 是生成可执行文件的输出选项。如果我们只想让源文件生成目标文件(给文件虽然也是机器代码但不可执行),可以使用标记-c ,详细命令如下所示:

默认情况下,生成的目标文件被命名为test.o,但我们也可以为输出文件指定名称,如下所示:

上面这条命令将编译后的目标文件命名为mytest.o,而不是默认的test.o。

迄今为止,我们谈论的程序仅涉及到一个源文件;现实中,一个程序的源代码通常包含在多个源文件之中,这该怎么办?没关系,即使这样,用GCC处理起来也并不复杂,见下例:

该命令将同时编译三个源文件,即first.c、second.c和third.c,然后将它们连接成一个可执行程序,名为test。

需要注意的是,要生成可执行程序时,一个程序无论有有一个源文件还是多个源文件,所有被编译和连接的源文件中必须有且仅有一个main函数,因为main函数是该程序的入口点(换句话说,当系统调用该程序时,首先将控制权授予程序的main函数)。但如果仅仅是把源文件编译成目标文件的时候,因为不会进行连接,所以main函数不是必需的。

四、常用选项

许多情况下,头文件和源文件会单独存放在不同的目录中。例如,假设存放源文件的子目录名为./src,而包含文件则放在层次的其他目录下,如./inc。当我们在./src 目录下进行编译工作时,如何告诉GCC到哪里找头文件呢?方法如下所示:

上面的命令告诉GCC包含文件存放在./inc 目录下,在当前目录的上一级。如果在编译时需要的包含文件存放在多个目录下,可以使用多个-I 来指定各个目录:

这里指出了另一个包含子目录inc2,较之前目录它还要在再上两级才能找到。

另外,我们还可以在编译命令行中定义符号常量。为此,我们可以简单的在命令行中使用-D选项即可,如下例所示:

上面的命令与在源文件中加入下列命令是等效的:

在编译命令行中定义符号常量的好处是,不必修改源文件就能改变由符号常量控制的行为。

五、警告功能

当GCC在编译过程中检查出错误的话,它就会中止编译;但检测到警告时却能继续编译生成可执行程序,因为警告只是针对程序结构的诊断信息,它不能说明程序一定有错误,

而是存在风险,或者可能存在错误。虽然GCC提供了非常丰富的警告,但前提是你已经启用了它们,否则它不会报告这些检测到的警告。

在众多的警告选项之中,最常用的就是-Wall选项。该选项能发现程序中一系列的常见错误警告,该选项用法举例如下:

该选项相当于同时使用了下列所有的选项:

◆unused-function:遇到仅声明过但尚未定义的静态函数时发出警告。

◆unused-label:遇到声明过但不使用的标号的警告。

◆unused-parameter:从未用过的函数参数的警告。

◆unused-variable:在本地声明但从未用过的变量的警告。

◆unused-value:仅计算但从未用过的值得警告。

◆Format:检查对printf和scanf等函数的调用,确认各个参数类型和格式串中的一致。

◆implicit-int:警告没有规定类型的声明。

◆implicit-function-:在函数在未经声明就使用时给予警告。

◆char-subscripts:警告把char类型作为数组下标。这是常见错误,程序员经常忘记在某些机器上char有符号。

◆missing-braces:聚合初始化两边缺少大括号。

◆Parentheses:在某些情况下如果忽略了括号,编译器就发出警告。

◆return-type:如果函数定义了返回类型,而默认类型是int型,编译器就发出警告。同时警告那些不带返回值的return语句,如果他们所属的函数并非void类型。

◆sequence-point:出现可疑的代码元素时,发出报警。

◆Switch:如果某条switch语句的参数属于枚举类型,但是没有对应的case语句使用枚举元素,编译器就发出警告(在switch语句中使用default分支能够防止这个警告)。超出枚举范围的case语句同样会导致这个警告。

◆strict-aliasing:对变量别名进行最严格的检查。

◆unknown-pragmas:使用了不允许的#pragma。

◆Uninitialized:在初始化之前就使用自动变量。

需要注意的是,各警告选项既然能使之生效,当然也能使之关闭。比如假设我们想要使用-Wall来启用个选项,同时又要关闭unused警告,利益通过下面的命令来达到目的:

下面是使用-Wall选项的时候没有生效的一些警告项:

◆cast-align:一旦某个指针类型强制转换时,会导致目标所需的地址对齐边界扩展,编译器就发出警告。例如,某些机器上只能在2或4字节边界上访问整数,如果在这种机型上把char *强制转换成int *类型,编译器就发出警告。

◆sign-compare:将有符号类型和无符号类型数据进行比较时发出警告。

◆missing-prototypes :如果没有预先声明函数原形就定义了全局函数,编译器就发出警告。即使函数定义自身提供了函数原形也会产生这个警告。这样做的目的是检查没有在头文件中声明的全局函数。

◆Packed:当结构体带有packed属性但实际并没有出现紧缩式给出警告。

◆Padded:如果结构体通过充填进行对齐则给出警告。

◆unreachable-code:如果发现从未执行的代码时给出警告。

◆Inline:如果某函数不能内嵌(inline),无论是声明为inline或者是指定了-finline-functions 选项,编译器都将发出警告。

◆disabled-optimization:当需要太长时间或过多资源而导致不能完成某项优化时给出警告。

上面是使用-Wall选项时没有生效,但又比较常用的一些警告选项。本文中要介绍的最后一个常用警告选项是-Werror。使用该选项后,GCC发现可疑之处时不会简单的发出警告就算完事,而是将警告作为一个错误而中断编译过程。该选项在希望得到高质量代码时非常有用。

六、小结

本文介绍了GCC的基本编译过程和编译模式,初学时最好从命令行入手,这样可以熟悉从编写程序、编译、调试和执行的整个过程。编写程序可以用vi或其它编辑器编写。编译则使用GCC命令。要往下学习首先就得熟悉GCC命令的用法。

GCC命令提供了非常多的命令选项,但并不是所有都要熟悉,初学时掌握几个常用的就可以了,到后面再慢慢学习其它选项,免得因选项太多而打击了学习的信心。

一). 常用编译命令选项

假设源程序文件名为test.c。

1. 无选项编译链接

用法:#gcc test.c

作用:将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。

2. 选项 -o

用法:#gcc test.c -o test

作用:将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。

3. 选项 -E

用法:#gcc -E test.c -o test.i

作用:将test.c预处理输出test.i文件。

4. 选项 -S

用法:#gcc -S test.i

作用:将预处理输出文件test.i汇编成test.s文件。

5. 选项 -c

用法:#gcc -c test.s

作用:将汇编输出文件test.s编译输出test.o文件。

6. 无选项链接

用法:#gcc test.o -o test

作用:将编译输出文件test.o链接成最终可执行文件test。

7. 选项-O

用法:#gcc -O1 test.c -o test

作用:使用编译优化级别1编译程序。级别为1~3,级别越大优化效果越好,但编译时间越长。

二). 多源文件的编译方法

如果有多个源文件,基本上有两种编译方法:

[假设有两个源文件为test.c和testfun.c]

1. 多个文件一起编译

用法:#gcc testfun.c test.c -o test

作用:将testfun.c和test.c分别编译后链接成test可执行文件。

2. 分别编译各个源文件,之后对编译后输出的目标文件链接。

用法:

#gcc -c testfun.c //将testfun.c编译成testfun.o

#gcc -c test.c //将test.c编译成test.o

#gcc -o testfun.o test.o -o test //将testfun.o和test.o链接成test

以上两种方法相比较,第一中方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译

相关主题
相关文档
最新文档