如何给自己的公司网站做优化,用rp怎么做网站导航菜单,wordpress三栏模板下载,常用的网络推广方式有哪些Linux系统编程 day02 vim、gcc、库的制作与使用 01. vim0101. 命令模式下的操作0102. 切换到文本输入模式0103. 末行模式下的操作0104. vim的配置文件 02. gcc03. 库的制作与使用0301. 静态库的制作与使用0302. 动态库(共享库)的制作与使用 01. vim
vim是一个编辑器#xff0… Linux系统编程 day02 vim、gcc、库的制作与使用 01. vim0101. 命令模式下的操作0102. 切换到文本输入模式0103. 末行模式下的操作0104. vim的配置文件 02. gcc03. 库的制作与使用0301. 静态库的制作与使用0302. 动态库(共享库)的制作与使用 01. vim
vim是一个编辑器需要自行安装可以使用命令sudo apt-get install vim。安装完之后可以在shell中输入vimtutor命令查看帮助文档。
vim有三种工作模式分别是命令模式、文本输入模式以及末行模式。三者的切换关系如下 0101. 命令模式下的操作
用户按下ESC键就可以使vim进入命令模式。当用户使用vim打开一个新文件的时候也是默认进入的命令模式。命令模式中的操作如下。
快捷键操作ZZ保存退出ggG格式化代码h光标左移j光标下移k光标上移l光标右移w光标移动一个单词gg光标移动到文件开头G光标移动到文件末尾0光标移动到行首$光标移动到行尾nG光标移动到第n行x删除光标后一个字符相当于DeleteX删除光标前一个字符相当于Backspacedw删除光标后一个字单词d0删除光标前本行的所有内容不包括光标所在字符d$删除光标后本行的所有内容包括光标所在字符D删除光标后本行的所有内容包括光标所在字符dd删除光标所在行的内容实际上是剪切ndd删除光标当前行向下n行的内容包括本行一共n行实际上是剪切v非列模式视图使用hjkl进行移动选择内容按d删除ctrl v列模式视图使用hjkl移动选择内容按d删除u撤销ctrl r反撤销yy复制当前行的内容nyy复制当前行向下n行包括本行一共n行p在光标位置向下开辟一行并粘贴P在光标位置向上开辟一行并粘贴r替换当前字符R替换当前行光标后的字符//xxx 从光标所在位置开始搜索按n向下搜索按N向上搜索??xxx 从光标所在位置开始搜索按n向上搜索按N向下搜索#将光标移动到待搜索的字符串上然后按n向上搜索按N向下搜索shift k在带搜索的字符串上按下shift k 或者 K 可以查看相关的帮助文档ctrl u向下翻半屏光标向上移动ctrl d向下翻半屏光标向下移动ctrl f向前翻一屏ctrl b向后翻一屏
0102. 切换到文本输入模式
从命令模式切换到文本输入模式的操作如下。
快捷键操作i在光标前插入a在光标后插入I在光标所在行的行首插入A在光标所在行的行尾插入o在光标所在行的下面开辟一行行首插入O在光标所在行的上面开辟一行行首插入s删除光标后的字符并在光标当前位置插入S删除光标所在当前行并在行首插入列模式插入按I或者shift i 向前插入插入字符串后按两次ESC保存。
0103. 末行模式下的操作
从命名模式切换到末行模式只需要输入:即可。下面是关于末行模式的一些操作。
快捷键操作q退出q!强制退出不保存修改内容w保存修改内容不退出wq保存并退出x保存并退出: 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将当前文件的所有old替换为new但是每次替换需要用户确认!shell命令执行shell命令按下两次ESC可以回到命令模式sp当前文件水平分屏vsp当前文件垂直分屏sp 文件名当前文件和另一个文件水平分屏vsp 文件名当前文件和另一个文件垂直分屏ctrl w w多个窗口间切换光标wall保存所有分屏窗口wqall保存并退出所有分屏窗口xall保存并退出所有分屏窗口qall退出所有分屏窗口qall!强制退出所有分屏窗口
分屏模式可以在shell中使用以下命令
# 水平分屏
vim -on 文件1 文件2 ....
vim -o 文件1 文件2 ....
# 垂直分屏
vim -On 文件1 文件2 ....
vim -O 文件1 文件2 ....0104. vim的配置文件
vim的配置文件分别是系统级别配置文件/etc/vim/vimrc和用户级别配置文件~/.vimrc。修改系统级别的配置文件会影响到该系统下的所有用户如果修改的是用户级别的配置文件只会影响到当前的用户而不会影响到其它用户。在配置文件中我们可以添加以下的设置。
命令功能set nu设置显示行号set nonu设置不显示行号set shiftwidth n设置ggG缩进为n个空格默认是8个空格set autoindent设置自动换行每行按与上一行同样的标准进行缩进set list将制表符显示为^|用$表示行尾set showmatch在vim中输入相应的右括号时光标会暂时回到相匹配的左括号set tabstop n设置tab缩进的字符数目为nset encodingutf-8设置编码格式为utf-8set smartindent为C程序提供自动缩进
这些命令也可以在末行模式下使用。
02. gcc
gcc编译器将C语言原程序文件生成一个可执行文件一共需要经理四个步骤分别是预处理、编译、汇编、链接。 这四个步骤的命令如下
# 预处理
gcc -E hello.c -o hello.i
# 编译
gcc -S hello.i -o hello.s
# 汇编
gcc -c hello.s -o hello.o
# 链接
gcc hello.o -o hello当然我们可以一步到位
gcc hello.c -o hello接下来我们来看一看关于gcc的一些常用参数
参数功能作用-v查看gcc版本号–version查看gcc版本号-E预处理生成预处理文件-S编译生成汇编文件-c只编译生成.o文件通常称为目标文件-I指定头文件所在路径-L指定库文件所在路径-l指定库名称-o指定生成的目标的名字-g包含调试信息使用gdb调试的时候需要添加-g参数-On n0~3编译优化n的值越大优化得越多-Wall提示更多警告信息-D编译时定义宏
03. 库的制作与使用
库是二进制文件是源代码文件的另一种表现形式可以认为是加了密的源代码。库是一些功能相近或者相似的函数的集合体。库可以提高代码的重用性提高程序的健壮性同时也可以减少开发者的代码量缩短开发周期。库可以分为静态库和动态库动态库也被称为共享库。
0301. 静态库的制作与使用
静态库可以认为是一些目标代码的集合是在可执行程序运行前就已经加入到执行代码中称为可执行程序的一部分。静态库我们习惯于用.a作为后缀名前缀为lib库的名称是自定义的。比如有一个库的名称是test则该静态库的库文件名就是libtest.a。
静态库的制作主要分为两步第一步是使用gcc中的-c参数将C语言源程序文件编译成.o文件。第二步是使用打包工具ar将.o问加你打包为.a文件。
例如此处我们有add.c、sub.c、mul.c、dive.c、main.c、head.h五个文件。其中head.h中为add.c、sub.c、mul.c、dive.c的声明部分实现在各自的.c文件中。接下来我们需要将前面四个.c文件进行打包制作静态库库名为smath。
首先将他们编译成.o文件。
# 第一种方法是全部直接编译
gcc -c add.c sub.c mul.c dive.c
# 第二种方法是逐个编译
gcc -c add.c -o add.o
gcc -c sub.c -o sub.o
gcc -c mul.c -o mul.o
gcc -c dive.c -o dive.o第二步使用ar打包工具进行打包为静态库文件。
# 将.o文件打包成静态库文件
ar rcs libsmath.a add.o sub.o mul.o dive.o在打包命令中参数r表示更新、c表示创建、s表示建立索引。
如此以来就创建好了一个静态库文件。那么怎么使用呢我们可以通过gcc的参数去指定静态库文件以及头文件的所在路径即可。需要注意的是-l指定库名称的时候不需要写库的前缀lib以及后缀.a。如libsmath.a只需要写smath即可。另外-L、-l、-I参数后面跟的参数可以用空格隔开也可以不隔开。如接下里我们需要编译main.c并执行。 # 生成可执行文件指定头文件为当前路径库文件为当前路径库名为smath
gcc main.c -I./ -L./ -lsmath -o main静态库文件制作好了之后需要将.a文件和头文件一并发布给用户。静态库最终打包到应用程序中实现函数本地化寻址方便、速度快。程序在运行时与函数库再无任何关系移植方便。但是静态库消耗系统资源较大每一个进程使用静态库都需要复制一份浪费内存。静态库会给程序的更新、部署和发布带来麻烦。如果静态库更新了那么所有使用它的应用程序都需要重新编译、发布给用户。对于使用者来说也就是一个很小的改动都需要重新下载整个程序。
0302. 动态库(共享库)的制作与使用
共享库的出现正好解决了上面动态库的不足。共享库在程序编译时并不会被连接到目标代码中而是在程序运行的时候才会被载入。不同的应用程序如果调用相同的共享库那么在内存中只需要有一份该共享库的拷贝即可避免了内存空间浪费的问题。由于动态库是程序运行时才会被载入也解决了静态库对程序的更新、部署和发布带来的麻烦。动态库习惯于以.so作为后缀名前缀也需要加上lib。比如有个动态库的名字为dmath则完成的动态库文件名为libdmath.so。
动态库的制作也有两个步骤第一个步骤是使用gcc中的-fpic参数创建与地址无关的编译程序生成目标文件.o。第二步是使用gcc的-shared生成动态库。
同样我们以静态库的那个例子生成动态库第一步生成目标文件的过程如下
# 生成目标文件 -fpic 创建与地址无关的编译程序 -c 只编译
gcc -fpic -c add.c sub.c mul.c dive.c第二步是生成动态库文件这里取库名为dmath。
# 生成动态库文件 -shared 指定生成动态库
gcc -shared add.o sub.o mul.o dive.o -o libdmath.so如此以来就生成了动态库文件libdmath.so。那么我们如何查看一个库中有哪些内容呢我们可以使用nm命令。
# 查看dmath动态库中有哪些内容
nm libdmath.so
# 查看smath静态库中有哪些内容
nm libsmath.a
# 查看add.o中有哪些内容
nm add.o动态库的使用和静态库的使用方法是一样的需要指定头文件路径、库路径以及库名。如接下来编译main.c生成可执行文件如下
gcc main.c -I./ -L./ -ldmath -o main这样就可以生成可执行程序main。但是在执行运行main程序的时候会报错这是为什么呢因为系统加载可执行代码的时候能够直到其以来的库文件名字但是还需要知道所依赖的库的绝对路径此时就会有系统动态载入器也就是lld。执行ldd命令可以查看可执行文件依赖的库文件。如下面查看main所依赖的库文件。
# 查看main所依赖的库文件
ldd main不过执行这句话的时候有时会反馈找不到。对于ELF格式的可执行程序是由ld-linux.so*来完成的它搜索ELF文件的DT_RPATH段再搜索环境变量LD_LIBRARY_PATH再搜索/etc/ld.so.cache文件列表最后搜索/lib/、/usr/lib/目录找到库文件并将其载入内存。如果上面的都找不到就会报错。我们可以使用file命令查看文件的类型如查看main的类型。
# 查看main的文件类型
file main那么如何让系统找到自己的共享库呢首先分析程序去搜索ELF文件的DT_RPATH段这个部分是我们不能更改的所以我们只能对剩下的三个路径进行下手。方法如下
第一种方法拷贝自己制作的动态库放在/lib/或者/usr/lib/目录下。第二种方法 临时设置LD_LIBRARY_PATH在shell中执行export LD_LIBRARY_PATH$LD_LIBRARY_PATH:库路径。第三种方法永久设置LD_LIBRARY_PATH将LD_LIBRARY_PATH$LD_LIBRARY_PATH:库路径设置到~/.bashrc中然后再使环境变量生效生效可以任使用以下的其中一个方法。 执行. ~/.bashrc使配置文件生效执行source ~/.bashrc使配置文件生效退出当前终端然后再次登录也可以使配置文件生效 第四种方法永久设置把LD_LIBRARY_PATH$LD_LIBRARY_PATH:库路径设置到 /etc/profile文件中。第五种方法添加到/etc/ld.so.cache文件中。编辑/etc/ld.so.conf文件假如库文件所在的目录路径再运行sudo ldconfig -v重建/etc/ld.so.cache文件。
通过上述的方法之后再执行ldd main就可以找到对应依赖的库文件。也就是这个程序终于可以正常运行了。
动态库把对一些库函数的链接载入推迟到了程序运行的时期。动态库实现了进程之间的资源共享。动态库使程序升级变得简单。动态库使得链接载入完全由程序员在代码中控制。
最后对比以下动态库与静态库的优缺点。
-优点缺点动态库1. 节省内存 2. 部署升级更新方便只需替换动态库即可然后再重启服务1. 加载速度比静态库慢 2. 移植性差需要把所有用到的动态库都移植静态库1. 执行速度快因为静态库已经编译到可执行文件内部 2. 移植方便不依赖其它库文件1. 耗费内存因为每一个静态库可执行程序都会加载一次 2. 部署更新麻烦因为静态库修改以后所有调用这个静态库的可执行文件都需要重新编译。