当前位置: 首页 > news >正文

C++ (week4):Linux基础

文章目录

    • 零、Linux简介
      • 1.配置环境
      • 2.Linux历史
      • 3.Linux模型
    • 一、vim
    • 二、Linux命令行 (shell命令)
      • 1.常用命令与快捷键
        • (1)常用命令
          • ①man命令:查看帮助手册
        • (2)快捷键
      • 2.用户子系统
        • (1)Linux用户
        • (2)用户命令
      • 3.文件子系统命令
      • (1)目录命令
        • 1.创建文件:mkdir
        • 2.删除目录:rmdir
        • 3.打印当前工作目录:pwd
        • 4.切换当前工作目录:cd
        • 5.复制:cp
        • 6.重命名/移动文件:mv
        • 7.删除文件和目录:rm
        • 8.查看文件的目录项:ls
        • 9.查看文件和目录所占用的磁盘空间:du
        • 10.列出文件目录项结构:tree
        • 11.别名:alias
      • (2)文件命令
        • 1.创建文件:echo、touch、vim
        • 2.查找文件:which
        • 3.查找文件:find
        • 4.查看文件内容/拼接文件:cat
        • 5.查看文件的前几行:head
        • 6.查看文件的后几行:tail
        • 7.分页浏览:more、less
        • 8.搜索文件内容:grep
        • 9.单词统计:wc (word count)
        • 10.命令的组合:3种
          • (1)多命令 `;`
          • (2)管道(pipe) `|`
          • (3)xargs:将cmd1输出的每一行,作为cmd2的命令行参数
        • 11.文件的权限:`chmod` (change mode)
        • 12.文件创建掩码:umask
        • 13.链接:硬链接和符号链接
        • 14.远程复制:`scp`
        • 15.打包和压缩:`tar` (text archive)
      • (3)通配符、正则表达式、重定向
    • 三、编译工具链
      • 1.编译
        • (1)下生成可执行程序的整个过程
        • (2)对应的 gcc 命令如下
        • (3)条件编译
      • 2.GDB调试
        • (1)调试程序
        • (2)coredump文件 (核心转储)
      • 3.Makefile
        • 6.完整的Makefile / makefile
        • 7.非常通用的Makefile模板
      • 4.库文件
        • (1)静态库
        • (2)动态库
        • (3)库的生成
    • 四、其他
      • 1.修改代码模板:snippet.c
      • 2.小知识储备

零、Linux简介

1.配置环境

0.安装unbuntu

1.静态IP地址:手动设置ip地址
instal net-tools


2.设置远程连接
网络协议SSH

sudo apt install ssh

3.安装vimplus


4.关闭主机前,先关闭虚拟机。否则会虚拟机损坏。


5.设置快照

6.daemon 守护进程 / 也是虚拟光驱软件

7.Linux哲学:
①一切皆文件
②没有消息就是最好的消息 (一般显示的消息是报错)


2.Linux历史

Unix → M → Linux


3.Linux模型

1.内核(Kernel):
①管理硬件资源:CPU(进程调度)、内存(内存管理)、外部设备(文件管理、网络通信、设备驱动)
②对上层应用程序提供接口(API),即系统调用

2.系统调用(System calls):内核给上层应用程序提供的接口

3.库函数(library function):对系统调用的包装,①方便使用 ②可移植性(不同操作系统的底层系统调用是不同的)

4.shell:命令行解释器
shell 是一个命令行解释器,它读取用户输入,然后执行命令,然后等待用户的下一
次输入

for(;;) {read(cmd);execute(cmd);
}

命令:一般来说,就是一些简单的可执行程序。
脚本:命令的集合

在这里插入图片描述



一、vim

1.理念:
①组合
②简单、快捷

2.vim是多模式编辑器
①普通模式/命令模式 (NORMAL):查看代码,最常待的模式
②编辑模式/插入模式 (INSERT):编辑文本
③视图模式 (VISUAL / V-BLOCK):v 行选,crtl + v 列选

在这里插入图片描述


3.NORMAL模式命令
①短命令:a,i,A,I,o,O,v, crtl+v
②底部命令:以:开头,以[Enter]结尾, :wq
③其他模式按[Esc]返回NORMAL模式

4.移动光标 (motion)

命令含义
j
k
h
l
i在光标前面插入
I在行首插入
a在光标后面插入
A在行尾插入
o下面另起一行,在行首插入
O上面另起一行,在行首插入
[n]-上移n行
[n]+下移n行
[n]G移动到第n行
:n移动到第n行
gg文首
G文末
0跳到行首
^本行第一个非空白字符
$行尾
w下一个单词的词首
W下一个词的词首,以空白字符分割
b上一个单词的词首
B上一个词的词首,以空白字符分割
t往后查找,光标置于该字符的前一个字符
T往上查找,光标置于该字符的后一个字符
f向后查找,光标置于该字符
F向前查找,光标置于该字符
x删除一个字符
X删除前一个字符
r替换一个字符

5.文本对象 (text object)
删除双引号内:ci"“,ca”"
ap (paragraph):整段,以空行为分割

①复制整段:yap
②删除整段:dapcip

在这里插入图片描述

a (all):包括边界
i (inside):不包括边界

在这里插入图片描述


6.动作 (action)
d (delete) 删除
y (yank) 复制
c (change) 删除并进入编辑模式
c change模式,直接进入插入模式
gcc:注释/取消注释


7.组合
(1)action + motion
dw、d$、d0
cgg:光标删除到文首,并进入插入模式
cw:删除后面的单词,并进入插入模式

(2)n命令:某个命令做n次

(3)action + text object


8.撤销与恢复
u (undo):撤销
[crtl] + r (recovery):恢复
p:向后粘贴
P:向前粘贴
yy:复制

