linux 系统中vi 编辑器和库的制作和使用

目录

1 vim

1.1 vim简单介绍

1.2 vim的三种模式

1.3 vim基本操作

1.3.1命令模式下的操作

1.3.2 切换到文本输入模式

1.3.3 末行模式下的操作

2 gcc编译器

2.1 gcc的工作流程

2.2 gcc常用参数

3 静态库和共享(动态)库

3.1库的介绍   

3.2静态库(static library)

3.3共享库(shared library)/动态库


学习目标

掌握vim命令模式下相关命令的使用

掌握从命令模式切换到编辑模式的相关命令

掌握vim末行模式下相关命令的使用

能够说出gcc的工作流程和掌握常见参数的使用

熟练掌握Linux下的静态库的制作和使用

熟练掌握Linux下的共享库的制作和使用

1 vim

1.1 vim简单介绍

vi是visual interface的简称, 它在Linux上的地位就仿佛Windows的记事本一样. 它可以执行编辑、删除、查找、替换、块操作等众多文本操作, 而且用户可以根据自己的需要对其进行定制. vi是一个文本编辑程序, 没有菜单, 只有命令.

vim更高级一些, 可以理解是vi的高级版本.

vim需要自行安装, 在shell中输入vimtutor命令可以查看相关的帮助文档.

1.2 vim的三种模式

Vi有三种基本工作模式: 命令模式、文本输入模式、末行模式。

三种工作模式的切换如图所示, 从下图中可以看出编辑模式和末行模式之间不能相互切换, 必须经过命令模式.

1.3 vim基本操作

1.3.1命令模式下的操作

用户按下esc键, 就可以使vi进入命令模式下; 当使用vi打开一个新文件开始也是进入命令模式下.

保存退出

快捷键

操作

ZZ

保存退出

代码格式化

快捷键

操作

gg=G

代码的格式化

光标移动

快捷键

操作

h

光标左移

j

光标下移

k

光标上移

l

光标右移

w

移动一个单词

gg

光标移动到文件开头

G

光标移动到文件末尾

0

光标移到到行首

$

光标移到到行尾

nG

行跳转, 例12G, 跳到12行处

删除命令

快捷键

操作

x

删除光标后一个字符,相当于 Del

X

删除光标前一个字符,相当于 Backspace

dw

删除光标开始位置的字,包含光标所在字符

d0

删除光标前本行所有内容,不包含光标所在字符

D[d$]

删除光标后本行所有内容,包含光标所在字符

dd

删除光标所在行(本质其实是剪切)

ndd

从光标当前行向下删除指定的行数, 如15dd

v/ctrl+v

使用h、j、k、l移动选择内容, 然后按d删除其中ctrl+v是列模式, v为非列模式

撤销和反撤销命令

快捷键

操作

u

一步一步撤销, 相当于word文档的ctrl+z

ctrl-r

反撤销, 相当于word文档的ctrl+y

复制粘贴

快捷键

操作

yy

复制当前行

nyy

复制n行, 如10yy

p

在光标所在位置向下新开辟一行, 粘贴

P

在光标所在位置向上新开辟一行, 粘贴

剪切

操作

按dd或者ndd删除, 将删除的行保存到剪贴板中, 然后按p/P就可以粘贴了

可视模式

快捷键

操作

v/ctrl+v

使用h、j、k、l移动选择内容;

使用d删除

使用y复制 

使用p粘贴到光标的后面

使用P粘贴到光标的前面

替换操作

快捷键

操作

r

替换当前字符

R

替换当前行光标后的字符

查找命令

快捷键

操作

/

/xxxx, 从光标所在的位置开始搜索, 按n向下搜索, 按N向上搜索

?

?xxxx, 从光标所在的位置开始搜索, 按n向上搜索, 按N向下搜索

#

将光标移动到待搜索的字符串上, 然后按n向上搜索,但N向下搜索

shift+k

在待搜索的字符串上按shift+k或者K, 可以查看相关的帮助文档

1.3.2 切换到文本输入模式

从命令模式切换到文本输入模式只需输入如下命令:

快捷键

操作

i

在光标前插入

a

在光标后插入

I

在光标所在行的行首插入

A

在光标所在行的行尾插入

o

在光标所在的行的下面新创建一行, 行首插入

O

在光标所在的行的上面新创建一行, 行首插入

s

删除光标后边的字符, 从光标当前位置插入

S

删除光标所在当前行, 从行首插入

按列模式插入

