Linux工具【1】(编辑器vim、编译器gcc与g++)
vim详解
- 引言
- vim
- Vim的三种模式及模式切换
- 普通模式下操作
- 底行模式下操作
- gcc与g++
- gcc的使用(g++类似)
- 预编译
- 编译
- 汇编
- 链接
- 静态库与动态库
- 总结
引言
vim(vi improved)编辑器是从 vi 发展出来的一个文本编辑器。 代码补全、编译及错误跳转、语法高亮等方便编程的功能特别丰富,在程序员中被广泛使用。
vim 可以说是程序开发者的一项很好用的工具,它更是一个程序开发工具而不只是文字处理软件。
在vim中编辑代码可以使程序员的手指集中在键盘中央,从而提高效率。
在vim中编辑代码后,要执行代码就需要编译器,在Linux中使用gcc
与g++
编译C与C++代码
vim
为方便演示,我们touch
一个test_vim.c
文件,并使用vim 文件名
以vim方式打开这个文件:
Vim的三种模式及模式切换
vim编辑器有许多模式,在这里只介绍三种常用的模式:命令(普通)模式Normal mode
、底行模式Last line mode
、插入模式Insert mode
:
命令模式(Normal mode)
控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入到Insert mode或者到 last line mode下:
使用vim 文件名
打开后的状态就是命令(正常)模式:
插入模式(Insert mode)
只有在Insert mode下,才可以做文字输入,是使用的最频繁的编辑模式。在命令模式下按i
即可进入该模式,按Esc
键可回到命令行模式:
这个模式中可以正常编辑代码,就不赘述了。
末行模式(last line mode)
文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下按:
即可进入该模式,按Esc
键可回到普通模式:
普通模式下操作
由于空文件下无法观察普通模式的操作,所以先使用插入模式在test_vim.c
文件中输入一些内容:
常用命令:
-
移动光标
小写英文字母h
、j
、k
、l
,分别控制光标左、下、上、右移一格:
G
:移动到文章的最后
$
:移动到光标所在行的“行尾”
^
:移动到光标所在行的“行首”
w
:光标跳到下个字的开头
e
:光标跳到下个字的字尾
b
:光标回到上个字的开头
#l
:光标移到该行的第#个位置
gg
:进入到文本开始
ctrl + b
:屏幕向后移动一页
ctrl + f
:屏幕向前移动一页
ctrl + u
:屏幕向后移动半页
ctrl + d
:屏幕向前移动半页
(移动光标的命令就不举例使用了) -
删除文字
x
:每按一次,删除光标所在位置的一个字符
#x
:表示删除光标所在位置的后(包含自己在内)#个字符
X
:每按一次,删除光标所在位置的前一个字符
#X
:表示删除光标所在位置的前#个字符
dd
:删除光标所在行
#dd
:从光标所在行开始删除#行
-
复制
yw
:将光标所在之处到字尾的字符复制到缓冲区中
#yw
:复制#个字到缓冲区
yy
:复制光标所在行到缓冲区。
#yy
:表示拷贝从光标所在行向下#行文字
p
:将缓冲区内的字符贴到光标所在位置
需要注意的是:所有与y
有关的复制命令都必须与p
配合才能完成复制与粘贴功能
-
替换
r
:替换光标所在处的字符。
R
:替换光标所到之处的字符,直到按下Esc
键为止。
-
撤销上一次操作
u
:回到上一个操作,按多次可以执行多次回复
ctrl + r
: 撤销的恢复 -
更改
cw
:更改光标所在处的字到字尾处
c#w
:表示更改#个字符 -
跳至指定的行
ctrl+g
: 列出光标所在行的行号
#G
:表示移动光标至文章的第#行行首
底行模式下操作
常用命令:
-
列出行号
set nu
: 在文件中的每一行前面列出行号。
(我使用的vim环境已经是配置过的,所以会默认显示行号) -
跳到文件中的某一行
#
:跳到第#行 -
查找字符
/关键字
: 先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按n
会往后寻找
?关键字
:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按n
会往前寻找 -
保存与退出
w
: 可以将文件保存起来,使用!
强制保存
q
:退出vim,后加!
强制离开vim
wq
:保存并退出
gcc与g++
在之前的C语言部分,我们知道我们所写的C代码要经过一系列处理为可执行程序后才能被系统执行,其中包括预编译、编译、汇编、链接
在Windows环境下我们经常使用Visual Studio、DevC、VC等开发环境环境进行代码的编写、编译与运行。而在Linux下我们使用vim
编写代码后,就使用gcc
与g++
编译C与C++代码:
gcc的使用(g++类似)
首先创建一个test_gcc.c
文件,并使用vim在其中编辑一段代码:
预编译
在预编译中会进行头文件包含、宏替换、注释删除、条件编译等,在Linux中执行完预编译后会生成一个.i
文件
使用 gcc -E 依赖文件 -o 目标.i文件
就可以实现将原文件只处理到预编译结束,生成.i
文件为止:
我们可以使用vim打开这个test_gcc.i
文件查看预编译后的代码:
可以看到,与之前的代码对比,将stdio.h文件拷贝到这里,并删除了注释,将M替换为100。
编译
编译即将预编译后的文件转化为汇编代码,在这之前还需要做词法分析、语法分析、语义分析、代码优化等的行为,在这过程中将会检查代码中的错误(即编译错误)。编译结束后会生成一个.s
文件
使用gcc -S 原文件 -o 目标.s文件
就可以实现将原文件只处理到编译结束,生成.s文件中止,(原文件可以为.c
文件,也可以是已经预编译后的.i
文件)
当然我们也可以使用vim查看这个.s
文件:
汇编
汇编即将之前生成的汇编代码生成目标代码(在这里就是机器可识别的二进制代码),这其中还要进行符号表的生成等(符号与其地址),之后会生成一个.o
文件
使用 gcc -c 原文件 -o 目标.o文件
就可以将原文件处理到汇编结束,生成.o文件为止(原文件可以为之前的任意状态的文件)
我们当然也可以通过vim查看这个.o
文件(但这并没有什么意义,因为完全看不懂,这里就不展示了)
链接
在进行完之前的处理后,就需要将我们写的文件与库,或者与我们写的其他文件链接起来,最终生成一个可执行程序。这个过程中会重新定位符表
使用 gcc 原文件 -o 可执行文件
就可以实现将之前任一状态的文件处理后进行链接从而生成一个可执行程序:
./
打开这个可执行程序就可以运行了:
需要注意的是,当编辑的代码中含有C99标准及以后的语法时,需要在编译时加上 -std=c99
选项
静态库与动态库
我们在文件中包含的stdio.h只是头文件,即声明。而这些函数的定义是在库中的,这也就是为什么我们需要将我们写的代码与库进行链接后才能生成可执行程序。 系统中有两种类型的库,即静态库与动态库。
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中。所以生成的文件比较大,但在运行时也就不再需要库文件了,其后缀名一般为.a
动态库是在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为.so
gcc 在编译时默认使用动态库(可以通过file
查看):
总结
到此,关于Linux工具中的编译器vim
与编译器gcc
/g++
就介绍完了
在下一篇文章中将介绍其余的Linux工具,希望大家持续关注哦
如果大家认为我对某一部分没有介绍清楚或者某一部分出了问题,欢迎大家在评论区提出
如果本文对你有帮助,希望一键三连哦
希望与大家共同进步哦
相关文章:

