【Linux】编辑器vim和编译器gcc/g++

vim是一个多模式编辑器,这里主要介绍三种:命令模式(command mode)、插⼊模式(Insert mode)和底⾏模式(last line mode)

1.初识vim

  • vim 文件名:文件存在就直接进入,文件不存在时,按q直接退出不会新建这个文件,按wq保存退出就会新建这个文件
  • vim 文件名 +n:进入文件后,光标直接定位到第n行

进入vim后默认的模式:命令模式

退出vim:

  1. shift+;(其实就是**:),然后按q**退出
  2. 输入两次大写的ZZ

在命令模式下,按i:换到插入模式

在插入模式下不能直接退出,可以先按键盘左上角的ESC键,退回到命令模式

然后输入两次大写的ZZ进行退出。

还有就是切换到底行模式退出,用shift+;(其实就是**:),然后按q**退出

如果里面写了内容,就输入wq,保存并退出。

设置行号:在底行模式下输入set nu

底行模式回退到命令模式: 按键盘左上角的ESC

但是我们不可以直接从底行模式切换到插入模式,从插入模式切换到底行模式也不可以,只能通过命令模式切换。

2.vim的3种模式

2.1 命令模式

命令模式就是快速编辑

  • gg:光标直接定位最开始
  • GG(shift+g):光标直接定位最结尾
  • n G(shift+g):光标定位到第n行
  • &(shift+4):光标定位到这一文本行的最右边
  • ^(shift+6):光标定位到这一文本行的最左边

如果只想要光标上下左右移动,有2种方法:

  1. 键盘的上下左右键

  2. h(左)、j(下)、k(上)、l(右)

  • w:光标以单词为单位移动,其他特殊符号不做多的考虑。
  • b:光标以单词为单位移动

上面的命令都可以带n。

  • yy:复制光标所在行的内容
  • p:光标所在位置的下一行进行粘贴粘贴

yy和p前面都可以带n,进行批量化复制粘贴。

  • dd:剪切 当前行,也可以用来删除
  • x:删除光标 所在位置的字符 ,光标后面的内容会往前移,光标也会移动
  • X(shift+x):删除光标所在位置的前面 的字符,光标不动
  • u撤销历史操作
  • ctrl + r:撤销刚刚的撤销,就是撤销u操作

u 和 ctrl + r互为对方的撤销,撤销操作一旦退出文件,就无法进行撤销操作了,但是如果只是保存,没有退出,就可以撤销。

  • r+新内容:替换光标所在字符为新内容
  • R(shift+r):批量化替换内容,左下角会出现REPLACE的标识,这个模式叫替换模式,退出替换模式按ESC

  • ~:光标所在位置字母的大小写切换

批量化增加操作:以注释为例

  • V(ctrl+v):从命令模式切换到视图模式

  • 然后通过h、j、k、l进行区域选择(如果按G,会直接选中到最后一行,别的指令区域选择也可以)
  • I(shift+i):直接从视图模式切换到插入模式
  • 然后在插入模式下直接输入//,注释一行
  • 最后按ESC,这个操作会批量化注释刚刚所选区域,而且会直接退回到命令模式下。

在不能撤销的情况下,批量化删除操作:以取消注释为例

  1. 先 V(ctrl+v)进入视图模式
  2. 对要删除的部分区域选择
  3. 按d,直接删除,并且会退回到命令模式下
  • #(shift+3):查找光标所在位置的单词,按n逆向查找

2.2 插入模式

进入插入模式:

  • i:直接进入,光标无变化
  • a:进入插入模式,光标向后移动一个
  • o:进入插入模式,并且会向下新增1行,光标也会移动到新增的这一行

这个模式就是编写内容的,没有啥特别的

2.3 底行模式

进入底行模式:冒号:(shift+;)

  • q:退出
  • w:保存
  • wq:保存并退出
  • wq!:强制保存并退出
  • set nu:设置行号
  • set nonu:取消行号
  • %s/被修改内容/指定内容/:批量化将所有被修改内容修改为指定内容
  • vs 文件名:再打开一个文件(可以分很多文件)
  • ctrl + w + w:光标在文件之间切换(命令模式)

3.gcc/g++

  • gcc xxx.c:编译,会生成a.out的可执行程序
  • gcc xxx.c**-o****yyy**:a.out是默认的名字,-o可指定可执行程序的文件名
  • ./a.out:运行

3.1 细看程序翻译过程

我们再分别对程序翻译的4个步骤展开学习,以下面这个程序为例。

cpp 复制代码
  1 #include <stdio.h>  
  2 #define  M 5                                                                                                                                                           
  3 #define  N 100
  4 int main()
  5 {
  6     //注释xxxxxxxxx
  7     for(int i = 0; i < M; i++)
  8     {
  9         printf("hello world!\n");
 10     }
 11 
 12 #ifdef N
 13     printf("N = %d\n", N);
 14 #else
 15     printf("No N");
 16 #endif
 17     return 0;
 18 }