先按ctrl+v进入列模式, 按hjkl移动选定某列,按I或者shift+i向前插入, 然后插入字符, 最后按两次esc.

1.3.3 末行模式下的操作

从命令模式切换到末行模式, 输入冒号(:)

保存退出

快捷键

操作

q

退出

 q!

强制退出,不保存修改内容

w

保存修改内容, 不退出

wq

保存并退出

x

相当于wq

替换操作

下面表格中old表示原字符串, new表示新字符串

快捷键

操作

:s/old/new/

光标所在行的第一个old替换为new

:s/old/new/g

光标所在行的所有old替换为new

:m, ns/old/new/g

将第m行至第n行之间的old全部替换成new

:%s/old/new/g

当前文件的所有old替换为new

:1,$s/old/new/g

当前文件的所有old替换为new

:%s/old/new/gc

同上,但是每次替换需要用户确认

快速翻屏

   快捷键

操作

ctrl + u

向下翻半屏(up)--光标向上移动

ctrl + d

向上翻半屏(down)--光标向下移动

ctrl + f

向上翻一屏(front)

ctrl + b

向后翻一屏(back)

在末行模式下执行shell命令

!shell命令

按下两次esc可以回到命令模式

分屏操作

  1. 在打开文件之后分屏:

快捷键

操作

sp

当前文件水平分屏

vsp

当前文件垂直分屏

sp 文件名

当前文件和另一个文件水平分屏

vsp 文件名

当前文件和另一个文件垂直分屏

ctrl-w-w

在多个窗口切换光标

wall/wqall/xall/qall/qall!

保存/保存退出/保存退出/退出/强制退出分屏窗口

  1. 在打开文件之前分屏:

分屏: vim -on file1 file2 …  

垂直分屏: vim -On file1 file2…  

注意: n可以省略, 有几个文件就分几屏

从末行模式切换回命令模式

按两次ESC, 退格(backspace)或者回车键

1.3.4 vim的配置文件

用户级别配置文件

~/.vimrc, 修改用户级别的配置文件只会影响当前用户, 不会影响其他的用户.

例如: 在用户的家目录下的.vimrc文件中添加

set tabstop=4  ----设置缩进4个空格

set nu        ----设置行号

set shiftwidth=4  ---设置gg=G缩进4个空格, 默认是缩进8个空格

系统级别配置文件

/etc/vim/vimrc, 修改了系统级别的配置文件将影响系统下的所有用户.

说明: 由于linux是多用户操作系统, 建议只在用户级别的配置文件下进行修改, 不要影响其他用户.

2 gcc编译器

2.1 gcc的工作流程

gcc编译器将c源文件生成一个可执行程序,中间一共经历了四个步骤:

 

四个步骤并不是gcc独立完成的,而在内部调用了其他工具,从而完成了整个工作流程, 其中编译最耗时, 因为要逐行检查语法.

下面以test.c为例介绍gcc的四个步骤:

gcc -E test.c -o test.i

gcc -S test.i -o test.s

gcc -c test.s -o test.o

gcc test.o -o test

一步生成最终的可执行程序:

  gcc test.c -o test

2.2 gcc常用参数

  • -v  查看gcc版本号, --version也可以
  • -E  生成预处理文件
  • -S  生成汇编文件
  • -c  只编译, 生成.o文件, 通常称为目标文件
  • -I   指定头文件所在的路径
  • -L   指定库文件所在的路径
  • -l    指定库的名字
  • -o   指定生成的目标文件的名字
  • -g   包含调试信息, 使用gdb调试需要添加-g参数
  • -On n=03 编译优化,n越大优化得越多

例如:下面代码片段

int a = 10;

int b = a;

int c = b;

printf("%d", c);

上面的代码可能会被编译器优化成:

int c = 10;

printf("%d", 10);

  • -Wall 提示更多警告信息

int a;

int b;

int c = 10;

printf(“[%d]\n”, c);

编译如下: 

gcc -o test -Wall test.c

warning: unused variable ‘b’ [-Wunused-variable]

warning: unused variable ‘a’ [-Wunused-variable]

  • -D  编译时定义宏

test.c文件中的代码片段:

printf("MAX==[%d]\n", MAX);

         编译:

     gcc -o test test.c -D MAX=10

       gcc -o test test.c -DMAX=10

3 静态库和共享(动态)

3.1库的介绍   

什么是库

   库是二进制文件, 是源代码文件的另一种表现形式, 是加了密的源代码;

是一些功能相近或者是相似的函数的集合体.