多个历史版本,两个栈实现前进后退


9.查找与替换
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


10.视图模式
选择范围,为了后面复制或删除

批量注释:ctrl + v ,选择范围,按gc


11.最小前缀原则:唯一识别,只写部分前缀即可。或者别名。
:w 就是 :write的缩写,保存(内存写回磁盘)。也可写:wri
:q 就是 :q的缩写,:q!是强制退出
:wq 是 保存并退出


12.多窗口 / 分屏
:sp:水平分屏
:vsp:垂直分屏
:q 退出当前窗口
:only 除了当前窗口,退出其他窗口
:w 保存
在这里插入图片描述


13.配置vim
①配置文件:.vimrc (是一个脚本,rc是running command)
②安装vimplus
③再单独装ycm (you complete me)

rm  -rf ~/.vim/plugged/YouCompleteMe
sudo apt install vim-youcompleteme
vim-addons install youcompleteme



二、Linux命令行 (shell命令)

1.常用命令与快捷键

(1)常用命令
命令含义
clear清屏
touch创建文件
ls -a全部显示,包括.开头的隐藏文件
rm清除,rm * -rf
echo “I love xixi”> b.txt写入文件
cat 文件名 (cat main.c)查看文件内容
执行程序gcc main.c -o main
./main
shutdown命令关机命令
reboot重启
man 命令名manual手册,解释该命令 (be a man!)
gg = G全文对齐
env查看环境变量

gcc:gnu c compiler


①man命令:查看帮助手册

1.man手册看哪些部分? (一手资料):
在这里插入图片描述


2.man手册的快捷键:
(1)翻页
↑、↓、f、b、d、u

↓:往下一行
d(down):往下翻半页
f(forward):往下翻一页
↑:往上一行
u(up):往上翻半页
b(backward):往上翻一页

(2)查找:/内容
查找下一个:n
查找上一个:N

(3)退出:q


3.man手册的数值的含义
①shell命令
②系统调用
③库函数

在这里插入图片描述

man 3 rmdir

4.man手册 (manual)
短选项:命令行
长选项:shell脚本


(2)快捷键
快捷键功能
Tab联想,命令补全
上一条命令
Ctrl + A将光标移动到最前面
Ctrl + E将光标移动到最后面

2.用户子系统

(1)Linux用户

(1)root:根用户,超级用户
(2)sudoers:管理员用户。安装ubuntu时,创建的用户默认为sudoers。sudoers可以使用sudo命令临时提升权限为root
(3)普通用户


(2)用户命令

(1)创建用户 useradd
(2)删除用户 userdel

sudo userdel 用户名 -r   #加-r,不仅删除用户,还将用户主目录中的文件和用户邮箱一起删除

(3)设置密码、修改用户密码 passwd

sudo passwd 用户名

(4)切换用户 su
(5)退出切换 exit


例题:

(填写执行的命令即可)
a. 创建 test1 用户,指定 test1 用户的 login shell 为 /bin/bash, 并给他创建家目录。
b. 将 test1 用户的密码修改为 123456 (或其它任意密码)
c. 切换到 test1 用户
d. 退出切换
e. 将 test1 用户删除,家目录也一起删除

a.sudo useradd test1 -m -s /bin/bash
b.sudo passwd test1123123
c.sudo su test1
d.exit
e.sudo userdel test1 -r



3.文件子系统命令

1.目录结构
根目录 /
bin:binary,可执行程序或脚本文件
sys:system,系统相关文件
dev:device,设备文件
proc:process,进程相关的数据
var:variable,经常发生变化的文件,比如日志文件
lib:库文件
root:超级用户
home:家目录,下面是普通用户
etc:存放配置文件和启动脚本
①passwd:man 5 passwd
②shadow:man 5 shadow

etc/passwd:存放账号
etc/shadow:存放密码

在这里插入图片描述

在这里插入图片描述


(1)目录命令

1.创建文件:mkdir

mkdir - p 创建文件 (-p是级联创建)

在这里插入图片描述


2.删除目录:rmdir

rmdir -p 删除空目录 (-p是级联删除)


3.打印当前工作目录:pwd

4.切换当前工作目录:cd

①. 当前目录
②… 上级目录
③/ 根目录
④~ 家目录
- 上次目录,环境变量 OLDPWD

cd 是 change directory


5.复制:cp

(1)常用格式

cp src des			 #复制文件
cp -r src des	     #递归复制目录
cp src1 src2 .. des  #拷贝多个文件到目标目录

(2)常用选项
-r:递归
-n:不覆盖 (des不存在,则创建。若存在,则不复制)
-i :交互询问

在这里插入图片描述
在这里插入图片描述


6.重命名/移动文件:mv

(1)常用格式
①重命名
mv会默认覆盖同名文件,

mv 文件名1 文件名2

inode不变

虚拟文件系统
在这里插入图片描述

②移动文件

mv 文件名 目录名

(2)常用选项
-n:不覆盖
-i:交互式


7.删除文件和目录:rm

rm(remove)命令可以删除文件和目录。

rm -rf dir

①rm -r 递归删除 (-r 是recursively,递归地)
②-i:交互式
③-f:force,强制执行,不给提示。-f 强制,不给消息。有些用户不想看消息,不想交互,就用-f,默默地强制执行。


8.查看文件的目录项:ls

ls -l:查看目录项
(1)常用选项
①-l:长格式,详细信息
②ls -a:显示所有内容,包括 .和…、隐藏文件
③-h:人类可读的
④-i:物理inode编号

(2)读写权限
①可执行程序:775 rwx rwx r-x (八进制,r w x 分别值为4 2 1 )
②普通文件:664 rw- rw- r–
③7列:九个字符(三组)表示权限、硬链接数、拥有者、拥有组、文件大小、最近修改时间、文件名
在这里插入图片描述