程序翻译的4个步骤:

  1. 预处理(进⾏宏替换/去注释/条件编译/头⽂件展开等)
  2. 编译(⽣成汇编)
  3. 汇编(⽣成机器可识别代码)
  4. 连接(⽣成可执⾏⽂件或库⽂件)
  • gcc**-E****xxx.c -o xxx.i**:把预处理结果放到xxx.i文件中

-E这个选项的意思就是:开始进行程序翻译,在预处理做完时就停下来,不用再往后执行了。

我们用vim打开这个code.i文件,会发现代码变得特别多。

从这个文件就能看出预处理阶段会把头文件展开去掉注释宏替换条件编译

预处理的本质就是修改编辑我们的文本代码 ;code.i里的内容此时还是C语言

  • gcc -S xxx.i -o xxx.s :形成xxx.i的汇编语言放到xxx.s文件里。

-S选项意思就是:开始进行程序翻译,编译做完时就停下来,不用再往后执行了。

  • gcc -c xxx.s -o xxx.o :生成可重定位目标文件,在win系统中就是以**.obj**结尾的文件

-c选项意思就是:开始进行程序翻译,汇编完成就停下来,不用再往后执行了。

此时这个code.o文件就已经是二进制文件了,打卡这个 code.o文件看到的就是一堆乱码。

不带-o选项的话,默认生成的是同名.o文件**

  • gcc code.o -o code:生成可执行文件。

有多个.o文件时,我们可以把所有的.o文件一起进行gcc,让他们整体形成一个****可执行程序

以下面这段代码为例

cpp 复制代码
#include <stdio.h>                                                                                                                                                         
int main()
{
#ifdef M 
     printf("免费版\n");
#else
     printf("专业版\n");
#endif
}

此时没有宏定义,输出结果为"专业版"

  • gcc code.o -o code -DM :命令行式的宏定义

宏定义M默认取值为1,可以用 -DM=n 让M取值为n

3.2 初始动静态库

库就是一套方法或者数据集,为我们开发提供最基本的保证(基本接口、功能、加速我们二次开发)

  • ldd 可执行文件:查看可执行文件依赖的库

前面的代码我们所依赖的C语言的c标准库就是这个

用 ls -l 查看这个库,就会出现这个绿色的文件libc-2.31.so

C语言里的类似printf的实现就是在这个库里保存的,用的时候就要到这个库里执行然后再返回。

  • Linux下,动态库XXX****.so, 静态库XXX****.a
  • Windows下,动态库XXX.dll, 静态库XXX.lib
  • 动态链接(编译时发生的)就是,让我的程序,能找到库中的方法的地址
  • 静态链接:把我们程序中用到的库方法拷贝到我的程序相应的位置,
  • 静态库:只有在链接的时候有用,一旦形成可执行程序,静态库就不再需要

动静态库对比:

  1. 动态库形成的可执行程序体积一定很小
  2. 可执行程序对静态库的依赖度小,而动态库不能缺失
  3. 程序运行时,需要加载到内存,静态链接的,会在内存中出现大量的重复代码
  4. 动态链接比较节省内存和磁盘资源
  • file 可执行文件:查看可执行文件依赖的库的更详细的信息

可以看到gcc编译连接方法是默认是动态连接的,动态链接的前提是这个库存在

  • gcc code.c -o code -static :用静态链接

然后再用file 查看库详细信息时,就会发现连接方法变成了静态链接,而且内存也变大了。

而且静态链接时,用ldd查这个可执行文件依赖的库是查不到的。

我们也可以找c++的动态库和静态连接

相关推荐
先鱼鲨生3 分钟前
【Linux】System V - 责任链模式与消息队列
linux·责任链模式
钢铁男儿22 分钟前
使用 asyncio 与 aiohttp 编写异步 Unicode 字符查找服务器_2025-07-30
运维·服务器
所念皆为东辞42 分钟前
gitlab+jenkins的ci/cd部署
运维·ci/cd·gitlab·jenkins
AIZHINAN1 小时前
性能测试篇 :Jmeter监控服务器性能
运维·服务器·jmeter
快快网络-三七1 小时前
第二篇:Linux 文件系统操作:从基础到进阶
linux·运维·服务器·centos·快快网络
Doris_LMS1 小时前
Linux的访问权限(保姆级别)
linux·运维·服务器·面试
玖剹1 小时前
Linux文件系统:从内核到缓冲区的奥秘
linux·c语言·c++·笔记·ubuntu
是阿建吖!1 小时前
【Linux | 网络】传输层(UDP和TCP)
linux·网络·udp·tcp
dessler2 小时前
RabbitMQ-镜像队列(Mirrored Queues)
linux·运维·rabbitmq