使用库有什么好处

  • 提高代码的可重用性, 而且还可以提高程序的健壮性;
  • 可以减少开发者的代码开发量, 缩短开发周期.

库制作完成后, 如何给用户使用

  • 头文件---包含了库函数的声明
  • 库文件---包含了库函数的代码实现

注意: 库不能单独使用, 只能作为其他执行程序的一部分完成某些功能, 也

就是说只能被其他程序调用才能使用.

库可分静态库(static library)和共享库(shared library)

3.2静态库(static library)

静态库可以认为是一些目标代码的集合, 是在可执行程序运行前就已经加入到执行码中, 成为执行程序的一部分. 按照习惯, 一般以.a做为文件后缀名.

静态库命名一般分为三个部分:

  • 前缀:lib
  • 库名称定义即可, 如test
  • 后缀:.a

所以最终的静态库的名字应该为:libtest.a

静态库的制作

下面以fun1.c , fun2.c和head.h三个文件为例讲述静态库的制作和使用, 其中head.h文件中有函数的声明,  fun1.c和fun2.c中有函数的实现.

步骤1:将c源文件生成对应的.o文件

gcc -c fun1.c fun2.c

   或者分别生成.o文件:

  gcc -c fun1.c -o fun1.o

  gcc -c fun2.c -o fun2.o

步骤2:使用打包工具ar将准备好的.o文件打包为.a文件 

  1. 在使用ar工具是时候需要添加参数rcs
  • r更新、c创建、s建立索引
  1. 命令:ar rcs 静态库名 .o文件
  • ar rcs libtest1.a fun1.o fun2.o

静态库的使用

静态库制作完成之后, 需要将.a文件和头文件一定发布给用户.

假设测试文件main.c, 静态库文件为libtest1.a, 头文件为head.h

用到的参数:

  • -L:指定要连接的库的所在目录
  • -l:指 
  • -I: 指定main.c文件用到的头文件head.h所在的路径

gcc -o main1 main.c -L./ -ltest1 -I./

gcc -o main1 main.c -L./ -ltest1

-I 指向头文件所在的位置 -L指向库文件所在的位置,头文件和库文件在同一个目录-I 可以省略

使用ldd main1.可以查看加载的动态库是否找到了。

静态库的优缺点

  1. 优点
    • 函数库最终被打包到应用程序中实现是函数本地化寻址方便、速度快。

(库函数调用效率==自定义函数使用效率)

    • 程序在运行时与函数库再无瓜葛,移植方便。
  1. 缺点
    • 消耗系统资源较大, 每个进程使用静态库都要复制一份, 无端浪费内存。

    • 静态库会程序的更新、部署和发布带来麻烦。如果静态库libxxx.a更新了,所有使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载)。

3.3共享库shared library/动态库

共享库在程序编译时并不会被连接到目标代码中, 而是在程序运行是才被载入. 不同的应用程序如果调用相同的库, 那么在内存里只需要有一份该共享库的拷贝, 规避了空间浪费问题.动态库在程序运行时才被载入, 也解决了静态库对程序的更新、部署和发布会带来麻烦. 用户只需要更新动态库即可, 增量更新. 为什么需要动态库, 其实也是静态库的特点导致.

按照习惯, 一般以.so”做为文件后缀名. 共享命名一般分为三个部分:

  • 前缀:lib
  • 库名称自己定义即可, 如test
  • 后缀:.so

所以最终的静态库的名字应该为:libtest.so

