• 【Linux】vim及gcc/g++的使用


    vim

    什么是vim

    通常使用的如VS2019等工具,具有以下特点

    • 可以写C、C++、python、网页等多种语言
    • 集编辑、调试、编译、链接等功能于一体

    类似的这种工具叫做IDE:集成开发环境

    相比之下,vim的功能就简单得多

    vim是一款纯编辑器:只负责写代码

    vim的常见几种模式

    vim test.c:用vim打开test.c

    vim:打开vim

    默认打开后 按键不能编辑文件内容,这是因为默认打开是命令模式

    vim常见有几种模式:

    • 命令模式:

      也叫普通模式或者正常模式

      1. 控制屏幕光标的移动
      2. 字符或字或行的删除
      3. 移动复制某区段
      4. 进入 其他两个模式的中间人
    • 编辑/插入模式:

      在此模式下可以进行编辑代码

    • 底行模式:

      1. 最基本的:文件保存和推出
      2. 进行文件替换
      3. 找字符串
      4. 列出行号

    查看所有的模式:vim命令来进入vim,然后底行模式输入 help vim-modes

    vim基本操作

    #模式的切换

    vim test.c就进入vim编辑画面,模式是[正常模式]

    需要切换到[插入模式]才可以输入文字

    • [命令模式] 切换至 [插入模式]

      • 按a
      • 按i (最常用:insert的缩写)
      • 按o
    • [插入模式] 切换至 [命令模式]

      • 按ESC
    • [命令模式] 切换至 [底行模式]

      • shift + ; 其实就是 :
    • [底行模式] 切换至 [命令模式]

      • 按ESC
    • vim的退出以及保存工作

      (以下的 : 表示在底行模式下)

      • :w (保存当前文件)
      • :q (退出文件)
      • :wq(保存并退出)
      • :q!(强制退出):通常因写入没保存就退出的时候会提示
      • :w!(强制保存):通常因权限不够而提示

    image-20220727112406362

    vim基本命令

    #复制粘贴

    yy :复制光标所在的行

    p:对复制的内容进行复制

    yy + p :可以复制一行,按一次p复制一行

    Linux

    yy + np:n为具体数字,按一次p复制 n行(如n为1000 就是复制1000行)

    例子:复制一行,粘贴3次

    Linux一次复制3行

    nyy + p:n为具体数字,复制从光标所在行开始向下的n行,然后粘贴一次

    例子:复制4行,粘贴1次

    Linux一次yy4行

    nyy+mp:n和m为具体数字,复制从光标所在行开始向下的n行,然后粘贴m次

    #撤销与反撤销

    在命令模式下

    u:撤销刚才的操作

    Ctrl + r:撤销刚才的撤销操作

    注意:一旦关闭文件,下一次进入文件就没有办法撤销了

    #光标定位

    • 上下定位

      shift + g:光标定位到文件的末尾

      gg:光标定位到文件的最开始

      n + shift + g:光标定位到第n行

    • 左右定位

      shift + 6(^):光标定位到当前行的最开始

      shift + 4($):光标定位到当前行的最结尾

      左右箭头按键 一行中左右移动(以字符为单位)

      w:以单词为单位向后移动

      b:以单词为单位向前移动

      nw:n为数字,向后移动n个单词

      nb:n为数字,向前移动n个单词

    • 其他定位

      h j k l :表示上下左右

      h:向左

      j:向下

      k:向上

      l:向右

    #文本删除和剪切

    dd:删除光标所在行

    ndd :删除从光标开始向下的n行

    dd+p:剪切所在行,按p粘贴

    ndd+p:剪切n行,然后粘贴

    #字母大小写转换

    shift + ~:转换成大写/小写(如果是大写就转换成小写,小写就转化成大写)

    Linux大小写转换

    #替换文本

    这里需要进入一种新的模式:替换模式

    • 直接替换文本

      shift + r:进入替换模式

      此时就会从光标处开始替换文本:输入什么替换什么

      (注意左下角已经进入了replace模式)

      Linux替换模式

    • 只替换一个字符

      r + 替换的字符(每一次都需要按一次r再按要替换的字符)

      Linux一次替换一个字符

    • 一次替换多个字符

      nr + 替换的字符(n为一个数字表示一次替换字符的个数)

      如图:一次替换四个w 和 x

      Linux一次替换多个字符gif

    #删除字符

    • 删除一个字符

      x:删除光标位置的字符(从左向右删)

      注意:作用在此行

      Linux删除字符

    • 删除多个字符

      nx:删除n个字符(从左向右)

      Linux一次删除多个字符

    注意:

    • shift + x(X) :删除当前光标的前一个字符(从右向左)
    • n shift + x:删除n个字符(从右向左)

    这两个与上面的x用法相同

    Linux从右向左删除

    底行模式的操作

    行号的设置与取消

    set nu:设置行号

    set nonu:取消行号

    多屏操作

    在vim中可以同时打开多个文件进行编辑

    vim test.c打开一个文件后

    : vs test1.c:底行命令打开另一个文件

    image-20220727140316898

    写入内容:(光标在哪就在哪里写)

    image-20220727140545070

    #光标在不同的屏幕之间切换

    Ctrl + ww :(Ctrl按住不懂,w快速按两下)

    可以在右边的文件中进行复制,然后粘贴到左边的文件中

    在vim中不退出执行命令操作

    :!cmd:直接在vim中执行Linux命令而不会退出vim(回车返回)

    如:! ls -al:在vim中执行ls -al命令

    image-20220727182610589

    好处:

    1. 可以直接在vim中执行编译指令,这样如果代码出错了,直接在vim中改即可
    2. 如果某个命令忘了,可以直接查看man手册

    vim的配置*

    在用户的家目录下cd ~,创建一个文件夹 .vimrc

    这里面包含了对vim的配置,比如显示行号、代码自动补齐、缩进字符数等

    这些配置可以在网上搜索到,然后Ctrl+cCtrl+v.vimrc中即可

    或者直接用yum命令安装人家写好的配置文件即可

    vimforcpp就是一个不错的选择

    安装:

    curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh

    卸载:

    bash ~/.VimForCpp/uninstall.sh

    sudo:添加用户到信任列表

    很多时候,我们需要用到root的权限

    但是,普通用户不在信任列表,就不可以添加执行sudo语句

    那么如何添加用户到信任列表?

    1. 切换成root用户

    2. vim打开 /etc/sudoers文件(只有root能打开)

      image-20220727193019159

    3. 然后找到107行左右

      image-20220727193054869

      如图 在后面添加 用户名 ALL=(ALL) ALL即可

      然后切换到底行模式,w!``q!(强制保存,强制退出)即可

    gcc && g++

    前言

    gcc是一个专门用来编译链接C语言的编译器

    g++则是编译链接C++,也可以编译链接C语言

    注意:gcc不能编译C++

    安装

    一般gcc都有,但是如果g++没有

    安装g++:sudo yum install -y gcc-c++

    查看版本:gcc -vg++ -v

    C/C++程序编译链接过程

    因为硬件的底层,是靠电路的正和负两种状态来实现的,对应就是0和1.所以计算机只认识二进制

    程序翻译的过程实际上就是把程序转化成二进制的过程

    1. 预处理 (.c -> .i)

      1. 去注释
      2. 宏替换
      3. 头文件展开
      4. 条件编译

      注意:预处理之后还是C语言

    2. 编译

      C/C++ -> 汇编语言 (.s)

    3. 汇编

      汇编语言 -> 可重定向二进制目标文件(.o / .obj)

    4. 链接

      多个.o / .obj -> 合并成一个可执行文件 (.exe)

    gcc的使用

    gcc默认一步到位生成可执行程序

    gcc test.c:直接生成可执行文件,默认名:a.out

    gcc test.c -o test:生成叫test的可执行文件

    也可以这样写:gcc -o test test.c

    注意:-o 后面紧跟 要形成的文件名

    gcc分步生成文件

    1. 预处理 (.c -> .i)

      gcc -E mytest.c :把预处理完成生成的内容 .i文件打印到屏幕

      gcc -E mytest.c -o mytest.i:把预处理生成的内容.i文件保存到 mytest.i 文件

      -o : 就是指定一个新的名字

      -E:从现在开始进行程序的翻译,如果预处理完成,就停下来

    2. 编译

      gcc -S mytest.i -o mytest.s:生成.s文件(汇编代码)

      -S:从现在开始进行程序的翻译,如果编译完成,就停下来

    3. 汇编

      gcc -c mytest.c -o mytest.o:生成.o文件(可重定向二进制目标文件),里面都是二进制

      -c:从现在开始进行程序的翻译,如果汇编完成就停下来

      可以用od mytest.o查看二进制文件

    4. 链接

      gcc mytest.o -o mytest:链接生成可执行文件mytest

    巧记

    过程:E S c -> 对应键盘的ESC建

    文件:i s o -> 镜像文件的后缀

    g++的过程和 gcc的程序翻译过程是一样的

    动静态库

    链接阶段,其实有一个重要的概念:函数库

    [[对库的认识]]

    写C/C++程序时,通常的做法是

    func.h中包含自己写的函数的声明

    func.cpp中包含函数的定义

    test.cpp中测试代码

    当test.cpp中包含了func.h文件后,也就是有了函数的声明。如果调用其中的函数,编译器就知道函数是存在的,会去别的地方找。

    静态库/动态库与func.cpp的作用类似,包含了.h文件后,就去库中找对应的函数的实现,从而构成可执行程序

    举个例子:

    我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而

    没有定义函数的实现,那么,是在哪里实“printf”函数的呢?

    最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用

    所以C程序是离不开C库文件的

    并且,Linux下很多命令也是直接利用C语言写的,比如ls命令

    通过ldd /usr/bin/ls就可以看到所依赖的库


    函数库一般分为静态库和动态库两种,对应就有静态链接和动态链接

    • 动态库:

      在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销(也就是在本文件中加载所调用函数的地址,去调用)

    • 静态库:

      直接把库文件对应函数的代码全部加入到可执行程序中,因此生成的文件比较大,但在运行时也就不再需要库文件了

    所以一般链接的过程有两种方式

    1. 动态链接 - 需要动态库
    2. 静态链接 - 需要静态库

    [[动态库和静态库在不同系统的后缀]]

    Linux下:.so(动态库),.a(静态库)

    Windows下:.dll(动态库) ,.lib(静态库)

    所以在安装VS2019等软件的时候,一并安装了C标准库的头文件和C标准库文件


    链接之后,生成了可执行文件,我们可以查看生成的可执行文件的信息:ldd mytestfile mytest

    其实最后生成的可执行文件 ,本身也是依赖于C语言的库的

    如图可见 可执行文件的信息:

    image-20220728152610753


    汇编之后生成的.o文件已经是二进制了,为什么不能执行?

    因为:生成的.o文件是自己写的代码翻译成了二进制的形式,但是你自己的代码中还有一些没有和库关联起来。调用的函数需要和库关联起来才能形成可执行文件。

    其实就是 调用函数,实际上需要调用函数的地址,而如果不关联,就找不到函数的地址(是未定义的),自然就报错


    动静态库的优缺点

    静态库:

    • 优点:不依赖库,直接把调用的函数的代码加载到可执行文件,运行比较快
    • 缺点:占用资源(节省内存,磁盘空间等),静态库会被添加到和它连接的每个程序中, 而且这些程序运行时, 都会被加载到内存中. 无形中又多消耗了更多的内存空间

    动态库:

    • 优点:因为只加载函数的地址,而不是函数的代码。生成的可执行文件小,节省空间
    • 缺点:由于运行时要去链接库会花费一定的时间,执行速度相对会慢一些

    总的来说静态库是牺牲了空间效率,换取了时间效率,共享库是牺牲了时间效率换取了空间效率,没有好与坏的区别,只看具体需要了。

    gcc/g++采用的链接方式

    gcc和g++默认形成的可执行程序是动态链接的

    事实上,动态链接形成可执行几乎是所有编译器的默认行为

    (可以通过 lddfile命令查看)

    image-20220728152610753

    如何静态链接呢?

    gcc tesc.c -o mytest_s -static: 生成采用静态链接的可执行文件 mytest_s(自定义命名即可,这里用s表示静态)

    -static:表示用静态链接的方法形成可执行程序

    image-20220728173035784

    可以看到采用静态链接生成的可执行文件的大小 远大于 采用动态链接生成的可执行程序的大小(将近100倍)

    注意:

    动态链接必须使用.so动态库文件

    静态链接必须使用.a静态库文件

    而云服务器一般只有动态库没有静态库,如果使用静态库就会导致链接失败,需要安装

    C静态库的安装:sudo yum install -y glibc-static

    C++静态库的安装:sudo yum install -y libstdc++-static

  • 相关阅读:
    js 模糊定位标签元素
    拥抱新技术?你需要考虑的方面
    【Python中图像相似性度量方法全面总结】
    视频监控智能分析技术
    基于 Jenkins 搭建一套 CI/CD 系统
    jira操作流程
    python-GUI键盘小工具
    画法几何及工程制图考试卷A卷
    ELK Stack日志采集架构详解
    linux系统延迟任务
  • 原文地址:https://blog.csdn.net/K_04_10/article/details/126051443