ls 目录名  #显示指定目录的内容

9.查看文件和目录所占用的磁盘空间:du

du是 disk usage 的缩写。
当使用ls -lih时,目录大小永远只显示4K,而无法递归地显示目录的真实大小,这时候就要使用du命令。

du -sh 路径

在这里插入图片描述


10.列出文件目录项结构:tree

11.别名:alias

①查看别名:alias
②设置别名:alias h=‘history’

在这里插入图片描述


(2)文件命令

1.创建文件:echo、touch、vim

echo:输入简短内容,不存在则创建,已存在则覆盖。echo "hello Linus" > a.txt"
touch:文件存在,修改时间戳;文件不存在,创建空文件
vim:编辑文件

在这里插入图片描述


2.查找文件:which

which:查找文件 (查找可执行程序,即查找命令)

which 可执行程序名 
which 可执行程序名  -a (遍历完PATH)

which是通过PATH环境变量,查找目录路径


3.查找文件:find

3.find:查找文件 (在目录中递归地查找)

find . -name "a.txt"

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
根据时间查找

-mtime 1   #1到2天内
-mtime +1  #2天前
-mtime -1  #0到1天内

在这里插入图片描述

在这里插入图片描述


4.查看文件内容/拼接文件:cat

4.cat
①看文件内容
cat -n 带行号

②拼接文件: cat text1 text2 > text3


5.查看文件的前几行:head
head -n 5   #只查看前5行
head -n -5  #除了后5行,都显示

6.查看文件的后几行:tail
tail -n 5
tail -n +5
tail -F      #实时显示文件追加的内容(如日志文件)

在这里插入图片描述


7.分页浏览:more、less

1.more:分页浏览
b、f或空格翻页

2.less:分页浏览 (more的升级版)
可以上下滚轮


8.搜索文件内容:grep

grep (globally search for a regular expression)命令可以用于搜索文件内容

grep -nE "pattern" 文件名

①-E:扩展功能(建议都加)
②-n:行号
③-i:忽略大小写
④-c:显示匹配了多少行的数量

在这里插入图片描述



例题:
搜索 Linux 内核源码中,包含调用 exit 函数的所有行。

grep -nE "\<exit\(.*\)" linux-6.9 -r 	#问题: *会多匹配内容,遇到)不结束
grep -nE "\<exit\([^)]*\)" linux-6.9 -r #问题:[^)]在遇到第一个)就结束。但是 exit() 的()中可能还有()


9.单词统计:wc (word count)
wc 文件名

行数 单词数 字节数 文件名

wc -l :统计行数


10.命令的组合:3种
(1)多命令 ;
cmd1 ; cmd2

先执行cmd1,再执行cmd2。如:mkdir dir ; cd dir


(2)管道(pipe) |

1.管道:cmd1的输出 作为 cmd2的输入

cmd1 | cmd2

2.原理:将cmd1的stdout 重定向 到 管道的写端,将cmd2的stdin 重定向 到 管道的读端
在这里插入图片描述

3.示例

history | wc -l  #得到1000

在这里插入图片描述


(3)xargs:将cmd1输出的每一行,作为cmd2的命令行参数

(1)格式

cmd1 | xargs cmd2

(2)原理:
①将cmd1的stdout 重定向 到 管道的写端,将cmd2的stdin 重定向 到 管道的读端
②xargs将stdin里的每一行 作为 命令行参数

在这里插入图片描述

(3)示例

find . -name "*.c" | xargs grep -nE "\<main\("

在这里插入图片描述


11.文件的权限:chmod (change mode)

目录:
r:查看目录项 (ls、tree)
w:添加和删除目录项
x:目录最基本的权限。若没有x权限,则不能r和w。不能cd到该目录。

在这里插入图片描述

(1)模型
目录文件的模型:

目录项以链表互相连接

在这里插入图片描述


(2)命令
①文字设定法: chmod [ugoa][±-][rwx] filename
②数字设定法: chmod mode filename

chmod 755 client	//数字设定法
chmod 664 a.txt	    //数字设定法
chmod a+x hello.py  //文字设定法

在这里插入图片描述


12.文件创建掩码:umask

想去掉的权限
在这里插入图片描述


13.链接:硬链接和符号链接

(1)硬链接 (hard link):
①原理:
i.共享inode结点
ii.引用计数。每增加一个硬链接,引用计数+1,引用计数为0才会真正删除文件。修改任意一个文件的内容,所有共享引用计数的文件内容都会改变。
②命令:ln (link)
③格式也是 - ,普通文件

ln a.txt link_a

在这里插入图片描述


(2)符号链接 /软连接 (symbolic link):
①命令:ln -s
②可以指向一个不存在的文件,大小为指向的路径名
③格式是 l
④类似C语言的指针、Windows的快捷方式。除了rm命令,符号链接可以解引用,修改软连接的内容,原内容也会修改。

ln -s b.txt link_b

在这里插入图片描述
在这里插入图片描述


14.远程复制:scp

上传:将本地的文件复制到远程
下载:将远程的文件复制到本地

远程路径:用户名@IP:绝对路径
递归复制目录要加 -r

在这里插入图片描述


scp ./file  edward@192.168.248.136:~/MyCode/cpp58/Linux/Linux04

在这里插入图片描述

非常实用,以后互相传文件不需要通过微信了。windows给ubuntu传文件也不需要通过WinSCP了。


15.打包和压缩:tar (text archive)

(1)选项,不加- (vf常用)
c:打包(创建包裹),默认包裹名结尾 .tar
r:追加
tvf 查看包裹内容
x:解打包
z,即使用gzip算法进行压缩或解压缩。默认文件结尾 .tar.gz

tar xvf linux-6.9.tar.xz   #解压命令

在这里插入图片描述
在这里插入图片描述