Linux工具【1】(编辑器vim、编译器gcc与g++)
vim详解 引言vimVim的三种模式及模式切换普通模式下操作底行模式下操作 gcc与ggcc的使用(g类似)预编译编译汇编链接静态库与动态库 总结 引言 vim(vi improved)编辑器是从 vi 发展出来的一个文本编辑器。 代码补全、编译及错误跳…...

基于Java+SpringBoot+vue前后端分离古典舞在线交流平台设计实现
博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…...

MQ - 闲聊MQ一二事儿 (Kafka、RocketMQ 、Pulsar )
文章目录 MQ的发展史阶段一:追求解耦阶段二:追求吞吐量与一致性阶段三:追求平台化 MQ的通用架构主题topic、生产者producer、消费者consumer分区partition MQ 存储KafkaGood Design ---> 磁盘顺序写盘Poor Impact---> topic 数量不能过…...

Qt中的 QIODevice类(包含:随机访问、顺序访问设备)
QIODevice类 一、简介 QIODevice用于对输入输出设备进行管理,是Qt中所有I/O设备的基接口类。为支持读写数据块的设备(如QFile、QBuffer和QTcpSocket)提供了通用实现和抽象接口。 输入设备有2种类型: 一种是随机访问设备,QFile(文件)和QBuff…...