共享库的制作

  1. 生成目标文件.o, 此时要加编译选项:-fPIC(fpic

gcc -fpic -c fun1.c fun2.c

参数:-fpic创建与地址无关的编译程序(pic, position independent code), 目的就是为了能够在多个应用程序间共享.

  1. 生成共享库, 此时要加链接器选项: -shared(指定生成动态链接库

gcc -shared fun1.o fun2.o -o libtest2.so

共享库的使用

引用动态库编译成可执行文件(跟静态库方式一样):

用到的参数:

  • -L:指定要连接的库的所在目录
  • -l:指定链接时需要的动态库, 去掉前缀和后缀
  • -I: 指定main.c文件用到的头文件head.h所在的路径

gcc main.c -I./ -L./ -ltest2 -o main2

然后运行:./main2,发现竟然报错了.

分析为什么在执行的时候找不到libtest2.so库

  • 当系统加载可执行代码时候, 能够知道其所依赖的库的名字, 但是还需要知道所依赖的库的绝对路径。此时就需要系统动态载入器(dynamic linker/loader)。

ldd命令可以查看可执行文件依赖的库文件, 执行ldd main2, 可以发现libtest2.so找不到.

  • 对于elf格式的可执行程序,是由ld-linux.so*来完成的, 它先后搜索elf文件的 DT_RPATH段 — 环境变量LD_LIBRARY_PATH /etc/ld.so.cache文件列表 — /lib/, /usr/lib目录找到库文件后将其载入内存。

使用file命令可以查看文件的类型: file main2

如何让系统找到共享库

  • 拷贝自己制作的共享库到/lib或者/usr/lib
  • 临时设置LD_LIBRARY_PATH:
    • export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径
  • 永久设置, 把export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径, 设置到/.bashrc文件中, 然后在执行下列三种办法之一:
  • 执行. ~/.bashrc使配置文件生效(第一个.后面有一个空格)
  • 执行source ~/.bashrc配置文件生效
  • 退出当前终端, 然后再次登陆也可以使配置文件生效
  • 永久设置,把export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径,设置到/etc/profile文件中
  • 将其添加到 /etc/ld.so.cache文件中
    • 编辑/etc/ld.so.conf文件, 加入库文件所在目录的路径
    • 运行sudo ldconfig -v, 该命令会重建/etc/ld.so.cache文件

解决了库的路径问题之后, 再次ldd命令可以查看可执行文件依赖的库文件, ldd main2:

共享库特点

  • 动态库把对一些库函数的链接载入推迟到程序运行的时期。
  • 可以实现进程之间的资源共享。(因此动态库也称为共享库)
  • 将一些程序升级变得简单。

甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)

3.4比较静态库和动态库的优缺点

 静态库的优点:

  1 执行速度快, 是因为静态库已经编译到可执行文件内部了

  2 移植方便, 不依赖域其他的库文件

 缺点:

  1 耗费内存, 是由于每一个静态库的可执行程序都会加载一次

  2 部署更新麻烦, 因为静态库修改以后所有的调用到这个静态库的可执行文

件都需要重新编译

 动态库的优点:

  1 节省内存

  2 部署升级更新方便, 只需替换动态库即可, 然后再重启服务.

 缺点:

  1 加载速度比静态库慢

  2 移植性差, 需要把所有用到的动态库都移植.

由于由静态库生成的可执行文件是把静态库加载到了其内部, 所以静态库生成的可执行文件一般会比动态库大.

作业:

1 复习当天内容, 重点是gcc和库的制作和使用

2 编写4个.c文件, 加, 减, 乘, 除

  add.c --加法

  sub.c --减法

  mul.c --乘法

  dive.c --除法

  main.c ---主函数所在文件, 内部调用上述函数

  head.h  ---函数声明

  libsmath.a  --静态库文件

  libdmath.so  --动态库文件

  main1---静态库可执行程序

  main2--动态库可执行程序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/96487.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring事件监听机制

前言 事件监听机制其原理就是观察者模式,而观察者模式又被称为发布-订阅模式。 观察者模式将有依赖关系的对象抽象为了观察者和主题两个不同的角色,多个观察者同时观察一个主题,两者只通过抽象接口保持松耦合状态,这样双方可以相…

【数据结构】 单链表面试题讲解

文章目录 引言反转单链表题目描述示例:题解思路代码实现: 移除链表元素题目描述:示例思路解析: 链表的中间结点题目描述:示例:思路解析代码实现如下: 链表中倒数第k个结点题目描述示例思路解析&…

2023.8 - java - 对象和类

public class Dog {String breed;int size;String colour;int age;void eat() {}void run() {}void sleep(){}void name(){} } 一个类可以包含以下类型变量: 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方…

基于IDE Eval Resetter延长IntelliJ IDEA等软件试用期的方法(包含新版本软件的操作方法)

本文介绍基于IDE Eval Resetter插件,对集成开发环境IntelliJ IDEA等JetBrains公司下属的多个开发软件,加以试用期延长的方法。 我们这里就以IntelliJ IDEA为例,来介绍这一插件发挥作用的具体方式。不过,需要说明使用IDE Eval Rese…

感觉和身边其他人有差距怎么办?

虽然清楚知识需要靠时间沉淀,但在看到自己做不出来的题别人会做,自己写不出的代码别人会写时还是会感到焦虑怎么办? 你是否也因为自身跟周围人的差距而产生过迷茫,这份迷茫如今是被你克服了还是仍旧让你感到困扰? 下…

SSM——用户、角色、权限操作

1. 数据库与表结构 1.1 用户表 1.1.1 用户表信息描述 users 1.1.2 sql语句 CREATE TABLE users( id varchar2(32) default SYS_GUID() PRIMARY KEY, email VARCHAR2(50) UNIQUE NOT NULL, username VARCHAR2(50), PASSWORD VARCHAR2(50), phoneNum VARCHAR2(20), STATUS INT…

推荐一个绘图平台(可替代Visio)

不废话,简易记网址: draw.io 网站会重定向到:https://app.diagrams.net/

Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)

文章目录 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)服务端客户端 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四) 服务端 服务端结构如下: UserModel using System; using System.Collections.Generic; usin…