若是.zip,需要使用unzip 包裹名命令


(3)通配符、正则表达式、重定向

1.通配符匹配文件名字
*:匹配任意多个字符 (0-n个)
?:匹配任意一个字符
集合/类:[cha]匹配集合内任意一个字符,[!cha]匹配集合外任意一个字符

例如:[abc]、[0-9]、[0-9a-zA-z_]、[!0-9a-zA-z_]


2.正则表达式匹配文件内容
(1)基本单位:
①普通字符
②转义字符
.:匹配任意一个字符
④集合:[abc]
⑤group:(abc)

在这里插入图片描述

(2)基本操作:
①连接:
在这里插入图片描述

②重复:前一个基本单位重复的次数
在这里插入图片描述
在这里插入图片描述

(3)指定基本单位出现的位置
^:行首,“^abc”
$:行尾,“xyz$”
\<:词首
\>:词尾


[^abc]:匹配除了 “a”、“b”、和 “c” 之外的任何单个字符
.*:任意字符,重复任意次


3.重定向 >
在这里插入图片描述


三、编译工具链

前面我们写程序的时候用的都是集成开发环境 (IDE: Integrated Development
Environment),集成开发环境可以极大地方便我们程序员编写程序,但是配置起来也
相对麻烦。在 Linux 环境下,我们用的是编译工具链,又叫软件开发工具包(SDK:
Software Development Kit)。Linux 环境下常见的编译工具链有:GCC 和 Clang,我
们使用的是 GCC。

1.编译

gcc、g++分别是 gnu 下的 c 和 c++ 编译器。

$ sudo apt install gcc gdb g++  #安装gcc和gdb
$ gcc -v 					    #查看gcc的版本
(1)下生成可执行程序的整个过程

在这里插入图片描述


(2)对应的 gcc 命令如下
gcc -E hello.c -o hello.i    #-E 预处理,生成 预处理后的文件
gcc -S hello.c -o hello.s	 #-S 预处理+编译,生成 汇编代码
gcc -c hello.c -o hello.o	 #-c 预处理+编译+汇编,生成 目标文件
gcc    hello.c -o hello		 #什么都不加,生成 可执行程序
gcc    hello.c -o hello -l库名	 #-l 链接库	
选项含义
-Wall生成所有警告信息 (warning all)
-g调试
-Dmacro相当于在文件开头加上了 #define macro
-Dmacro=value相当于在文件开头加上了 #define macro value
Idir指定#include头文件的优先查找的目录,找不到再到当前目录、系统的include目录查找
-O0,-O1,-O2,-O3-O0不优化(开发环境),-O1和-O2(生产环境),-O3是激进的优化策略(一般不使用),Optimize

(3)条件编译

1.条件编译的3种预处理指令:
在这里插入图片描述

#if

#if 常量表达式
...
#endif

(2)#if defined(macro)

#if defined(DEBUG)
...
#endif

#ifdef (是上文的语法糖)

#ifdef DEBUG
...
#endif

#ifndef

#ifndef 标识符
...
#endif

2.条件编译的作用/适用场景:
(1)编写可移植的代码:

#ifdef WIN32
...Windows的代码块
#elif MAC_OS
...
#elif LINUX
...
#endif

在这里插入图片描述


(2)为宏提供默认定义
我们可以检测一个宏是否被定义了,如果没有,则提供一个默认的定义:

#ifndef MAXSIZE
#define MAXSIZE 4096
...
#endif

(3)避免头文件重复包含
第一次碰到该宏,会定义该宏,并执行代码块。
第二次碰到该宏,因为已经定义过该宏,会跳过代码块。
宏的命名就是为了标识该头文件。

#ifndef __WD_FOO_H   //若没有定义过该宏,则定义该宏
#define __WD_FOO_H	//下次再碰到,就已经定义了该宏,会直接跳过
...
#endif
#ifndef _HELLO_H_
#define _HELLO_H_
...
#endif

在这里插入图片描述

(4)调试程序:临时屏蔽包含注释的代码

在这里插入图片描述


2.GDB调试

1.观念:调试程序的难度是写程序的两倍
2.调试程序的步骤:调试程序要 [走一走,停一停,看一看]。看程序的状态是否和预期的一致。(调试程序之前,一定要有预期)
若不一致:
i.预期错了:加深对问题的理解
ii.程序错了:线索,指向真正出错的地方


(1)调试程序

0.记得加-g选项,才能gdb。否则会显示没有符号表(no symbol table)被读取。请使用 "file" 命令。

gcc hello.c -o hello -g [-Wall]

1.进入GDB调试界面的两种方式

gdb executable_name 				 #不设置任何命令行参数
gdb --args executable_name arg1 arg2 ...  #设置命令行参数

2.查看源代码 list,但是更建议再开一个窗口用vim

2.设置命令行参数

(gdb) set args arg1 arg2 ...

3.打断点:break/b n

(gdb) break 20 # 在第20行设置断点
(gdb) break main # 在main函数的开头设置断点
(gdb) break scanner.c:20 # 在scanner.c文件的第20行设置断点
(gdb) break scanner.c:scanToken # 在scanner.c文件的scanToken函数开头设置断点

4.查看断点:info break/ i b

5.删除断点:delete 断点编号

(gdb) delete 2 	#删除2号断点
(gdb) d 		#删除所有断点

6.执行程序:run/r

7.逐过程/步过:next/n
遇到函数调用,它不会进入函数,而是把函数调用看作一条语句。

8.单步调试 (逐语句/步入):step/s
遇到函数调用,会进入函数里面

9.跳出函数(步出):finish
执行完当前被调函数,回到主调函数。(原理:执行完栈顶的栈帧,并出栈,然后停下)

10.继续:continue/c
执行到逻辑上的下一个断点