【JavaScript 07】函数声明 地位平等 函数提升 属性方法 作用域 参数 arguments对象 闭包 IIFE立即调用函数表达式 eval命令
函数 1 概述1.1 声明1.2 重复声明 1.3 圆括号/return/recursion1.4 一等公民1.5 函数提升 2 函数属性与方法2.1 name属性2.2 length属性2.3 toString() 3 函数作用域3.1 概念3.2 函数内部变量提升3.3 函数本身作用域 4 参数4.1 概念4.2 省略4.3 传递4.4 同名4.5 arguments 对象…...

MyBatis源码分析_ResultSetHandler(7)
目录 1. 传统JDBC 2. Mybatis访问数据库 2.1 Statement访问数据库 2.2 火枪手 ResultSetHandler 出现 3. ResultSetHandler处理结果集 3.1 首先就是进入 handleResultSets 方法 3.2 handleResultSet 方法根据映射规则(resultMap)对结果集进行转化…...

Unittest加载执行用例的方法总结
前言 说到测试框架,unittest是我最先接触的自动化测试框架之一了, 而且也是用的时间最长的, unittest框架有很多方法加载用例,让我们针对不同的项目,不同项目的大小及用例的多少自己选择加载方式。今天我们就简单的说说…...

使用预训练的2D扩散模型改进3D成像
扩散模型已经成为一种新的生成高质量样本的生成模型,也被作为有效的逆问题求解器。然而,由于生成过程仍然处于相同的高维(即与数据维相同)空间中,极高的内存和计算成本导致模型尚未扩展到3D逆问题。在本文中࿰…...

微服务测试是什么?
微服务测试是一种特殊的测试类型,因为它涉及到多个独立的服务。以下是进行微服务测试的一般性步骤: 【B站最通俗易懂】Python接口自动化测试从入门到精通,超详细的进阶教程,看完这套视频就够了 1. 确定系统架构 了解微服务架构对…...

《现代C++教程》笔记(5-7)
文章目录 5 智能指针与内存管理5.1 RAII与引用计数5.2 std::shared_ptr5.3 std::unique_ptr5.4 std::weak_ptr 6 正则表达式7 并行与并发7.1 并行基础7.2 互斥量与临界区7.3 期物7.4 条件变量7.5 原子操作与内存模型 5 智能指针与内存管理 5.1 RAII与引用计数 在传统 C 中&am…...

红黑树深入剖析【C++】
目录 一、红黑树概念 二、红黑树节点结构设计 三、插入操作 处理情况1 处理情况2 处理情况3 插入总结: 四、插入操作源码 五、红黑树验证 一、红黑树概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色࿰…...

教育机构视频播放时观看行为分析有哪些应用?
教育机构视频播放时观看行为分析有哪些应用? 观看行为分析 观看行为分析是指我们平台基于视频大数据分析,能够以秒为粒度展示观众如何观看您的视频。 视频观看热力图是单次观看行为的图形化表示,我们平台云点播视频的每一次播放࿰…...

Jmeter+验证json结果是否正确小技巧
前言: 通过sql语句或者返回的参数,可以在查看结果树返回的结果中,用方法先跑一下验证是否取到自己想要的值 步骤: 1、添加查看结果树 2、跑出结果 3、在查看结果树中 text改成选Json Path Tester 返回的值如果是列表里面的字符…...

Spring 6.0官方文档示例(22): singleton类型的bean和prototype类型的bean协同工作的方法(一)
一、配置文件: <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:context"http://www.springframework.org/schema/context"xsi:schemaLocation"http…...

Android平台GB28181设备接入侧如何同时对外输出RTSP流?
技术背景 GB28181的应用场景非常广泛,如公共安全、交通管理、企业安全、教育、医疗等众多领域,细分场景可用于如执法记录仪、智能安全帽、智能监控、智慧零售、智慧教育、远程办公、明厨亮灶、智慧交通、智慧工地、雪亮工程、平安乡村、生产运输、车载终…...

el-Cascader 中div上绑定keyDown事件
keydown,keyup,keypress 事件默认是给页面上可以聚焦的元素绑定键盘事件,例如input输入框,点击输入框即代表聚焦在该元素上。那么想要给div或者其他不能聚焦的元素上使用键盘事件怎么处理呢?这里用到tabindex属性。 …...