因果推断(四)断点回归(RD)

因果推断(四)断点回归(RD) 在传统的因果推断方法中,有一种方法可以控制观察到的混杂因素和未观察到的混杂因素,这就是断点回归,因为它只需要观察干预两侧的数据,是否存在明显的断点…

QT的布局与间隔器介绍

布局与间隔器 1、概述 QT中使用绝对定位的布局方式,无法适用窗口的变化,但是,也可以通过尺寸策略来进行 调整,使得 可以适用窗口变化。 布局管理器作用最主要用来在qt设计师中进行控件的排列,另外,布局管理…

[论文笔记]Glancing Transformer for Non-Autoregressive Neural Machine Translation

引言 这是论文Glancing Transformer for Non-Autoregressive Neural Machine Translation的笔记。 传统的非自回归文本生成速度较慢,因为需要给定之前的token来预测下一个token。但自回归模型虽然效率高,但性能没那么好。 这篇论文提出了Glancing Transformer,可以只需要一…

vscode ssh 远程 gdb 调试

一、点运行与调试,生成launch.json 文件 二、点添加配置,选择GDB 三、修改启动程序路径

AMD fTPM RNG的BUG使得Linus Torvalds不满

导读因为在 Ryzen 系统上对内核造成了困扰,Linus Torvalds 最近在邮件列表中表达了对 AMD fTPM 硬件随机数生成器的不满,并提出了禁用该功能的建议。 因为在 Ryzen 系统上对内核造成了困扰,Linus Torvalds 最近在邮件列表中表达了对 AMD fTPM…

『C语言』数据在内存中的存储规则

前言 小羊近期已经将C语言初阶学习内容与铁汁们分享完成,接下来小羊会继续追更C语言进阶相关知识,小伙伴们坐好板凳,拿起笔开始上课啦~ 一、数据类型的介绍 我们目前已经学了基本的内置类型: char //字符数据类型 short …

高效反编译luac文件

对于游戏开发人员,有时候希望从一些游戏apk中反编译出源代码,进行学习,但是如果你触碰到法律边缘,那么你要非常小心。 这篇文章,我针对一些用lua写客户端或者服务器的编译过的luac文件进行反编译,获取其源代码的过程。 这里我不赘述如何反编译解压apk包的过程了,只说重点…

CSS3:图片边框

简介 图片也可以作为边框&#xff0c;以下是实例演示 注意 实现该效果必须添加border样式&#xff0c;且必须位于border-image-socure之前否则不会生效 实例 <html lang"en"><head><style>p {width: 600px;margin: 200px auto;border: 30px soli…

【数理知识】三维空间旋转矩阵的欧拉角表示法,四元数表示法,两者之间的转换,Matlab 代码实现

序号内容1【数理知识】自由度 degree of freedom 及自由度的计算方法2【数理知识】刚体 rigid body 及刚体的运动3【数理知识】刚体基本运动&#xff0c;平动&#xff0c;转动4【数理知识】向量数乘&#xff0c;内积&#xff0c;外积&#xff0c;matlab代码实现5【数理知识】最…

【C语言】每日一题(找到所有数组中消失的数字)

找到所有数组中消失的数字&#xff0c;链接奉上。 这里简单说一下&#xff0c;因为还没有接触到动态内存&#xff0c;数据结构&#xff0c;所以知识有限&#xff0c;也是尽力而为&#xff0c;结合题库的评论区找到了适合我的解法&#xff0c;以后有机会&#xff0c;会补上各种…

视频云存储/安防监控/视频汇聚EasyCVR平台新增设备经纬度选取

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…

使用Vscode调试shell脚本

在vcode中安装bash dug插件 在vcode中添加launch.json配置&#xff0c;默认就好 参考&#xff1a;http://www.rply.cn/news/73966.html 推荐插件&#xff1a; shellman(支持shell,智能提示) shellcheck(shell语法检查) shell-format(shell格式化)