cen's blog cen's blog
首页
  • 编程文章

    • markdown使用
  • 学习笔记

    • 《JavaScript教程》
    • C++学习
    • C++数据结构
    • MySQL
    • Linux
  • 高中时代
  • 工作日常
  • CLion
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

cen

十年饮冰,难凉热血
首页
  • 编程文章

    • markdown使用
  • 学习笔记

    • 《JavaScript教程》
    • C++学习
    • C++数据结构
    • MySQL
    • Linux
  • 高中时代
  • 工作日常
  • CLion
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • Linux环境搭建
  • 基本指令
  • 权限
  • Linux基础开发工具
    • 软件包管理器-yum
      • 查看软件包
      • 安装软件包
      • 卸载软件包
    • 编辑器-vim
      • 三种模式
      • 基本操作
      • 命令模式命令集
      • 底行模式命令集
      • 简单配置vim
    • 编译器-gcc/g++
      • gcc/g++语法
      • 过程
      • 动态库和静态库
    • 调试器-gdb
      • gdb使用须知
      • gdb命令集
    • 项目自动化构建工具-make/makefile
      • 引入
      • 依赖关系和依赖方法
      • 多文件编写
  • 进程概念
  • 进程控制
  • 基础IO流
  • 动态库和静态库
  • 进程通信
  • 进程信号
  • 多线程
  • 线程安全
  • Linux
cen
2025-02-10
目录

Linux基础开发工具

# 软件包管理器-yum

在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序。但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装。软件包和软件包管理器, 就好比 "App" 和 "应用商店" 这样的关系。yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器. 主要应用在Fedora, RedHat, Centos等发行版上。

# 查看软件包

yum list
1

示例搜索lrzsz

lrzsz.x86_64 0.12.20-36.el7 @base

  • 软件包名称: 主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构.
  • "x86_64" 后缀表示64位系统的安装包, "i686" 后缀表示32位系统安装包. 选择包时要和系统匹配.
  • "el7" 表示操作系统发行版的版本. "el7" 表示的是 centos7/redhat7. "el6" 表示 centos6/redhat6.
  • "base" 表示的是 "软件源" 的名称

# 安装软件包

yum install xxx
1

# 卸载软件包

yum remove xxx
1

# 编辑器-vim

vim/vi都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行,也可以运行于x window、 mac os、windows。

# 三种模式

vim的三种模式,分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下:

  • 正常/普通/命令模式(Normal) 控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode
  • 插入模式(Insert) 只有在Insert下,才可以做文字输入,按「ESC」键可回到命令行模式。
  • 末行模式(last line) 文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。

在命令模式下,shift + : 即可进入该模式。

要查看你的所有模式:打开vim,底行模式直接输入:help vim-modes

# 基本操作

  1. [正常模式]切换至[插入模式]:输入i/a/o
  2. [插入模式]切换至[正常模式]:Esc
  3. [正常模式]切换至[末行模式]:Shift + ; == :
  4. [末行模式]切换至[正常模式]:Esc
  5. 退出vim及保存文件:在[正常模式]下,进入[末行模式],再按 wq 即可退出并保存

# 命令模式命令集

【移动光标】

  1. 按「k」:光标上移。
  2. 按「j」:光标下移。
  3. 按「h」:光标左移。
  4. 按「l」:光标右移。
  5. 按「$」:移动到光标所在行的行尾。
  6. 按「^」:移动到光标所在行的行首。
  7. 按「gg」:移动到文本开始。
  8. 按「Shift + g」:移动到文本末尾。
  9. 按「n + Shift + g」:移动到第n行行首。
  10. 按「n + Enter」:当前光标向下移动n行。
  11. 按「w」:光标从左到右,从上到下的跳到下一个字的开头。
  12. 按「e」:光标从左到右,从上到下的跳到下一个字的结尾。
  13. 按「b」:光标从右到左,从下到上的跳到上一个字的开头

【删除】

  1. 按「x」:删除光标所在位置的字符。
  2. 按「nx」:删除光标所在位置开始往后的n个字符。
  3. 按「X」:删除光标所在位置的前一个字符。
  4. 按「nX」:删除光标所在位置的前n个字符。
  5. 按「dd」:删除光标所在行。
  6. 按「ndd」:删除光标所在行开始往下的n行。