11.忽略断点:ignore
我们可以用 ignore 命令来指定忽略某个断点多少次,这在调试循环的时候非常有用:

格式: ignore N COUNT
常见用法: ignore 1 10   #忽略1号断点10次

在这里插入图片描述

12.退出GDB界面:qiut/q


看一看 [查看程序的状态]:print EXP、display EXP、info display、undisplay 编号、backtrace、frame 栈帧编号、info args、info locals、info registers

13.监视
(1)打印表达式的值:print/p 表达式

print/p EXP
print/p EXP=value

(2)自动展示表达式的值:display

display EXP 	#自动展示EXP
info display 	#显示所有自动展示的表达式信息
undisplay [n] 	#删除所有或[n]号自动展示的表达式

14.查看内存

x/4xb arr+5
x/1dw arr+5   #查看值
x/10dw arr    #数组的值

在这里插入图片描述

15.GDB帮助手册:help 要查看的命令


(2)coredump文件 (核心转储)

1.core文件:
(1)是什么:程序异常终止时的运行状态的快照 (程序及内存)
(2)为什么需要,作用:一定能实现错误复现,因为core文件保存了当时内存崩溃的场景,core文件可以恢复场景。

多线程的错误很难还原,在生产环境下的程序,可能每次运行结果都不同。不一定能复现,而core文件就可以用来复现错误

2.开启生成core文件
(1)查看系统是否允许生成Coredump文件

$ ulimit -a				#查看
...
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
...
$ ulimit -c unlimited 	#将core文件的大小临时设置为不受限制

(2)设置Coredump文件的格式

$ sudo vim /etc/sysctl.conf kernel.core_pattern = %e_core_%s_%t 	#%e:executable-name,%s:signal,%t:timestamp
$ sudo sysctl -p 						#让配置生效

(3)使用Coredump文件调试程序
①查看信号异常终止的数字对应的宏:kill -l (list)
②用GDB查看core文件,复现错误

$ gcc test.c -o test -g # 生成可执行程序test
$ ./test # 运行test
#报错了,并生成了core文件,可使用ls命令查看生产的core文件名
$ gdb test test_core_8_1679196427 # 使用Coredump文件调试程序:gdb 可执行程序名 core文件名

③查看栈:backtrace/bt
在这里插入图片描述
④查看栈帧:frame n
⑤查看传递的参数的值:info args
⑥查看局部变量的值:lnfo locals
⑦查看寄存器的 值:info registers

普通GDB也可以查看 info args、info locals,并不一定需要有core文件


3.Makefile

1.Makefile是什么 (what)
Makefile:脚本文件
make工具:解释并执行Makefile

在这里插入图片描述


2.Makefile的作用 (why)
(1)自动编译:写好 Makefile 之后,输入一个 make命令就可以构建整个项目了,自动进行编译。
(2)增量编译:Makefile只编译新增的和修改过的.c文件 (-c生成.o文件)

不需要全量编译,全量编译需要若干个小时。
编译很慢,链接很快。核心是.o目标文件

在这里插入图片描述


3.书写Makefile (how)
特点:Makefile的语法要求非常严格

main: main.o add.o sub.o mul.o div.ogcc main.o add.o sub.o mul.o div.o -o main
main.o: main.c algs.hgcc -c main.c -Wall -g
add.o: add.c algs.hgcc -c add.c  -Wall -g
sub.o: sub.c algs.hgcc -c sub.c  -Wall -g
mul.o: mul.c algs.hgcc -c mul.c  -Wall -g
div.o: div.c algs.hgcc -c div.c  -Wall -g

规则:目标,依赖,命令

在这里插入图片描述


4.Makefile的工作原理:
(1)通过有向无环图(DAG)来管理依赖
make [目标],若不指定目标,则自动选择第一个target作为目标。
make 伪目标,才会走.PHONY里的

在这里插入图片描述

(2)拓扑排序
①保证了依赖关系
②使用DFS,对DAG进行拓扑排序

在这里插入图片描述


5.伪目标
每次都能执行的命令,但不生成文件

.PHONY: clean rebuild	#一定执行
clean:rm -rf *.o amin
rebuild: clean main

在这里插入图片描述


6.完整的Makefile / makefile
main: main.o add.o sub.o mul.o div.ogcc main.o add.o sub.o mul.o div.o -o main
main.o: main.c algs.hgcc -c main.c -Wall -g
add.o: add.c algs.hgcc -c add.c -Wall -g
sub.o: sub.c algs.hgcc -c sub.c -Wall -g
mul.o: mul.c algs.hgcc -c mul.c -Wall -g
div.o: div.c algs.hgcc -c div.c -Wall -g.PHONY: clean rebuild
clean:rm -f main main.o add.o sub.o mul.o div.o
rebuild: clean main

其对应的源码:

// algs.h
#ifndef __WD_ALGS_H
#define __WD_ALGS_Hint add(int, int);
int sub(int, int);
int mul(int, int);
int div(int, int);#endif
// add.c
#include "algs.h"int add(int a, int b) {return a + b;
}
// sub.c
#include "algs.h"int sub(int a, int b) {return a - b;
}
// mul.c
#include "algs.h"int mul(int a, int b) {return a * b;
}
// div.c
#include "algs.h"int div(int a, int b) {return a / b;
}
// main.c
#include "algs.h"
#include <stdio.h>int main(int argc, char* argv[])
{printf("add(7,3) = %d\n", add(7,3));printf("sub(7,3) = %d\n", sub(7,3));printf("mul(7,3) = %d\n", mul(7,3));printf("div(7,3) = %d\n", div(7,3));return 0;
}


使用Makefile编写shell脚本:
make、make clean、make build

test: test.ogcc test.c -o test	#编译链接./test				#执行程序.PHONY: clean rebuild
clean:rm test test.o 
rebuild: clean test


