目录
[一. 软件包管理器](#一. 软件包管理器)
[1.1 什么是软件包](#1.1 什么是软件包)
[1.2 Linux软件生态](#1.2 Linux软件生态)
[1.3 如何使用yum/apt](#1.3 如何使用yum/apt)
[1.4 安装源](#1.4 安装源)
[二. 编辑器Vim](#二. 编辑器Vim)
[2.1 Linux编辑器-vim](#2.1 Linux编辑器-vim)
[2.2 vim的基本概念](#2.2 vim的基本概念)
[2.3 vim的基本操作](#2.3 vim的基本操作)
[2.4 vim命令模式命令集](#2.4 vim命令模式命令集)
[2)从插入模式切换为命令模式 :](#2)从插入模式切换为命令模式 :)
[3)移动光标 :](#3)移动光标 :)
[7)更改 :](#7)更改 :)
[2.5 vim底行模式命令集](#2.5 vim底行模式命令集)
[2.6 vim操作总结](#2.6 vim操作总结)
[2.7 三个实用技巧](#2.7 三个实用技巧)
[1. 批量化注释和去注释](#1. 批量化注释和去注释)
[3. ! + 单个字符](#3. ! + 单个字符)
[2.8 vim中常遇到的几个问题](#2.8 vim中常遇到的几个问题)
[1. vim异常退出的问题(代码丢失的问题)](#1. vim异常退出的问题(代码丢失的问题))
[2.9 简单的vim配置](#2.9 简单的vim配置)
1.配置项属于单个用户,配置也只配置单个用户(最好是各配各的)
[三. 编译器gcc/g++](#三. 编译器gcc/g++)
[3.1 背景知识](#3.1 背景知识)
[3.2 gcc选项](#3.2 gcc选项)
[3.2.1 预处理:把C语言变干净(去掉宏、注释等)【对代码作二次编辑(增、删、改)】](#3.2.1 预处理:把C语言变干净(去掉宏、注释等)【对代码作二次编辑(增、删、改)】)
[3.2.2 编译:C语言 -> 汇编语言](#3.2.2 编译:C语言 -> 汇编语言)
[3.2.3 汇编:汇编语言 -> 目标文件(.o/.obj)(全称为:可重定位二进制目标文件)](#3.2.3 汇编:汇编语言 -> 目标文件(.o/.obj)(全称为:可重定位二进制目标文件))
[3.2.4 链接:](#3.2.4 链接:)
[3.2.5 深入探讨条件编译](#3.2.5 深入探讨条件编译)
[1. 看条件编译(是在预处理阶段完成的)](#1. 看条件编译(是在预处理阶段完成的))
[2. 谈用场景](#2. 谈用场景)
[3.2.6 为什么要有这个过程(历史演变)](#3.2.6 为什么要有这个过程(历史演变))
[3.2.7 一般程序的构建过程 --- .o 文件](#3.2.7 一般程序的构建过程 --- .o 文件)
[3.3 动态链接和静态链接](#3.3 动态链接和静态链接)
[3.4 初步了解动态库和静态库](#3.4 初步了解动态库和静态库)
[3.5 动/静态库,动/静态链接补充](#3.5 动/静态库,动/静态链接补充)
[3.6 gcc其他常用选项](#3.6 gcc其他常用选项)
引言
在Linux环境下进行开发,不仅意味着编写代码,更意味着要熟练驾驭一套强大的工具链。与Windows下集成的IDE不同,Linux的哲学是将每个功能的工具做到极致。
一. 软件包管理器
1.1 什么是软件包
- 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序.
- 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上 的安装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装.
- 软件包和软件包管理器, 就好比 "App" 和 "应用商店" 这样的关系.
- yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器. 主要应用在Fedora, RedHat, Centos等发行版上.
- Ubuntu:主要使用apt(Advanced Package Tool)作为其包管理器。apt同样提供了自动解决依赖关系、下载和安装软件包的功能。
在Linux系统中安装,查找,卸载软件的问题!
在Linux中有3种安装软件的方式:
**1.源代码安装:**开发者提供源代码,用户需自行编译安装,但存在编译困难和依赖问题,不推荐。
比如开源的东西,有源代码;我们可以自己编译发布,安装到自己的系统中
一般会有编译脚本和安装脚本,直接用命令跑一下就行
(现阶段不好,因为有的在编译时在我们自己的平台下不一定编的过;因为它可能用到了别人的库,可能需要我们安装配套的更多的库)
2. rpm包(类似Windows中的安装包)
用对应的指令解压并安装到系统(存在问题,比如安装一个A软件,它可能依赖B软件,C软件等)
是预编译好的软件包,使用RPM命令安装,但存在软件依赖关系问题,安装过程可能较麻烦。
3.yum/apt:包管理器(推荐)
**类似于Linux下的应用商店。是一个客户端程序,**能自动查找、安装、卸载软件,并解决软件依赖问题
-
包管理器的本质:类似于Linux下的应用商店,是客户端程序,用于在Linux系统中搜索、安装、卸载软件,用户通过其直接操作即可完成软件管理。
-
包管理器的生态系统:涉及软件开发者提供软件、社区或企业提供云服务器存放编译好的软件包、客户端通过配置文件指向软件包服务器地址进行下载安装,国内还有镜像源解决国外服务器访问慢或无法访问的问题。
**问:**你的Linux机器,怎么知道软件包在全球的那台机器上??
**配置文件:**保存目标服务器的下载链接!!!
1.2 Linux软件生态
Linux下载软件的过程(Ubuntu、Centos、other)

操作系统好坏的评估------生态问题
除操作系统本身稳定、安全、高效外,更重要的是其生态完善,包括社区活跃、论坛丰富、官方文档完善、软件体系丰富、维护更新及时及有针对性的用户群体。
操作系统生态完善的原因:操作系统诞生后最重要的是有人使用,而完善的生态能吸引更多用户,用户越多越能促进生态发展,形成良性循环,如华为鸿蒙系统通过兼容安卓APP和庞大用户量逐步建立自身生态。

为什么会有人免费特定社区提供软件,还发布?还提供云服务器让你下载?
-
软件来源与编译:开发者自愿为Linux开发应用软件,将源代码在各Linux平台编译成软件包,上传到包管理服务器。
-
服务器资源提供:由于Linux操作系统有大量企业用户和开发者,云服务厂商会为社区免费提供云服务器存放软件包,开源模式能吸引免费的人力和硬件资源。
-
国内镜像源:国外Linux软件包服务器在国内访问可能受限,国内云服务厂商、高校或机构会将国外软件包镜像到国内服务器,并提供国内配置文件,方便国内用户下载安装软件。

包管理器解决软件包依赖的问题
- 自动解决软件依赖:安装目标软件时,包管理器会自动解析其依赖的其他软件,并将所有依赖软件一同下载安装,避免用户手动处理复杂的依赖关系,这是推荐使用包管理器的重要原因。

国内镜像源
国外Linux软件包服务器在国内访问可能受限,国内云服务厂商、高校或机构会将国外软件包镜像到国内服务器,并提供国内配置文件,方便国内用户下载安装软件。

以下是一些国内Linux软件安装源的官方链接:
1. 阿里云官方镜像站
- 官方链接:https://developer.aliyun.com/mirror/
- 阿里云提供了丰富的Linux发行版镜像,包括CentOS、Ubuntu、Debian等,用户可 以通过该镜像站快速下载和更新软件包。
2. 清华大学开源软件镜像站
- 官方链接:https://mirrors.tuna.tsinghua.edu.cn/
- 清华大学镜像站提供了多种Linux发行版的镜像,以及Python、Perl、Ruby等编程语 言的扩展包。该镜像站还提供了丰富的文档和教程,帮助用户更好地使用这些软件包。
3. 中国科学技术大学开源镜像站
- 官方链接:http://mirrors.ustc.edu.cn/
- 中科大镜像站提供了多种Linux发行版的镜像,以及常用的编程语言和开发工具。用户可以通过该镜像站方便地获取所需的软件包和工具。
4. 北京交通大学自由与开源软件镜像站
- 官方链接:https://mirror.bjtu.edu.cn/
- 北交大镜像站提供了多种Linux发行版的镜像,以及相关的软件仓库和工具。该镜像站 还提供了详细的文档和指南,帮助用户配置和使用这些软件源。
5. 中国科学院软件研究所镜像站(ISCAS)
- 官方链接:http://mirror.iscas.ac.cn/
- ISCAS镜像站提供了多种Linux发行版、编程语言和开发工具的镜像。用户可以通过该 镜像站快速获取所需的软件包和更新。
6. 上海交通大学开源镜像站
- 官方链接:https://ftp.sjtu.edu.cn/
- 上海交大镜像站提供了丰富的Linux软件资源,包括多种发行版的镜像和软件仓库。用 户可以通过该镜像站方便地下载和安装所需的软件包。
7. 网易开源镜像站
- 官方链接:http://mirrors.163.com/
- 网易镜像站提供了多种Linux发行版的镜像,以及相关的软件仓库和工具。该镜像站还 提供了便捷的搜索功能,帮助用户快速找到所需的软件包。
此外,还有一些其他的国内镜像源,如搜狐开源镜像站等,但可能由于时间变化或政策调 整,部分镜像站的链接或状态可能有所变动。因此,建议用户在使用前访问官方网站或咨询 相关社区以获取最新的信息和帮助。

1.3 如何使用yum/apt
CentOS:(yum)
查询:
罗列出所有软件包:yum list
搜索:yum list | grep 要安装的包名
安装/卸载:
root用户可以直接装,普通用户需要sudo提权
安装:sudo yum install 软件名 sudo yum install -y 软件名 (这样直接安装,不会询问)
卸载:sudo yum remove 软件名 sudo yum remove -y 软件名 (这样直接卸载,不会询问)
Ubuntu:(apt)
查询:
apt search 包名
apt show 包名:查看包更详细的信息
安装和卸载同上,只是yum改为apt
问:我怎么知道要安装的软件包包名名是什么?
和应用场景有关,根据需要安装
问:Linux中软件安装,如果有多个用户,安装几次?? 1次
因为是超级用户安装,是安装到了usr/bin路径下,所有用户都能用
注意:yum/apt 安装软件要一个一个的安装
补充命令:
**查看系统:**cat /etc/os_release
**ls -ld:**查看这个目录本身,不查看里面的内容
1.4 安装源
**问:**yum/apt怎么知道安装包在哪里?
通过国内镜像源对应的配置文件,里面会保存链接,yum/apt会在里面找
**centos:**ls /etc/yum.repos.d/ epel表示扩展软件源
**Ubuntu:**ls /etc/apt/sources.list/ (稳定软件源)ls /etc/apt/sources.list.d/ (扩展软件源)
扩展源现默认是不带的,如果需要,则需要安装:
bash
# Cetnos 安装源路径:
$ ll /etc/yum.repos.d/
total 16
-rw-r--r-- 1 root root 676 Oct 8 20:47 CentOS-Base.repo # 标准源
-rw-r--r-- 1 root root 230 Aug 27 10:31 epel.repo # 扩展源
# 安装扩展源
# $ sudo yum install -y epel-release
# Ubuntu 安装源路径:
$ cat /etc/apt/sources.list # 标准源
$ ll /etc/apt/sources.list.d/ # 扩展源
# ubuntu 安装扩展源,就结合未来具体场景
软件源更新的问题:(软件源就是包管理器yum/apt对应的配置文件)
(**注:**云服务器的的使用者是不用做的,因为厂商已经把配置文件改为了从国内镜像源安装软件;
虚拟机:OS镜像打包配置文件,软件源指向的是国外的,这时需要进行软件源的更新)
方法:用一个新的配置文件替换系统的!
软件源如何更新:(下面以CentOS为例)
1.首先要找到对应的软件源,然后下载到本地:
centos:wget -O [/etc/yum.repos.d/]CentOS-Base.repo http://mirrors.sliyun.com/repo/Centos-7.repo
上面这个命令的意思是:把远端对应的文件通过wget命令从网络中下载下来,然后在我的本地把名字从Centos-7.repo改为CentOS-Base.repo
wget是从真实的网址处获取内容
2. 更新(替换)国内配置文件(在浏览器搜索指定操作系统的镜像源,如centos 7等)
首先找到自己的yum源在哪里:ls /etc/yum.repos.d/,然后cd进入
ll会看到自带的yum源:CentOS-Base.repo,要用新的yum源将这个老的yum源覆盖掉
为了防止出错,我们可以先将老的yum源备份,将它的名字更改:mv CentOS-Base.repo CentOS-Base.backup1,这就相当于将它备份了;然后将下载的yum源从下载的路径拷贝到这个路径下:sudo cp /home/whb/code/118/CentOS-Base.repo .
3. 清理安装源缓存:sudo yum clean all
4. 使用新的配置,重新形成缓存:sudo yum makecache
二. 编辑器Vim
yum/apt/vim:工具、指令、程序

2.1 Linux编辑器-vim
vi/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令(类似C与C++的关系),而且还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行,也可以运行于x window、 mac os、 windows。
vim是什么?
文本编辑器 --- 只能用来写代码或者更改配置文件
vs是集编写,编译,调试,运行可以编译各种语言的集成开发环境,而Linux黑屏下是没有这种集成开发环境,如果是图形化界面,有的可以装一些集成开发环境
vim的地位? Linux最主流,20-30%
把它当成一个快速的文本修改的工具!其他的工具比较慢,如:vscode
vim是增强版的vi(类似C与C++之间的关系),vim比vi更好用,且功能更强大
2.2 vim的基本概念
vim的最主要的三种模式(其实有好多模式),分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下:
正常/普通/命令模式(Normal mode):
控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode
插入模式(Insert mode):
只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面用 的最频繁的编辑模式。
底行模式(last line mode):
文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下,*shift+:* 即可进入该模式。要查看你的所有模式:打开 vim,底行模式直接输入 :help vim-modes
这里一共有12种模式:six BASIC modes和six ADDITIONAL modes

下面再总结拓展一下
vim 是一款具有多种模式的编辑器!!【打开vim时默认为命令模式】
1.命令模式(最核心):输入的内容都会被当做命令(可以脱离鼠标操作)
提高效率(类似Windows中的快捷键,如:ctrl c,ctrl v)
用键盘输入i(insert)(光标不移动),a(光标右移),o(光标下移),即可从命令模式转换为插入模式;esc:退出插入模式,进入命令模式
2.插入模式:
正常的编辑模式,可以直接写代码
3.底行模式:
命令模式才能进入底行模式:"shift + ;" == " : "
Esc:底行模式回退到命令模式
4.替换模式:
R == shift + r:让vim进入替换模式,当前光标之后的内容当做没有,直接覆盖
Esc:回退到命令模式
5.视图模式(进行区域选择时,区域选择可视化):
ctrl + v进入视图模式,进行区域选择(然后可以shiftv + i进入插入模式,进行区域插入/删除的操作)【对具有相同特征的代码,进行批量化编辑!】
Esc:回退到命令模式
(注:插入模式和底行模式和替换模式原则上不能互相切换,都要回退到命令模式,所以说命令模式是核心模式)
2.3 vim的基本操作
进入vim,在系统提示符号输入vim及文件名称后,就进入vim全屏幕编辑画面:
- $ vim test.c
- 不过有一点要特别注意,就是你进入vim之后,是处于[正常模式],你要切换到[插入模式]才能够 输入文字。
[正常模式]切换至[插入模式]:
- 输入a
- 输入i
- 输入o
[插入模式]切换至[正常模式]:
- 目前处于[插入模式],就只能一直输入文字,如果发现输错了字,想用光标键往回移动,将该字删除,可以先按一下「ESC」键转到[正常模式]再删除文字。当然,也可以直接删除。
[正常模式]切换至[末行模式]:
- 「shift + ;」, 其实就是输入「:」
退出vim及保存文件,在[正常模式]下,按一下「:」冒号键进入「Last line mode」,例如:
- : w (保存当前文件)
- : wq (输入「wq」,存盘并退出vim)
- : q! (输入q!,不存盘强制退出vim)
2.4 vim命令模式命令集
1)进入插入模式:
- 按「i」切换进入插入模式「insert mode」,按"i"进入插入模式后是从光标当前位置开始输入 文件;
- 按「a」进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字;
- 按「o」进入插入模式后,是插入新的一行,从行首开始输入文字。
2)从插入模式切换为命令模式 :
- 按「ESC」键。
3)移动光标 :
- vim可以直接用键盘上的光标来上下左右移动,但正规的vim是用小写英文字母「h」、「j」、 「k」、「l」,分别控制光标左、下、上、右移一格
- 按「G」:移动到文章的最后
- 按「 $ 」:移动到光标所在行的"行尾" • 按「^」:移动到光标所在行的"行首" •
- 按「w」:光标跳到下个字的开头
- 按「e」:光标跳到下个字的字尾
- 按「b」:光标回到上个字的开头
- 按「#l」:光标移到该行的第#个位置,如:5l,56l
- 按[gg]:进入到文本开始
- 按[shift+g]:进入文本末端
- 按「ctrl」+「b」:屏幕往"后"移动一页
- 按「ctrl」+「f」:屏幕往"前"移动一页 • 按「ctrl」+「u」:屏幕往"后"移动半页
- 按「ctrl」+「d」:屏幕往"前"移动半页
4)删除文字:
- 「x」:每按一次,删除光标所在位置的一个字符
- 「#x」:例如,「6x」表示删除光标所在位置的"后面(包含自己在内)"6个字符 •
- 「X」:大写的X,每按一次,删除光标所在位置的"前面"一个字符
- 「#X」:例如,「20X」表示删除光标所在位置的"前面"20个字符
- 「dd」:删除光标所在行 • 「#dd」:从光标所在行开始删除#行
4)复制:
- 「yw」:将光标所在之处到字尾的字符复制到缓冲区中。
- 「#yw」:复制#个字到缓冲区
- 「yy」:复制光标所在行到缓冲区。
- 「#yy」:例如,「6yy」表示拷贝从光标所在的该行"往下数"6行文字。
- 「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与"y"有关的复制命令都必须 与"p"配合才能完成复制与粘贴功能。
5)替换:
- 「r」:替换光标所在处的字符。
- 「R」:替换光标所到之处的字符,直到按下「ESC」键为止。
6)撤销上一次操作:
- 「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次"u"可以执行 多次回复。
- 「ctrl + r」: 撤销的恢复
7)更改 :
- 「cw」:更改光标所在处的字到字尾处
- 「c#w」:例如,「c3w」表示更改3个字 • 跳至指定的行 • 「ctrl」+「g」列出光标所在行的行号。
- 「#G」:例如,「15G」,表示移动光标至文章的第15行首。
8)跳至指定的行:
- 「ctrl」+「g」列出光标所在行的行号。
- 「#G」:例如,「15G」,表示移动光标至文章的第15行首。
总结并拓展:
命令模式:( 更多的编辑命令**)**
1.光标移动:
1)行:
gg:光标定位到开头
G == shift + g:末尾 行号 + shift + g == G:跳转到指定行
2)列:(不要用小数字键盘)
^ == shift + 6 :定位到行首
$ == shift + 4:顶位到行尾
**上下左右移动:**上下左右键也可以,但是这个下面这几个比较好:
- h:左
- j:下(jump)
- k:上(King)
- l:右
数字 + h,j,k,l,按指定数字上下左右跳转
**w:**以单词为单位向后移动(如果当前行没有单词了,会向下移动)(word)
**b:**以单词为单位向前移动(如果当前行没有单词了,会向上移动)(back)
数字 + w/b:按指定数字数前后移动
2.编辑操作:(如果不多说,编辑命令前面一般都可以加数字)
**yy:**复制当前行
n + yy: 复制n行
**p(post):**粘贴(多次p可多次粘贴)(从光标所在行往后粘贴)
数字(n) + p: 粘贴n次
**u:**撤销刚刚的操作
**ctrl + r:**恢复刚刚的撤销
【只要不退出vim,随时可以后悔,但是一旦退出vim,保存内容,就无法再u或ctrl + r】
dd:剪切/删除行(不调用p即可 )
n + dd:多行剪切
x:从光标位置向后删除,一次删一个
n + x:多个删除
输入 i 进入插入模式,然后就可以正常删除了
**ctrl + v:**hjkl 区域选择,选择之后输入 d 删除
~ == shift + `:大小写切换
r:对光标所在字符进行替换 n + r:批量化替换
R == shift + r:让vim进入替换模式,当前光标之后的内容当做没有,直接覆盖(在不删除的情况下,直接覆盖式的进行输入)
**ZZ == shift + zz:**保存并退出(不用进入底行模式)
2.5 vim底行模式命令集
在使用末行模式之前,请记住先按「ESC」键确定您已经处于正常模式,再按「:」冒号即可进入末行模式。
1)列出行号:
- 「set nu」: 输入「set nu」后,会在文件中的每一行前面列出行号。
2)跳到文件中的某一行:
- 「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字 15,再回车,就会跳到文章的第15行。
3)查找字符:
- 「/关键字」: 先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以 一直按「n」会往后寻找到您要的关键字为止。
- 「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可 以一直按「n」会往前寻找到您要的关键字为止。
- 问题:/ 和 ?查找有和区别?操作实验一下
4)保存文件:
- 「w」: 在冒号输入字母「w」就可以将文件保存起来
5)离开vim:
- 「q」:按「q」就是退出,如果无法离开vim,可以在「q」后跟一个「!」强制离开vim。
- 「wq」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。
总结并拓展:
底行模式:(也是命令的一种)
:== shift + ;-> 进入底行
w:保存写入的内容 w!:强制保存
q:退出 q!:强制退出(不要轻易使用)
!:强制
如果进入文件后,没有对文件做修改或已经做了修改,如果不w保存文件,无法直接退出。
如果要强制退出,那么可以用 q! 强制退出,但这时修改的内容无法被保存
wq:保存并退出
wq!:强制保存并退出
set nu:调出行号 set nonu:去掉行号
使用vim编辑后想要查看结果还要退出vim,然后编译,然后运行,比较麻烦,过程如下:
gcc code.c ./a.out
所以vim支持不退出,可以直接在底行模式进行操作:(注意要是纯英文)
! gcc code.c ! ./a.out
在底行,用 ! 基本上可以执行在命令行的任意命令,如:! ls、! ls -a -l 等
! man 函数名:常看这个函数的man手册(比较常用)
! command:bash中执行的命令,都可以在底行直接执行(不用退出vim)
vs 文件名:分屏对比文件
**光标移动:**ctr + ww (让光标在多屏切换)
光标在那个文件对应的区域,编辑的就是哪个文件;退出操作和单屏时一样的
在底行当中,如果打开一个不存在的文件,没有编辑直接退出,该文件不会被创建
但是,如果w保存了,vim会自动为我们新建这个文件
**/要搜索的关键字:**高亮匹配项目,点击 n 依次查看匹配项
%s / target / src / g:用新内容 替换 指定的项目
s便是替换,target是被替换的项目,src是新内容,g表示全局
2.6 vim操作总结
三种主要模式:
- 命令模式
- 插入模式
- 底行模式
vim操作:
- 打开,关闭,查看,查询,插入,删除,替换,撤销,复制等等操作。

2.7 三个实用技巧
1. 批量化注释和去注释
加注释:
在命令模式下ctrl + v进入视图模式,hjkl进行区域选择,输入shift + i == I 进入插入模式,加上// ,最后Esc。(可以结合前面的光标移动,快速进行区域选择)
去注释:
ctrl + v == 视图模式,hjkl进行区域选择,d即可删除注释区域
2.指定行号进入vim
vim启动时,光标默认在退出时的位置
vim 文件名 +行号:进入vim时光标会在指定行位置(编译报错时,进入vim查看这样很方便)
3. ! + 单个字符
**! + 单个字符:**匹配最近一次以该字符开头的命令
2.8 vim中常遇到的几个问题
1. vim异常退出的问题(代码丢失的问题)
在vim中编辑后,没有保存,因为网络或其他原因异常退出怎么办?
其实vim有一个隐藏文件,会保存之前的信息(Windows也有)【.code.c.swp】
在vim打开期间,就会自动形成【.code.c.swp】这个隐藏文件,当我们在vim里面写的时候,就已经自动把信息保存到了【.code.c.swp】这个文件当中,如果正常退出,这个文件就自动被删除了,如果异常退出,这个文件就会被保存,在进入可以被恢复。
(注:恢复之后,就可以把(.code.c.swp)这个文件删除了,不然每次打开都会询问你是否恢复)
2、给用户进行赋权,把用户添加到白名单


我们可以看到root也是没有w(写权限)的,但是我们可以 w! 强制写入,这里其实是为了告诉root用户,这比较重要,不要轻易修改

进入文件之后,直接yy复制,然后p粘贴,将前面的用户名改为要更改的用户名。
最后进入底行模式,输入 w! / wq! 强制保存并退出
2.9 简单的vim配置
vim需要经过配置,才能更好的使用

把vim配置项,写入到当前用户的/home/lxd/.vimrc,它就自动生效了
1.配置项属于单个用户,配置也只配置单个用户(最好是各配各的)
vim test.c,vim启动时,首先会在对应的家目录下找对应的配置文件,然后那这个配置文件加载到vim配置项里面,让我们可以直接配置
2.vim的配置项都有哪些??我怎么知道
可以通过AI大模型搜索查询。
如果想要进行比较高端的配置,比如自动补全等,需要插配置件
首先要在家目录下创建 .vim 文件,然后在 .vimrc 把要有的插件全部配置进去
3.一键化配置vim的方案
Gitee搜开源VimForCpp,然后下滑,找到对应的链接直接复制到命令行即可
Ubuntu可以搜vimplus,但是功能没有上面的强大
如果想要自己配置插件,可以接着看看,如果不想自己配置,直接用上面开源的配置型就够用了
配置文件的位置:
- 在目录 /etc/ 下面,有个名为vimrc的文件,这是系统中公共的vim配置文件,对所有用户都有效。
- 而在每个用户的主目录下,都可以自己建立私有的配置文件,命名为:".vimrc"。例如,/root 目录下,通常已经存在一个.vimrc文件,如果不存在,则创建之。
- 切换用户成为自己执行 su ,进入自己的主工作目录,执行 cd ~
- 打开自己目录下的.vimrc文件,执行 vim .vimrc
常用配置选项,用来测试:
设置语法高亮: syntax on
**显示行号:**set nu
设置缩进的空格数为4: set shiftwidth=4
使用插件:
要配置好看的vim,原生的配置可能功能不全,可以选择安装插件来完善配置,保证用户是你要配置的用户,接下来:
- 安装TagList插件,下载taglist_xx.zip ,解压完成,将解压出来的doc的内容放到~/.vim/doc, 将解 压出来的plugin下的内容拷贝到~/.vim/plugin
- 在~/.vimrc 中添加: let Tlist_Show_One_File=1 let Tlist_Exit_OnlyWindow=1 let Tlist_Use_Right_Window=1
- 安装文件浏览器和窗口管理器插件: WinManager
- 下载winmanager.zip,2.X版本以上的
- 解压winmanager.zip,将解压出来的doc的内容放到~/.vim/doc, 将解压出来的plugin下的内容 拷贝到~/.vim/plugin
- 在~/.vimrc 中添加 let g:winManagerWindowLayout='FileExplorer|TagList nmap wm :WMToggle
- 然后重启vim,打开~/XXX.c或~/XXX.cpp, 在normal状态下输入"wm", 你将看到上图的效果。更具 体移步:点我, 其他手册,请执行 vimtutor 命令。
三. 编译器gcc/g++
3.1 背景知识
编译器:gcc:编译C语言;g++:编译C/C++
编译的过程 ------ 把源文件(.c / .cpp)翻译成为可执行二进制文件
- 预处理(进行宏替换/去注释/条件编译/头文件展开等)
- 编译(生成汇编)
- 汇编(生成机器可识别代码)
- 链接(生成可执行文件或库文件)
3.2 gcc选项
格式 gcc [选项] 要编译的文件 [选项] [目标文件]
直接编译:(看不到翻译过程)
gcc coed.c,就会生成可执行程序,名称为a.out
如果要指定目标新文件的名称加一个 -o:gcc code.c -o code.exe 或 gcc -o code.exe code.c
-o 可以放前面也可以刚后面,但是后面一定要紧跟新文件名
通过不同的gcc选项看到翻译的过程 【C->C->汇编->.o->bin】
3.2.1 预处理:把C语言变干净(去掉宏、注释等)【对代码作二次编辑(增、删、改)】
问:预处理后还是C语言吗? 是。
预处理只是对文件内容进行文本处理(如:头文件展开就是文本拷贝,宏替换就是文本替换,去注释就是文本删除,条件编译就是文本裁剪等)
- >头文件展开【默认头文件时安装在了系统的(/usr/include/stdio.h)路径下的】
- 就是把头文件相关内容拷贝到源文件!头源合并的过程!
- (编译器只有在预处理的时候需要头文件)
- >去注释
- >宏替换
- >条件编译
gcc -E code.c:只做预处理,语处理完之后,会将内容全部打印在显示器上,看起来不方便
gcc -E code.c -o code.i:把预处理之后的结果保存在code.i文件中;
-o选项: 指明新文件的名称
**-E选项:**进行code.c的翻译工作,预处理做完就停下来;预处理结果写到code.i文件中
**问:**怎么证明它停下来了?它没有形成可执行程序,而是形成了code.i文件
3.2.2 编译:C语言 -> 汇编语言
gcc -S code.i -o code.s
**-S选项:**开始进行程序编译,做完编译就停下来
3.2.3 汇编:汇编语言 -> 目标文件(.o/.obj)(全称为:可重定位二进制目标文件)
gcc -c code.s -o code.o
**-c选项:**开始进行程序的翻译,汇编工作做完,就停下来
虽然已经是二进制文件,但是仍然无法执行
3.2.4 链接:
printf(); 要使用它,需要再链接的时候,把我们的.o和C标准库连接形成可执行
gcc code.o -o code.exe
3.2.5 深入探讨条件编译
a. 条件编译 --- 应用场景 -- 软件生态【实现软件多功能多种类管理的功能】
**1.**看条件编译(是在预处理阶段完成的)


因为没有定义V1宏,所以编译时相当于把Version1()函数调用的过程这部分代码给裁掉了,只保留了Version2
条件编译可做对我们的代码进行裁剪!在预处理阶段
理解:#define等这些是预处理符,是给编译器看的
问:为什么要有条件编译?可以用来进行多商业化软件,进行不同种类的管理。
安装软件时有:免费版/社区版 收费版/专业版
问:如果我是软件的编写者,是维护一份代码还是两份代码? 只维护一份
因为免费版和专业版有部分功能是重叠的,如果是两份代码,出了bug,两个都要修复,并且修好之后,两个都要测试,成本比较高;采用条件编译的方式,我们就可以只维护付费版这一个版本即可。

把FREE插入到源代码的头部(-D选项)

**2.**谈用场景
- 上面的商业化软件
- Linux内核开发用条件编译进行功能裁剪,这样就能适配各种不同的场景(可以在电脑上跑,可以再手机上跑等等)
3.2.6 为什么要有这个过程(历史演变)
编译过程【C->C->汇编->.o->bin】
**问:**为什么是上面那个过程?编译器的历史,语言的历史
编译性的语言:主要就是C/C++
解释性的语言比较多:比如python/php/java(算是半解释性语言)等等
所有语言最后都必须变为二进制,因为CPU只认识二进制
汇编语言 VS 汇编编译器 VS 汇编语言写的汇编编译器
先设计出了汇编语言的规则,然后用汇编语言之前的二进制纸带编程来设计出第一个 支持汇编语言的编译器,然后在这个编译器上写汇编代码,然后就可以用汇编代码来制作编译器,即用汇编语言写的汇编编译器 。综上,就有了汇编代码的编译器是汇编语言写的这种情况。
编译器和对应语言的关系 --- 自举
先有的语言,后有的编译器
3.2.7 一般程序的构建过程 --- .o 文件
gcc -c code.c 后面不加 -o指定新文件名称,默认就会生成同名的.o文件code.o

建议先把对应的文件编译为.o文件,然后再把.o文件链接。 为什么?
**提高编译效率。**如果文件比较多的话,如果有一个文件修改了,那么我们只需将这个修改的文件重新编译为.o文件,然后再将它与其他的所有文件链接即可。如果是直接生成可执行程序,那么修改之后,其他的文件都要在编译一次然后再链接,效率比较低。
3.3 动态链接和静态链接
在我们的实际开发中,不可能将所有代码放在一个源文件中,所以会出现多个源文件,而且多个源文件之间不是独立的,而会存在多种依赖关系,如一个源文件可能要调用另一个源文件中定义的函数, 但是每个源文件都是独立编译的,即每个*.c文件会形成一个*.o文件,为了满足前面说的依赖关系,则需要将这些源文件产生的目标文件进行链接,从而形成一个可以执行的程序。这个链接的过程就是静态链接 。静态链接的缺点很明显:
- 浪费空间:因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对 同一个目标文件都有依赖,如多个程序中都调用了printf()函数,则这多个程序中都含有 printf.o,所以同一个目标文件都在内存存在多个副本;
- 更新比较困难:因为每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程 序。但是静态链接的优点就是,在可执行程序中已经具备了所有执行程序所需要的任何东西,在 执行的时候运行速度快。 动态链接的出现解决了静态链接中提到问题。动态链接的基本思想是把程序按照模块拆分成各个相对 独立部分,在程序运行时才将它们链接在一起形成一个完整的程序,而不是像静态链接一样把所有程 序模块都链接成一个单独的可执行文件。 动态链接其实远比静态链接要常用得多。比如我们查看下 hello 这个可执行程序依赖的动态库,会发 现它就用到了一个c动态链接库:
bash
$ ldd hello
linux-vdso.so.1 => (0x00007fffeb1ab000)
libc.so.6 => /lib64/libc.so.6 (0x00007ff776af5000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff776ec3000)
# ldd命令用于打印程序或者库文件所依赖的共享库列表。
在这里涉及到一个重要的概念: 库
- 我们的C程序中,并没有定义"printf"的函数实现,且在预编译中包含的"stdio.h"中也只有该 函数的声明,而没有定义函数的实现,那么,是在哪里实"printf"函数的呢?
- 最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定 时,gcc 会到系统默认的搜索路径"/usr/lib"下进行查找,也就是链接到 libc.so.6 库函数中去,这样 就能实现函数"printf"了,而这也就是链接的作用
3.4 初步了解动态库和静态库

1.为什么要有库?
本质上是程序员之间的一种浪漫的协作方式,站在巨人的肩膀,提高开发效率
2.库在哪里? 
3.库的分类
库分为两种:

- 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运 行时也就不再需要库文件了。其后缀名一般为".a"
- 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由 运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为".so",如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文 件,如下所示。 gcc hello.o --o hello
- gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。
注意:
- Linux下,动态库XXX.so, 静态库XXX.a
- Windows下,动态库XXX.dll, 静态库XXX.lib
一般我们的云服务器,C/C++的静态库并没有安装,可以采用如下方法安装
bash
# Centos
yum install glibc-static libstdc++-static -y
3.5 动/静态库,动/静态链接相关知识补充
1.关于链接
**动态库:**通常和程序进行动态链接
**静态库:**通常和程序进行静态链接
2.如何理解动静态库和动静态库链接??(感性的理解)
**动态库【共享库】(共享资源):**是真实存在的一个文件(动态库在内存中)
**动态链接:**向程序中写入库函数的地址(一个动作)
**动态库和动态链接最大的缺点:**一旦库文件缺失,所有程序无法运行
**优点:**节省资源(不存在重复代码,可以理解为重复的代码都放在了动态库中)
静态库:
静态链接:把每一个程序要用的函数实现,给每一个程序都拷贝一份
动静库和静态链接最大的优点:程序不再依赖任何其他的库
缺点:让可执行程序体积变大。(运行时,加载到内存,占据更多的空间,浪费资源)
gcc默认使用动态库(共享库),节省资源
3.如何强制转换为静态链接?
加一个**-static:** gcc soft.c -o soft_s -static
动态链接文件大小:(默认动态链接)

静态链接文件大小:(需要强制)

查看动态链接和静态链接生成的可执行程序的详细信息和它们所依赖的库信息:

4.两个细节
细节1: 如果我删掉C动态库??
一般而言,系统中大部分指令就无法运行了!
**细节2:**gcc默认使用动态库和动态链接---Linux系统中,默认只安装了动态库。如何解决?
关于指令查看:
**查看一个文件所用的库:**ldd soft(二进制文件名)
3.6 gcc其他常用选项
- -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
- -S 编译到汇编语言不进行汇编和链接
- -c 编译到目标代码
- -o 文件输出到 文件
- -static 此选项对生成的文件采用静态链接
- -g 生成调试信息。GNU 调试器可利用该信息。
- -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
- -O0
- -O1
- -O2
- -O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高 •
- -w 不生成任何警告信息。
- -Wall 生成所有警告信息。
总结
如有不足或改进之处,欢迎大家在评论区积极讨论,后续我也会持续更新Linux相关的知识。文章制作不易,如果文章对你有帮助,就点赞收藏关注支持一下作者吧,让我们一起努力,共同进步!