【复制粘贴】

  1. 按「yy」:复制光标所在行到缓冲区。
  2. 按「nyy」:复制光标所在行开始往下的n行到缓冲区。
  3. 按「yw」:将光标所在位置开始到字尾的字符复制到缓冲区。
  4. 按「nyw」:将光标所在位置开始往后的n个字复制到缓冲区。
  5. 按「p」:将已复制的内容在光标的下一行粘贴上。
  6. 按「np」:将已复制的内容在光标的下一行粘贴n次。

【剪切】

  1. 按「dd」:剪切光标所在行。
  2. 按「ndd」:剪切光标所在行开始往下的n行。
  3. 按「p」:将已剪切的内容在光标的下一行粘贴上。
  4. 按「np」:将已剪切的内容在光标的下一行粘贴n次。

【撤销】

  1. 按「u」:撤销。
  2. 按「Ctrl + r」:恢复刚刚的撤销。

【大小写切换】

  1. 按「~」:完成光标所在位置字符的大小写切换。
  2. 按「n~」:完成光标所在位置开始往后的n个字符的大小写切换。

【替换】

  1. 按「r」:替换光标所在位置的字符。
  2. 按「R」:替换光标所到位置的字符,直到按下「Esc」键为止。

【更改】

  1. 按「cw」:将光标所在位置开始到字尾的字符删除,并进入插入模式。
  2. 按「cnw」:将光标所在位置开始往后的n个字删除,并进入插入模式。

【翻页】

  1. 按「Ctrl + b」:上翻一页。
  2. 按「Ctrl + f」:下翻一页。
  3. 按「Ctrl + u」:上翻半页。
  4. 按「Ctrl + d」:下翻半页。

# 底行模式命令集

【行号设置】

  1. 「set nu」:显示行号。
  2. 「set nonu」:取消行号。

【保存退出】

  1. 「w」:保存文件。
  2. 「q」:退出vim,如果无法离开vim,可在「q」后面跟一个「!」表示强制退出。
  3. 「wq」:保存退出。

【分屏指令】

  1. 「vs 文件名」:实现多文件的编辑。
  2. 「Ctrl + w + w」:在正常模式下光标在多屏幕下进行切换。

【执行指令】

  1. 「! + 指令」:在不退出vim的情况下,可以在指令前面加上「!」就可以执行Linux的指令,例如查看目录、编译当前代码等。

# 简单配置vim

在目录 /etc/ 下面,有个名为vimrc的文件,这是系统中公共的vim配置文件,对所有用户都有效。而在每个用户的主目录下,都可以自己建立私有的配置文件,命名为:.vimrc

  • /root目录下,通常已经存在一个.vimrc文件,如果不存在,则创建之。
  • 切换用户成为自己执行 su ,进入自己的主工作目录,执行 cd ~打开自己目录下的.vimrc文件,执行 vim .vimrc

常用配置选项,用来测试:

  • 设置语法高亮: syntax on
  • 显示行号: set nu
  • 设置缩进的空格数为4: set shiftwidth=4
  • ...

# 编译器-gcc/g++

gcc和g++分别是GNU的C和C++的编译器,gcc和g++在执行编译的时候一般有以下四个步骤:

  1. 预处理(头文件展开、去注释、宏替换、条件编译)
  2. 编译(C/C++代码翻译成汇编语言)
  3. 汇编(汇编代码转为二进制目标代码)
  4. 链接(将汇编过程产生的二进制代码进行链接)

# gcc/g++语法

语法:gcc/g++ 选项 文件

选项:

  1. -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
  2. -S 编译到汇编语言不进行汇编和链接
  3. -c 编译到目标代码
  4. -o 文件输出到文件
  5. -static 此选项对生成的文件采用静态链接
  6. -g 生成调试信息,GNU调试器可利用该信息
  7. -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库
  8. -w 不生成任何警告信息。
  9. -Wall 生成所有警告信息

# 过程

预处理:

gcc -E test.c -o test.i

  • -E选项的作用是让gcc/g++在预处理结束后停止编译过程
  • -o选项是指目标文件,xxx.i文件为已经过预处理的原始程序

编译:

gcc -S test.i -o test.s

  • 用户可以使用-S选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码
  • -o选项是指目标文件,xxx.s文件为已经过翻译的原始程序

汇编:

gcc -c test.s -o test.o

  • 汇编阶段是把编译阶段生成的xxx.s文件转成目标文件
  • 使用-c选项就可以得到汇编代码转化为xxx.o的二进制目标代码了

链接:

gcc test.o -o test

  • gcc/g++不带-E、-S、-c选项时,就默认生成预处理、编译、汇编、链接全过程后的文件
  • 若不用-o选项指定生成文件的文件名,则默认生成的可执行文件名为a.out