7.非常通用的Makefile模板
Srcs := $(wildcard *.c)
Outs := $(patsubst %.c, %, $(Srcs))CC := gcc
CFLAGS = -Wall -g -pthreadALL: $(Outs) %: %.c$(CC) $< -o $@ $(CFLAGS).PHONY: clean rebuild ALLclean:$(RM) $(Outs)
rebuild: clean ALL

8.变量
(1)变量在声明时需要赋初始值;使用时,需要给在变量名前加上$符号,如果变量名包含
多个字符,我们应该用小括号 () 或大括号 {} 把变量括起来。

(2)使用变量,改写上文的Makefile

Objs := main.o add.o sub.o mul.o div.o
Out := main$(Out): $(Objs)gcc $(Objs) -o $(Out)
main.o: main.c algs.hgcc -c main.c -Wall -g
add.o: add.c algs.hgcc -c add.c -Wall -g
sub.o: sub.c algs.hgcc -c sub.c -Wall -g
mul.o: mul.c algs.hgcc -c mul.c -Wall -g
div.o: div.c algs.hgcc -c div.c -Wall -g.PHONY: clean rebuild
clean:rm -f $(Out) $(Objs)
rebuild: clean $(Out)

(3)预定义变量
在这里插入图片描述

使用预定义变量,改写上文的Makefile

Objs := main.o add.o sub.o mul.o div.o
Out := main
CC := gcc
CFLAGS := -Wall -g$(Out): $(Objs)$(CC) $(Objs) -o $(Out)
main.o: main.c algs.h$(CC) -c main.c $(CFLAGS)
add.o: add.c algs.h$(CC) -c add.c $(CFLAGS)
sub.o: sub.c algs.h$(CC) -c sub.c $(CFLAGS)
mul.o: mul.c algs.h$(CC) -c mul.c $(CFLAGS)
div.o: div.c algs.h$(CC) -c div.c $(CFLAGS).PHONY: clean rebuild
clean:$(RM) $(Out) $(Objs)
rebuild: clean $(Out)

(4)规则中的特殊变量
在这里插入图片描述
引入自动变量后,我们可以将上面的 Makefile 改写成:

Objs := main.o add.o sub.o mul.o div.o
Out := main
CC := gcc
CFLAGS := -Wall -g$(Out): $(Objs)$(CC) $^ -o $@ 
main.o: main.c algs.h$(CC) -c $< $(CFLAGS)
add.o: add.c algs.h$(CC) -c $< $(CFLAGS)
sub.o: sub.c algs.h$(CC) -c $< $(CFLAGS)
mul.o: mul.c algs.h$(CC) -c $< $(CFLAGS)
div.o: div.c algs.h$(CC) -c $< $(CFLAGS).PHONY: clean rebuild
clean:$(RM) $(Out) $(Objs)
rebuild: clean $(Out)

9.模式规则
模式规则"%.o : %.c",表示的含义是:所有的.o文件依赖于对应的.c文件。
下面示例就是 Makefile 的一个模式规则,由所有的.c文件生成对应的.o文件:

%.o: %.c$(CC) -c $< -o $@

有了模式规则后,我们可以这样写 Makefile:

Objs := main.o add.o sub.o mul.o div.o
Out := main
CC := gcc
CFLAGS := -Wall -g$(Out): $(Objs)  #Objs := main.o add.o sub.o mul.o
div.o$(CC) $^ -o $@
%.o: %.c algs.h  #这里应用了Makefile的隐式推导,%.o是与上一个规则的依赖进行匹配,即$(Objs)$(CC) -c $< $(CFLAGS).PHONY: clean rebuild
clean:$(RM) $(Out) $(Objs)
rebuild: clean $(Out)

10.内置函数
(1)通配符函数
在这里插入图片描述

(2)模式替换函数
在这里插入图片描述

在这里插入图片描述


4.库文件

库文件是目标文件(*.o)的集合

静态库动态库
Windows.lib.dll
Linux.a.so
(1)静态库

静态库:链接阶段,将库代码嵌入可执行程序,合为一体

优点:移植方便,程序运行时与静态库再无瓜葛。当链接好静态库后,即使静态库坏了、没了,依然不影响已生成的程序的执行。
缺点:①浪费空间,每个进程都有一份静态库的副本 ②对程序更新,部署,发布不友好,当静态库更新时,所有用户都需要重新下载安装的可执行程序。


(2)动态库

动态库:对函数的链接,是在运行时完成的

优点:①节省内存空间,动态库可以被多个进程共享 ,动态库(dynamic library)又称为共享库(shared library) ②对程序的更新,部署,发布友好,只需要更新动态库就好了
缺点:程序运行时,依赖动态库,移植不方便


(3)库的生成

1.生成静态库

ar crsv lib库名.a add.o sub.o mul.o div.o     #静态库打包,用archive
sudo mv lib库名.a /usr/lib
gcc main.c -o main -l库名		#需要加-l选项,链接库

2.生成动态库

gcc -c *.c -fpic   		#生成动态库的目标文件,要加-fpic
gcc -shared *.o -o libalgs.so	#打包生成共享库,用gcc
sudo mv libalgs.so /usr/lib  	#移动到系统的库目录下
gcc main.c -o main -l库名		#同名的静态库和动态库都存在时,默认加载动态库

3.修改版本
libalgs.so当作一个符号链接,其他的带版本号是真的动态库

sudo ln -s libalgs.so.001 libalgs.so    #这样libalgs.so就仅仅只是一个符号链接



四、其他

1.修改代码模板:snippet.c

vim ~/.vim/plugged/prepare-code/snippet/snippet.c

2.小知识储备

1.字段与字段之间,以冒号:分隔