elementUI 表格滚动分页加载请求数据
需求:elementui Table表格滚动分页(不使用分页组件),请求数据。 1、自定义加载更多数据的指令,在utils文件夹中创建 loadMore.js /*** 加载更多数据的指令*/ export default {install(Vue) {Vue.mixin({directives: …...

JAVA面试总结-Redis篇章(五)——持久化
Java面试总结-Redis篇章(五)——持久化 1.RDBRDB全称Redis Database Backup file (Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件&#x…...

【数据结构】·顺序表函数实现·赶紧学起来呀
💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …...

C++,类和对象-多态,制作饮品
#include<iostream> using namespace std;//多态案例,制作饮品class AbstractDrinking { public://煮水virtual void Boil() 0;//冲泡virtual void Brew() 0;//倒入茶杯virtual void PourInCup() 0;//加入辅料virtual void PutSomething() 0;//制作饮品vo…...

网站分析:学习如何分析目标网站的页面结构和URL规律,确定爬取目标和策略。
要学习如何分析目标网站的页面结构和URL规律,确定爬取目标和策略,可以遵循以下步骤: 目标网站的页面结构分析: 寻找目标网站的主页,并观察主页上的链接、导航菜单和内容分类等元素,以了解网站的整体结构。 …...

《向量数据库指南》:向量数据库Pinecone如何集成数据湖
目录 为什么选择Databricks? 为什么选择Pinecone? 设置Spark集群 环境设置 将数据集加载到分区中 创建将文本转换为嵌入的函数 将UDF应用于数据 更新嵌入 摘要 使用Databricks和Pinecone在规模上创建和索引向量嵌入 建立在Apache Spark之上的Databricks是一个强大的…...

Vue3中使用pinia
在Vue 3中使用Pinia,您需要按照以下步骤进行设置: 安装Pinia: npm install pinia创建和配置Pinia存储: // main.jsimport { createApp } from vue import { createPinia } from pinia import App from ./App.vueconst app create…...

Mysql中(@i:=@i+1)的介绍
i:i1 表达式 生成伪列实现自增序列 语法: select (i:i1) as ,t.* from table_name t,(select i:0) as j (i:i1)代表定义一个变量,每次叠加 1; (select i:0) as j 代表建立一个临时表,j是随便取的表名,但别名一定…...

Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作
Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作 基础半导体器件领域的高产能生产专家Nexperia(安世半导体)近日宣布与国际著名的为汽车行业提供先进电子器件的供应商 KYOCERA AVX Components (Salzburg) GmbH 建立合作关系&am…...

数据库应用:Redis安装部署
目录 一、理论 1.缓存 2.关系型数据库与非关系型数据库 3.Redis 4.Redis安装部署 5.Redis命令工具 6.Redis数据库常用命令 7.Redis多数据库操作 二、实验 1.Redis安装部署 2.Redis命令工具 3.Redis数据库命令 4.Redis多数据库操作 三、问题 1.RESP连接CentOS 7 R…...

7.Docker-compose
文章目录 Docker-compose概念Docker-compose部署YAML文件格式和编写注意事项注意数据结构对象映射序列属组布尔值序列的映射映射的映射JSON格式文本换行锚点和引用 Docker compose配置常用字段docker compose常用命令Docker Compose 文件结构docker compose部署apachedocker co…...

多线程:管程法
管程法 生产者把生产好的数据放入缓冲区,消费者从缓冲区拿出数据 package jingcheng.test.gaoji; //测试生产者消费者模型-->利用缓冲区解决:管程法 //生产者,消费者,产品,缓冲区 public class TestPc {public st…...

7.1 String StringBuffer 和 StringBuilder 的区别是什么? String 为什么是不可变的?
可变性 简单的来说:String 类中使用 final 关键字修饰字符数组来保存字符串,private final char value[],所以String 对象是不可变的。 补充(来自issue 675):在 Java 9 之后,String 、StringBu…...

【C++STL标准库】容器适配器
功能:将功能类似,但是接口不符合的接口转换成另一个接口 stack 栈stack(栈) 特点:先入后出,只能从栈顶弹出值,只能从栈顶压入值 也就是说栈需要的功能:push_back、pop_back 所以可…...