链接的本质:我们调用库函数的手如何与标准库链接的?

# 动态库和静态库

  • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也 就不再需要库文件了。其后缀名一般为“.a”
  • 动态库在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时 链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态 库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件。 gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证

动态链接:优点:省空间(磁盘的空间,内存的空间),bin体积小,加载速度快;缺点:依赖动态库,程序可移植性较差。

静态链接:优点:不依赖第三方库,程序的可移植性较高;缺点:浪费空间。

# 调试器-gdb

# gdb使用须知

程序发布方式:  1、debug版本:程序本身会被加入更多的调试信息,以便于进行调试。  2、release版本:不会添加任何调试信息,是不可调试的。

# gdb命令集

【进入gdb】

指令:gdb 文件名

【调试】

  1. 「run/r」:运行代码(启动调试)。
  2. 「next/n」:逐过程调试。
  3. 「step/s」:逐语句调试。
  4. 「until 行号」:跳转至指定行。
  5. 「finish」:执行完当前正在调用的函数后停下来(不能是主函数)。
  6. 「continue/c」:运行到下一个断点处。
  7. 「set var 变量=x」:修改变量的值为x。

【显示】

  1. 「list/l n」:显示从第n行开始的源代码,每次显示10行,若n未给出则默认从上次的位置往下显示.。
  2. 「list/l 函数名」:显示该函数的源代码。
  3. 「print/p 变量」:打印变量的值。
  4. 「print/p &变量」:打印变量的地址。
  5. 「print/p 表达式」:打印表达式的值,通过表达式可以修改变量的值。
  6. 「display 变量」:将变量加入常显示(每次停下来都显示它的值)。
  7. 「display &变量」:将变量的地址加入常显示。
  8. 「undisplay 编号」:取消指定编号变量的常显示。
  9. 「bt」:查看各级函数调用及参数。
  10. 「info/i locals」:查看当前栈帧当中局部变量的值。

【断点】

  1. 「break/b n」:在第n行设置断点。
  2. 「break/b 函数名」:在某函数体内第一行设置断点。
  3. 「info breakpoint/b」:查看已打断点信息。
  4. 「delete/d 编号」:删除指定编号的断点。
  5. 「disable 编号」:禁用指定编号的断点。
  6. 「enable 编号」:启用指定编号的断点。

【退出gdb】

  1. 「quit/q」:退出gdb。

# 项目自动化构建工具-make/makefile

# 引入

会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂 的功能操作。 makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编 译,极大的提高了软件开发的效率。

make是一个命令工具,是一个解释makefile中指令的命令工具。

make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

# 依赖关系和依赖方法

  1. 依赖关系: 文件A的变更会影响到文件B,那么就称文件B依赖于文件A。

例如,test.o文件是由test.c文件通过预处理、编译以及汇编之后生成的文件,所以test.c文件的改变会影响test.o,所以说test.o文件依赖于test.c文件。

  1. 依赖方法: 如果文件B依赖于文件A,那么通过文件A得到文件B的方法,就是文件B依赖于文件A的依赖方法。

例如,test.o依赖于test.c,而test.c通过gcc -c test.c -o test.o指令就可以得到test.o,那么test.o依赖于test.c的依赖方法就是gcc -c test.c -o test.o

# 多文件编写

例如,编写一个进度条小程序:

.
├── Makefile
├── progress
├── progress.cpp
├── progress.h
└── test.cpp
1
2
3
4
5
6

Makefile文件:

test:test.cpp progress.cpp
	g++ -o progress test.cpp progress.cpp       # 不需要头文件
.PHONY:clean
clean:
	rm -rf progress
1
2
3
4
5

progress.cpp文件:

#include"progress.h"

#include <iostream>
#include <iomanip>
#include <chrono>
#include <thread>
#include <string>

void progresson() {
    const int totalSteps = 100;
    std::string proc(totalSteps, ' ');
    const std::string symbols = "\\|/-";
    for (int i = 0; i <= totalSteps; ++i) {
        proc[i] = '#';
        std::cout << "[" << proc << "]" << "[" << std::setw(3) << i << "%]" << "[" << symbols[i % 4] << "]\r" << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(60));
    }
    std::cout << std::endl;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
上次更新: 2025/03/01, 15:31:03
权限
进程概念

← 权限 进程概念→

最近更新
01
线程安全
05-21
02
cmake教程
05-08
03
项目
05-07
更多文章>
Theme by Vdoing | Copyright © 2024-2025 京ICP备2020044002号-3 京公网安备11010502056119号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式