2.Windows回收站
其实是一个文件夹,Windows的删除其实是mv操作。Linux没有回收站。


3.脚本
Python脚本
在这里插入图片描述


相关文章:

C++ (week4):Linux基础

文章目录 零、Linux简介1.配置环境2.Linux历史3.Linux模型 一、vim二、Linux命令行 (shell命令)1.常用命令与快捷键(1)常用命令①man命令&#xff1a;查看帮助手册 (2)快捷键 2.用户子系统(1)Linux用户(2)用户命令 3.文件子系统命令(1)目录命令1.创建文件&#xff1a;mkdir2.删…...

如何将手机中的音乐转移到 SD 卡上?轻松传输音乐

概括 如何将音乐从手机转移到 SD 卡&#xff1f;我们的智能手机可以充当个人点唱机&#xff0c;因此有效管理我们的音乐库变得至关重要。无论您是存储空间不足还是只是想整理您的音乐收藏&#xff0c;将音乐从手机传输到 SD 卡都是一个实用的解决方案。 在本指南中&#xff0…...

JKTECH柔性振动盘用途

柔性振动盘的作用与用途 在现代工业自动化领域&#xff0c;柔性振动盘凭借其独特的功能和广泛的应用场景&#xff0c;正逐渐成为生产线上的重要工具。柔性振动盘&#xff0c;又称柔性供料器&#xff0c;它结合了传统振动盘的高效性和现代自动化技术的灵活性&#xff0c;为各种…...

【职场心灵伴侣】文心一言智能体

【文心一言】智能体 写在最前面名称和简介&#xff1a;职场心灵伴侣AI生成头像添加工具智能体调优 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限…...

【运维】笔记本电脑风扇清洁

笔记本电脑是我们不可或缺的工具&#xff0c;无论是工作、学习还是娱乐。然而&#xff0c;随着时间的推移&#xff0c;笔记本电脑的性能可能会因为各种原因受到影响&#xff0c;尤其是散热问题。过热不仅会降低性能&#xff0c;还可能缩短硬件的寿命。最近&#xff0c;在使用我…...

3.1 掌握RDD的创建

在Apache Spark中&#xff0c;RDD&#xff08;Resilient Distributed Dataset&#xff09;是一个基本的、不可变的、分布式的和可分区的数据集。它能够自动进行容错处理&#xff0c;并支持在大规模集群上的并行操作。RDD之间存在依赖关系&#xff0c;可以实现管道化&#xff0c…...

深入理解 Java 中的 `volatile` 关键字:可见性与有序性的保障

深入理解 Java 中的 volatile 关键字&#xff1a;可见性与有序性的保障 volatile主要做了两个事情可见性保证 和 有序性 可见性保证就是&#xff1a; 对volatile的写操作会对其他线程可见。 简单来说我们A线程的修改了volatile的值&#xff0c;那么我B线程也可以看见。 有序…...

1077: 平衡二叉树的判定

解法&#xff1a; 平衡二叉树是一种特殊的二叉树&#xff0c;它满足以下两个条件&#xff1a; 左子树和右子树的高度差不超过1&#xff08;即&#xff0c;左右子树高度差的绝对值不超过1&#xff09;。左子树和右子树都是平衡二叉树。 后序遍历过程中每次判断左右子树高度差…...

深度学习-Softmax回归+损失函数+图像分类数据集

目录 Softmax回归回归 VS 分类Kaggle上的分类问题 从回归到多类分类回归分类从回归到多类分类-均方损失从回归到多类分类-无校验比例从回归到多类分类-校验比例 Softmax和交叉熵损失总结损失函数均方损失绝对值损失函数鲁棒损失 图像分类数据集通过框架中内置函数将FashionMNIS…...

【论文解读】Overview of the Scalable Video Coding Extension of the H.264/AVC Standard

介绍 该篇论文是一篇关于H.264/AVC标准可扩展视频编码(SVC)扩展的综述论文,由Heiko Schwarz、Detlev Marpe和Thomas Wiegand撰写,发表在《IEEE Transactions on Circuits and Systems for Video Technology》2007年9月第17卷第9期上。 论文解读 摘要: H.264/AVC视频编…...

【C语言】程序员自我修养之文件操作

【C语言】程序员自我修养之文件操作 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C语言学习之路 文章目录 【C语言】程序员自我修养之文件操作前言一.文件介绍1.1为什么使用文件1.2文件分类1.3二进制文件和文本文件 二.文件的打开和关闭2.…...

一种获取java代码结构的实现思路

一种获取java代码结构的实现思路 有时,我们需要获取java文件里的代码结构,即,只需要里面的class定义、方法声明、属性定义。不需要额外的方法实现 这里提供一下实现思路: 采用语法解析器Tree-sitter对java代码进行解析,获取里面的方法实现遍历第一步获取到的方法列表,在源…...

MySQL---增删改查

MySQL是一个流行的关系型数据库管理系统,它使用结构化查询语言(SQL)来管理数据库中的数据。以下是MySQL中增删改查(CRUD)操作的基本命令: 创建(Create): 创建新表:CREATE TABLE table_name (column1 datatype,column2 datatype,...PRIMARY KEY (column) );插入数据:…...

C#编程-.NET Framework使用工具类简化对象之间的属性复制和操作

在C#编程中&#xff0c;对象之间的属性复制和操作是一个常见的需求。为此&#xff0c;.NET Framework提供了多种实用工具库&#xff0c;如AutoMapper、ValueInjecter和ExpressMapper。这些库通过简化代码&#xff0c;提高了开发效率。本文将介绍这些工具库&#xff0c;比较它们…...

爬虫基本原理及requests库用法

