Linux系统编程 Part2(vim、gcc编译、动静态库)

vim

三种模式的转换:

*命令模式 *

插入:进入输入模式

  • i:在光标前进行输入
  • a:在光标后进行输入
  • I:在光标所在行首进行输入
  • A:在光标所在行尾进行输入
  • o:在光标下一行进行输入
  • O:在光标上一行进行输入

删除:其实是剪切到缓冲区

  • 删除单个字符:x(删的是光标上的那个字符)
  • 删除一个单词:dw(光标必须处于这个单词的第一个字母)
  • 删除光标至行尾:D或者d$(光标所在处字符会被删除)
  • 删除光标至行首:d0(光标所在处字符会被删除)
  • 删除指定1行:dd
  • 删除指定n行:ndd
  • 删除指定区域:按V切换为可视模式,移动光标来选中待删除区域,再按 d 删除该区域

移动光标:

  • 上下左右:小键盘方向键或者hjkl
  • 移至行首:0
  • 移至行尾:$

跳转到指定行:

  • 跳到首行:gg
  • 跳到末行:G
  • 跳到指定行:25G(或者在末行模式下可以通过:25来进行跳转)

复制粘贴剪切:

  • 复制本行:yy
  • 复制多行:nyy
  • 复制指定区域:按V切换为可视模式,移动光标来选中待复制区域,再按 yy复制该区域
  • 粘贴:p(粘贴到光标后)、P(粘贴到光标前)
  • 剪切:删除就会将内容剪切到缓冲区

查找:

  • 关键字查找:按/输入搜索关键字,回车,再按n显示下一个搜索结果
  • 文中重复内容查找:将光标置于单词任意一个字符上,按*或者#

撤销修改:u

反向撤销修改:ctrl + r

自动格式排版:gg=G

找到对应的另一半大括号:将光标移动到其中一个大括号,按下%即可跳转到另一个大括号

跳转至 man 帮助手册:将光标置于待查看函数单词上,按下K跳转(指定卷:nK)

查看宏定义:将光标置于待查看宏定义单词上,按下[d查看定义语句

函数跳转:将光标置于函数名上,按Ctrl-]进行跳转(需要ctags工具,详见下一篇博文)

*末行模式*

替换:

  • 单个字符替换:将光标置于待替换字符上, 按r进行替换(注意要在命令模式下执行)
  • 单行替换:将光标置于待替换行上,进入末行模式,输入:s/原数据/新数据
  • 通篇替换:末行模式下,输入 :%s /原数据/新数据/g
  • 指定行的替换:末行模式,:起始行号,终止行号s /原数据/新数据/g

分屏:

  • 竖屏:vsp (分屏可以直接新建或打开文件,比如 :vsp sub.c
  • 横屏:sp
  • 切换屏幕:ctrl+ww
  • 关闭分屏::q(如果要一次性关闭所有分屏并保存 :wqall

执行shell命令:!命令


gcc

gcc编译四步骤:预处理、编译、汇编、链接

gcc命令参数:

  • -o:指定gcc编译结果文件名 gcc hello.c -o hello
  • -I:指定头文件所在目录位置 gcc hello.c -o hello -I ./inc
  • -c:只做预处理、编译、汇编,得到hello.o二进制文件 gcc -c ./src/hello.c -o ./obj/hello -I ./inc
  • -g:编译时添加调试语句,主要支持gdb调试 gcc hello.c -o hellog
  • -Wall:warning all,即显示所有警告信息
  • -D:向程序中“动态”注册宏定义 gcc hello.c -o hello4 -D HONG
  • l:指定动态库名
  • -L:指定动态库路径

程序库

简单来说,程序库是包含了数据和执行码的文件,本质是一组具有相似、相近功能函数的集合。可以作为其它执行程序的一部分来完成某些功能,但不能单独执行。程序库加快了程序的再编译,使得程序模块化并且便于升级。

程序库分为静态库共享库(又叫动态库),静态库是在可执行程序运行就已经加入到执行码中,成为执行程序的一部分,而共享库是在执行程序启动(且调用到了共享库中的“函数”时)加载到执行程序中,可以被多个执行程序共享使用。静态库文件名一般以lib开头,以.a结尾,动态库文件名一般以.so结尾。

静态库:(了解即可)

  • 机制:每个使用静态库的程序都要将整个静态库编译到可执行程序
  • 优点:库函数本地化,调用速度快
  • 缺点:消耗系统资源大
  • 使用场景:适合对空间要求较低,而对时间要求较高的核心程序中

动态库:(重点)

  • 机制:多个可执行程序共享一份库文件(共享代码、不共享数据)
  • 优点:节省内存、易于更新
  • 缺点:由于实现机制原因,较静态库函数调用相比速度慢
  • 使用场景:适合对时间要求较低,而对空间要求较高的程序中

静态库制作及使用步骤:

  1. 将 .c 生成 .o 二进制文件 gcc -c add.c -o add.o
  2. 使用 ar 工具制作静态库 ar rcs libmymath.a add.o sub.o div1.o
  3. 编译静态库到可执行文件中 gcc test.c libmymath.a -o test.out

但这样会存在函数的隐性声明警告,因为函数在.c程序中既没定义(在静态库中),也没声明。最好新建一个mymath.h头文件,并在.c程序中引入。

头文件守卫:防止头文件被重复包含

完整步骤(from xiaobing1016):

动态库制作及使用步骤:

  1. 将 .c 生成 .o 二进制文件 (与制作静态库不同,要生成与位置无关的代码,参数为-fPICgcc -c add.c -o add.o -fPIC
  2. 使用 gcc -shared选项制作动态库 gcc -shared -o libmymath.so add.o sub.o div1.o(注意这里的.o文件和制作静态库时不同,因为加了-fPIC
  3. 编译可执行程序时,指定所使用的动态库。选项 -l 指定库名(去掉lib前缀和.so后缀), -L指定库路径。 gcc test.c -o a.out -l mymath -L ./lib
  4. 运行可以执行程序 ./a.out

常见报错:./a.out: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory

原因: -l 和 -L 是给链接器用的,动态链接器找不到动态库的位置

  • 链接器:工作于链接阶段,工作时需要 -l-L
  • 动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置(报错原因)

解决方式:

  1. 临时生效:通过环境变量 export LD_LIBRARY_PATH=动态库路径(终端重启环境变量失效)
  2. 永久生效:将上述命令写入终端配置文件.bashrc,重启终端让修改后的.bashrc生效
  3. 拷贝自定义动态库到 /lib (标准C库所在目录位置)
  4. 配置文件法:1)sudo vi /etc/ld.so.conf 2) 写入动态库绝对路径 3)sudo ldconfig -v 使配置文件生效

动态库注意事项:

  • 动态库是否加载到了内存,取决于程序是否运行
  • 动态库每次加载的位置不固定
  • 动、静态库共存时,编译器默认使用动态库

完整步骤(from xiaobing1016)


数据段合并:


不准投币喔 👆

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