文章目录 一、爬虫基本原理1、什么是爬虫2、爬虫的分类3、网址的构成4、爬虫的基本步骤5、动态【异步】页面和静态【同步】页面6、请求头 二、requests基本原理及使用1、chrome 抓包按钮详解1.1 Elements1.2 元素定位器1.3 Network1.4 All1.5 XHR1.6 Preserve log1.7 手机模式1…...

spring和springboot、springcloud版本关系

进入新公司&#xff0c;看底层框架代码时&#xff0c;想了解spring的版本&#xff0c;很好奇这些版本之间时怎么对应的&#xff0c;因为不同版本应该有依赖关系&#xff0c;用得不对可能代码会有隐藏问题。 Spring、SpringBoot和SpringCloud的版本不一致&#xff0c;并且需要搭…...

视频监控汇聚平台LntonCVS通过GB/T28181国标协议实现视频监控平台的级联方案

近年来&#xff0c;随着网络视频监控应用范围的拓展&#xff0c;越来越多的政府部门和跨区域行业单位对视频监控的需求已经不局限于本地联网监控。他们正在探索在原有的本地联网监控基础上&#xff0c;建设省级乃至全国范围内的跨区域监控联网&#xff0c;以全面打造数据共享平…...

【精品】使用 v-md-editor 上传图片

简介 v-md-editor 是基于 Vue 开发的 markdown 编辑器组件&#xff0c;即支持vue2也支持vue3。 gitee&#xff1a;https://gitee.com/ckang1229/vue-markdown-editor文档&#xff1a;https://code-farmer-i.github.io/vue-markdown-editor/zh/ 服务器端代码 RestController…...

STM32——DAC篇(基于f103)

技术笔记&#xff01; 一、DAC简介&#xff08;了解&#xff09; 1.1 DAC概念 传感器信号采集改变电信号&#xff0c;通过ADC转换成单片机可以处理的数字信号&#xff0c;处理后&#xff0c;通过DAC转换成电信号&#xff0c;进而实现对系统的控制。 1.2 DAC的特性参数 1.3…...

突然提示由于找不到msvcr120.dll,无法继续执行代码有什么办法可以解决?

msvcr120.dll是Microsoft Visual C 2013 Redistributable Package的一部分&#xff0c;它包含了运行时库&#xff0c;用于支持使用Visual C 2013开发的应用程序。如果电脑突然提示由于找不到msvcr120.dll,无法继续执行代码有什么办法可以解决&#xff1f;以下是关于msvcr120.dl…...

swig4.2.1压缩包中里面没有找到swig.exe

官网&#xff1a;Simplified Wrapper and Interface Generator C转 C# 采用Swig.exe 打开Example示例的解决方案&#xff1a;sln 生成 即可查看如何调用和使用.i文件 但是&#xff1a;迅雷不管下载哪个版本都是没有exe 官网说了自带。很迷很迷~ 下载其他版本的时候发现&…...

Vue文本溢出如何自动换行

css新增 word-break: break-all; word-wrap: break-word;...

【系统架构师】-论文-系统安全性与保密性设计

1、摘要: 2018 年初&#xff0c;我所在的公司为一票务公司开发开票业务平台的建设。我在该项目中担任系统架构设计师的职务&#xff0c;主要负责设计平台系统架构和安全体系架构。该平台以采用 B/S 架构服务用户&#xff0c;采用”平台应用”的模式解决现有应用单机独立开票的模…...

Cisco Catalyst 9000 9200 9300 9400 IOS software upgrade

1 背景 从Catalyst 3650 ,3850&#xff0c;Catalyst 9000开始, 更准确的说是IOS XE的交换机的系统镜像安装方式分为2种  Bundle mode  Install mode 这2种方工啥区别&#xff1f; Bundle mode 传统方式利用boot system flash:c9k.xx16.bin方式引导 Install mode 将bin文…...

Web Server项目实战2-Linux上的五种IO模型

上一节内容的补充&#xff1a;I/O多路复用是同步的&#xff0c;只有调用某些API才是异步的 Unix/Linux上的五种IO模型 a.阻塞 blocking 调用者调用了某个函数&#xff0c;等待这个函数返回&#xff0c;期间什么也不做&#xff0c;不停地去检查这个函数有没有返回&#xff0c…...

Docker | 基础指令

环境&#xff1a;centos8 参考&#xff1a; 安装 Docker | Docker 从入门到实践https://vuepress.mirror.docker-practice.com/install/ 安装Docker 卸载旧版本&#xff0c;安装依赖包&#xff0c;添加yum软件源&#xff0c;更新 yum 软件源缓存&#xff0c;安装 docker-ce…...

10款手机黑科技app,每款都好用到爆!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 1. 计划程序应用 —— Android Auto Text Android Auto Text&#xff08;前身为 Do It Later&#xff09;是一款简单易用的日程安排应用程序&am…...

tomcat请求数据解析过程

前面提到tomcat请求处理的io交互过程&#xff0c;现在开始看下经过io交互后tomcat是怎么处理请求数据的。首先到AbstractProtocol.java中的process方法&#xff0c;注意这个方法是在tomcat线程池分配的线程调用的。生成用来对请求字节流数据进行解析的Http11Processor。 public…...

《扑克牌游戏》

描述 有一个扑克牌游戏&#xff0c;游戏规则是不断地摸牌&#xff0c;尽可能地使手上的牌的点数接近于10&#xff0c;最完美的情况是总点数为10&#xff0c;不可以超过10&#xff0c;否则就爆了。输入10张牌的点数&#xff0c;(每张点数不超过10)&#xff0c;请你输出用户应该抓…...

kali模块及字典介绍

1. 基本模块介绍 模块 类型 使用模式 功能 dmitry 信息收集 命令行 whois查询/子域名收集/端口扫描 dnmap 信息收集 命令行 用于组建分布式nmap&#xff0c;dnmap_server为服务端;dnmap_client为客户端 i…...