在 Linux
下安装软件, 一个通常的办法是 下载到程序的源代码, 并进行编译, 得到可执行程序。但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成 软件包(可以理解成 windows
上的安装程序) 放在一个服务器上,通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装。
App
, 而 软件包管理器 相当于 “应用商店”。 而 yum
就是 centos
的软件包管理器。
yum
(Yellow dog Updater, Modifified)是 Linux
下非常常用的一种包管理器。主要应用在 Fedora
、RedHat
、Centos
等发行版上。
通过 yum list
可命令以罗列出当前一共有哪些软件包. 由于包的数目可能非常之多, 这里我们需要使用 grep
命令 只筛选出我们关注的包. 例如:
yum list | grep lrzsz
结果如下:
lrzsz.x86_64 0.12.20-36.el7 @base
x86_64
:后缀表示 64
位系统的安装包,i686
后缀表示 32
位系统安装包,选择包时要和系统匹配。el7
:表示操作系统发行版的版本。el7
表示的是 centos7
/redhat7
。base
:表示的是 “软件源” 的名称,类似于 “小米应用商店”,“华为应用商店” 这样的概念。 补充内容:
yum
工具在每次安装指定软件包的时候,都会检测源服务器上的软件包信息,为了便捷不用每次都去搜索软件包信息,因此使用 yum makecache
将软件包信息缓存到本地,使用 yum clean all
清理老旧的缓存信息
yum search
:搜索包含指定关键字的软件包
yum -y update
:升级所有包同时,也升级软件和系统内核;
yum -y upgrade
:只升级所有包,不升级软件和系统内核,软件和内核保持原样
sudo yum install -y lrzsz # 安装的语法(加了-y后默认同意)
sudo yum remove lrzsz # 删除的语法
yum
会自动找到都有哪些软件包需要下载, 这时候敲 y
确认安装。出现 complete
字样, 说明安装完成.
注意事项:
sudo
或者切到 root
账户下才能完成.yum
安装软件只能一个装完了再装另一个. 正在 yum
安装一个软件的过程中, 如果再尝试用 yum
安装另外一个软件, yum
会报错. rz
、sz
是 Linux
/Unix
同 Windows
进行 ZModem
文件传输的命令行工具。
rz
(receive Zmodem) 可以很方便的从客户端传文件到服务器,sz
(send Zmodem) 也可以很方便的从服务器传文件到客户端,就算中间隔着跳板机也不影响。
远程文件传输的工具有很多,例如 rz
、sz
、scp
、sftp
、ftp
等。如果环境服务器需要通过跳板机(relay)访问,使用 rz
、sz
传输更为方便。
在 SecureCRT
下的传输协议有 ASCII
、Xmodem
、Ymodem
、Zmodem
4种:
ASCII
:这是最快的传输协议,但只能传送文本文件
Xmodem
:这种古老的传输协议速度较慢,但由于使用了 CRC
错误侦测方法,传输的准确率可高达 99.6%
Ymodem
:这是 Xmodem
的改良版,使用了 1024
位区段传送,速度比 Xmodem
要快。
Zmodem
:Zmodem
采用了串流式(streaming)传输方式,传输速度较快,而且还具有自动改变区段大小和断点续传、快速错误侦测等功能,是目前最流行的文件传输协议
lrzsz
的使用:(需要提前用 yum 安装)
功能:这个工具用于 windows
机器和远端的 Linux
机器通过 XShell
传输文件
从 Windows
传到 Linux
:
使用 rz
[ 选项 ] 具体选项可以使用 rz -h
进行查阅
rz -e # -e 选项会对所有控制字符进行转义
直接将要上传到 linux
中的文件拖到 xshell
的界面
从 Linux
到 Windows
:
使用 sz
[ 选项 ] 文件名
sz t1.txt
yum
的配置文件:/etc/yum.conf
[liren@VM-8-2-centos tmp]$ ls /etc/yum.conf #查看yum的配置文件
/etc/yum.conf
[liren@VM-8-2-centos tmp]$ vim /etc/yum.conf #使用vim打开yum的配置文件
yum
源的存放地点:/etc/yum.repos.d
若进入到 CentOS-Base.repo
中:
[liren@VM-8-2-centos tmp]$ vim /etc/yum.repos.d/CentOS-Base.repo #使用vim进入CentOS-Base.repo
若无这些配置,可到百度查找:centos7 配置国内yum源,进行配置。
vi
和 vim
的区别简单点来说,它们都是多模式编辑器,不同的是 vim
是 vi
的升级版本,它不仅兼容 vi
的所有指令,而且还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行,也可以运行于 xp window
、 mac os
、windows
。下面我们统一按照 vim
来进行讲解!
Normal mode
):控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入插入模式下,或者到末行模式。
Insert mode
):只有在插入模式下,才可以做文字输入,按「ESC
」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。
last line mode
):文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下,shift + :
即可进入该模式。
三种常见模式的转换关系:
进入 vim
的方法:vim + 文件名
退出 vim
的方法:
:w
(保存当前文件):wq
(输入「wq」,存盘并退出vim):q!
(输入q!,不存盘强制退出vim)i
进入插入模式后,从光标当前位置开始输入文字
a
进入插入模式后,从目前光标所在位置的下一个位置开始输入文字
o
进入插入模式后,插入新的一行,从行首开始输入文字
Esc
键vim
可以直接用键盘上的光标来上下左右移动,但正规的 vim
是用小写英文字母 h
、j
、k
、l
,分别控制光标左、下、上、右移一格gg
: 进入到文本开头G
或 shift + g
或 n + shift + g
: 移动到 文本末端 或 向下移动n
位shift + ^
: 移动到光标所在行的“行首”shift + $
: 移动到光标所在行的“行尾”w
: 光标跳到下个字的开头e
: 光标跳到下个字的字尾b
: 光标回到上个字的开头n + 方向键
: 光标移到该行或上下的第 n 个位置,如:5l,56jctrl + b
: 屏幕往“后”移动一页ctrl + f
: 屏幕往“前”移动一页ctrl + u
: 屏幕往“后”移动半页ctrl + d
: 屏幕往“前”移动半页x
:每按一次,删除光标所在位置的一个字符n + x
:例如,「6x」表示删除光标所在位置的“后面(包含自己在内)”6个字符X
:大写的X,每按一次,删除光标所在位置的“前面”一个字符n + X
:例如,「20X」表示删除光标所在位置的“前面”20个字符dd
:删除光标所在行n + dd
:从光标所在行开始删除 n 行dd + p
或 n + dd + p
:剪切某行或剪切 n 行u
:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次“u”可以执行多次回复。ctrl + r
: 撤销上一次的撤销p
:将缓冲区内的字符粘贴到光标所在位置(注意所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能)yy
:复制光标所在行到缓冲区。n + yy
:例如,「6yy」表示拷贝从光标所在的该行“往下数”6行文字。yw
:将光标所在之处到字尾的字符复制到缓冲区中。n + yw
:复制 n 个完整的字符串到缓冲区shift + ~
:将光标处的大小写互相切换r
:替换光标所在处的字符。n + r
:替换光标所在处的 n 个字符。shift + r (R)
:切换为替换模式,直到按下「ESC」键为止。cw
:更改光标所在处的字到字尾处c + n + w
:例如,「c3w」表示更改3个完整的字符串在使用末行模式之前,请记住先按「ESC」键确定您已经处于正常模式,再按「:」冒号即可进入末行模式。
set nu
:在文件中的每一行前面列出行号。
set nonu
:取消行号。
#
:这个符号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字 15
,再回车,就会跳到文章的第 15
行。/ + 关键字
:先按「/」键,再输入想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会 往后 寻找到您要的关键字为止。? + 关键字
:先按「?」键,再输入想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会 往前 寻找到您要的关键字为止。vim
:
w
:在冒号输入字母「w」就可以将文件保存起来
q
:按「q」就是退出,如果无法离开 vim,可以在「q」后跟一个「!」强制离开 vim。
wq
:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件
x!
:保存并退出编辑,仅当文件有修改时会保存,并修改文件时间属性
vim
执行命令行命令:
:! + 命令
:如 「:! gcc test.c」 即可在vim中编译.c文件vim
中的分屏:
: vs + 文件名
:如在 test.c 中打开或创建一个文件「: vs liren.c 」ctrl + w
:光标在分屏的多屏幕下进行切换: %s/要被修改的关键字/最终修改的关键字/g
:比如将 makefile
中的 mycmd
修改为 mytest
,是 %s/mycmd/mytest/g
vim
中多行注释和多行删除命令,这些命令也是经常用到的一些小技巧,可以大大提高工作效率。
esc
进入命令行模式下,按下 Ctrl + v
,进入列(也叫区块)模式
2. 在行首使用上下键选择需要注释的多行
3. 按下键盘(大写)I
键,进入插入模式
4. 然后输入注释符( //
、#
等)
5. 最后按下 Esc
键(在按下 esc
键后,会稍等一会才会出现注释,不要着急~~时间很短的)
esc
进入命令行模式下,按下 Ctrl + v
, 进入列模式x
或者 d
(注意:如果是 //
注释,那需要执行两次该操作,如果是 #
注释,一次即可):set nu
显示行号:32,65d
,回车键,然后 32-65 行就被删除了u
键恢复(命令模式下)/etc/
下面,有个名为 vimrc
的文件,这是系统中公共的 vim
配置文件,对所有用户都有效。.vimrc
。例如,/root
目录下,通常已经存在一个 .vimrc
文件,如果不存在,则创建即可。.vimrc
文件,执行 vim .vimrc
注:直接到百度查找vim配置项,做为了解即可。 —> 一套完整的配置文件(直接安装即可)
sudo yum install gcc
sudo yum install gcc-c++
格式: gcc [选项] 要编译的文件 [选项] [目标文件]
-E
)(生成 .i
文件) #
号开头的代码行-E
,该选项的作用是让 gcc
在预处理结束后停止编译过程-o
是指目标文件,.i
文件为已经过预处理的C原始程序-S
)(生成 .s
文件) parse tree
或者语法树 syntax tree
gcc
首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc
把代码翻译成汇编语言。-S
选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码,生成的后缀文件为 .s
-c
)(生成 .o
文件) .s
文件转成目标文件-c
就可看到汇编代码已转化为 .o
的二进制目标代码-o
选择目标文件)(生成可执行文件) 我们的 C 程序中,并没有定义 printf
的函数实现,且在预编译中包含的 stdio.h
中也只有该函数的声明,而没有定义函数的实现,那么是在哪里实现了 printf
函数的呢?
答案是:linux
系统把这些函数实现都被做到名为 libc.so.6
的库文件中去了,在没有特别指定时,gcc
会到系统默认的搜索路径 /usr/lib
下进行查找,也就是链接到 libc.so.6
库函数中去,这样就能实现函数 printf
了,而这也就是链接的作用。
.a
。
.so
,如前面所述的 libc.so.6
就是动态库。gcc
在编译时默认使用动态库。完成了链接之后,gcc
就可以生成可执行文件,如下所示:gcc
默认生成的二进制程序,是动态链接的,这点可以通过 file
命令验证:
此外,系统默认会自动携带动态库,而不存在静态库,如果我们需要使用静态库链接的话,需要自己手动安装:
sudo yum install -y glibc-static
sudo yum install -y libstdc++-static
-E
: 只激活 预处理,这个不生成文件,你需要把它重定向到一个输出文件里面-S
: 编译 到汇编文件,而不进行汇编和链接-c
: 汇编 到二进制目标代码-o
: 文件输出到指定文件-I
(include
):后面跟着 头文件的绝对路径,让 gcc
指定到该路径去**链接头文件**-L
(link
):后面跟着 库的绝对路径,让 gcc
指定到该路径去**链接库**-l
:后面跟着 库的名称,指定链接某一个库。(注意这里的库名称要去掉前缀和后缀)-D
: 宏的命令行定义,多用于 条件编译中的调试-static
: 此选项对生成的文件采用静态链接-g
: 生成 调试程序-std=c99
或 -std=gnu99
:用指定标准来生成可执行文件-w
: 不生成任何警告信息-Wall
: 生成所有警告信息-shared
: 此选项将 尽量使用动态库,所以生成文件比较小,但是需要系统有动态库-O0
:该选项表示 禁止所有优化,生成的代码与源代码完全一致,主要用于调试目的-O1
:该选项表示启用 基本优化,是默认选项。如删除没有用到的代码、简单的常量折叠和复写、函数内联等。这些优化不会对编译时间和代码大小产生太大的影响,但可以提高程序的执行速度-O2
:该选项启用 更多的优化,包括循环展开、函数调用的参数传递寄存器化、优化算术运算等。这些优化会对编译时间和代码大小产生一定的影响,但可以进一步提高程序的执行速度-O3
:该选项启用 最高级别的优化,包括自动向量化、函数内联、强制内联等。这些优化可能会对编译时间和代码大小产生较大的影响,但也可以进一步提高程序的执行速度gcc
的优化级别越高,生成的代码质量和执行速度都会越好,但编译时间和代码大小也会相应地增加。因此,我们需要根据具体情况选择适当的优化级别debug
模式和 release
模式Linux gcc/g++
生成的二进制程序,默认是 release
模式gdb
调试,必须在编译指令中加上 -g
选项 用下面的命令即可,如果可以 debug
,则会显示 debug
相关的一些信息,否则没有相关信息:objdump --syms your-binary | grep debug
或 objdump -t your-binary | grep debug
,如下所示:
[liren@VM-8-2-centos tmp1]$ objdump --syms mytmp | grep debug #该文件可以debug所以会出现以下这些文件
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
ctrl + d
或 quit
l + 行号
:显示 binFile
源代码,接着上次的位置往下列,每次列 10
行l + 函数名
:列出某个函数的源代码上述的
l
就是list
的意思,可以将其替换为list
r
(run
):运行程序,从开始连续而非单步执行程序
n
(next
):单条执行,逐过程
s
(step
):进入函数调用,逐语句
c
(continue
):直接跳转到下一个断点
until 行号
:跳至某行
finish
:直接运行完毕对应的函数
b + 行号
(break
):在某一行设置断点
b + 函数名
:在某个函数开头设置断点
i b
(infomation
): 查看断点信息
d b
(delete
): 删除所有断点
d b + 行号
: 删除行号为 n
的断点
disable b
(breakpoints
): 禁用断点
enable b
: 启用断点
p + 变量或表达式
(print
):打印表达式的值,通过表达式可以修改变量的值或者调用函数
display 变量名
:跟踪查看一个变量,每次停下来都显示它的值,相当于vs中的监视
undisplay 变量名
:取消对先前设置的那些变量的跟踪
bt
(breaktrace
):查看各级函数调用及参数,相当于 vs
中的调用堆栈窗口
i locals
(info
):查看当前栈帧局部变量的值
set 变量名=n
:修改变量的值为 n
shell + shell指令
:在 gdb
界面使用 shell
指令
会不会写 makefile
,从一个侧面说明了一个人是否具备完成大型工程的能力。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile
定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作!
makefile
带来的好处就是“自动化编译”,一旦写好,只需要一个 make
命令,整个工程完全自动编译,极大的提高了软件开发的效率。
而 make
是一个命令工具,是一个解释 makefile
中指令的命令工具,一般来说,大多数的 IDE
都有这个命令,比如:Delphi
的 make
,Visual C++
的 nmake
,Linux
下 GNU
的 make
。可见,makefile
都成为了一种在工程方面的编译方法。
总结起来就是:make
是一条命令,makefile
是一个文件,两个搭配使用,完成项目自动化构建。
实例:
mytmp:tmp.c # 其中 :前面的是依赖关系中的目标文件,而 :后面的是依赖关系中的依赖文件列表
gcc -o tmp.c tmp.c # 这行命令表示依赖方法
.PHONY:clean # 用.PHONY修饰,代表了伪目标
clean:
rm -f mytmp
上面的例子中,mytmp
文件就依赖于 tmp.c
文件
如果是以这个为例子的话,其中:
mytmp
依赖于 tmp.o
tmp.o
依赖于 tmp.s
tmp.s
依赖于 tmp.i
tmp.i
依赖于 tmp.c
这样子相当于上面例子的 mytmp
依赖于 tmp.c
,而我们一般操作时候也以 mytmp
依赖于 tmp.c
为主,更加简洁
上面例子中的 gcc -o mytmp tmp.c
就是依赖方法!
make
是如何工作的,在默认的方式下,也就是我们只输入 make
命令。此时:
make
会在当前目录下找名字叫 Makefile
或 makefile
的文件。
target
),在上面的例子中,他会找到 mytmp
这个文件,并把这个文件作为最终的目标文件。
mytmp
文件不存在,或是 mytmp
所依赖的后面的 tmp.o
文件的文件修改时间要比 mytmp
这个文件新(可以用 touch
命令查看),那么他就会执行后面所定义的命令来生成 mytmp
这个文件。
mytmp
所依赖的 tmp.o
文件不存在,那么 make
会在当前文件中找目标为 tmp.o
文件的依赖性,如果找到则再根据那一个规则生成 tmp.o
文件。(这有点像一个堆栈的过程)
.c
文件和 .h
文件是存在的啦,于是 make
会生成 tmp.o
文件,然后再用 tmp.o
文件声明 make
的终极任务,也就是执行文件 mytmp
了。
make
的依赖性,make
会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
make
就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make
根本不理。
make
只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
工程是需要被清理的,像 clean
这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过我们可以显示要 make
执行。即命令 make clean
,以此来清除所有的目标文件,以便重编译。
但是一般我们这种 clean
的目标文件,我们将它设置为伪目标,用 .PHONY
修饰,伪目标的特性是,总是被执行的*。
可以将我们的 hello
目标文件声明成伪目标,测试一下:
举例:
mytest:test.o main.o
gcc -o $@ $^
test.o:test.c
gcc -c $<
main.o:main.c
gcc -c $<
.PHONY:clean
clean:
rm -f *.o mytest
makefile
文件中,保存了编译器和链接器的参数选项,并且描述了所有源文件之间的关系。make
程序会读取 makefile
文件中的数据,然后根据规则调用编译器,汇编器,链接器产生最后的输出,即 makefile
文件保存了编译器和连接器的参数选项。Makefile
里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释 make
有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写 makefile
,比如源文件与目标文件之间的时间关系判断之类makefile
中可以定义变量,当 makefile
被执行时,其中的变量都会被扩展到相应的引用位置上,通常使用 $(var)
表示引用变量makefile
中引用另一个 makefile
,类似C语言中的 include
。makefile
中可以使用 #
在行首表示行注释make
命令会在当前目录下按顺序找寻文件名为“GNUmakefile
”、“makefile
”、“Makefile
”的文件make
的执行规则是,只生成所有目标对象中的第一个,当然 make
会根据语法规则,递归生成第一个目标对象的所有依赖对象后再回头生成第一个目标对象,生成后退出。make
在执行 makefile
规则中,根据语法规则,会分析目标对象与依赖对象的时间信息,判断是否在上一次生成后,源文件发生了修改,若发生了修改才需要重新生成。makefile
中的伪对象表示对象名称并不代表真正的文件名,与实际存在的同名文件没有相互关系,因此伪对象不管同名目标文件是否存在都会执行对应的生成指令。伪对象的作用有两个: 首先我们得先了解一个东西,就是文件的一些时间问题:
一个文件的时间分为三种:Access
、Modify
、Change
,这三种分别有什么区别呢?
Access
: 表示最后一次访问(不包括改动)文件的时间,当时新版本中优化了,为了减少频繁的改变时间带来的负载,新版本将其设为多次访问后才会修改 Access 的时间,而不是一次!Modify
: 表示该 文件内容 被修改的时间Change
: 表示该 文件属性 被修改的时间(其实也==包括文件权限,大小,属性==等等,因为改变了内容就改变了文件大小,文件属性也就跟着改变了) 把上面的文件时间搞明白之后,我们想一想,一个文件是否需要被重新生成,是不是与其改变的时间有关?
答案是对的!与其 Modify
即修改时间是有关系的,如果源文件没有被改动,其 make
后的可执行文件的 Modify
时间应当是和源文件相同的,所以系统会去比较这两个时间,相同则说明不需要重新生成;若源文件被改动了,那么源文件的 Modify
时间肯定是要比原来 make
的可执行文件要新,所以重新 make
的话,系统去比较时间的时候就会判断源文件被改动了,所以就会重新生成可执行文件!
下面我们用 touch
指令来验证一下:(touch
一个存在的文件,其修改时间是会被改变的~)
\n
) 会进行实际 I/O 操作\n
) 会将行缓冲区的内容显示出来 fflush()
函数继续刷新\n
:换到下一行,称为 换行\r
:代表的是光标回到 当前行 的最开始的位置 ,称为 回车 注:根据上面的概念,真正的回车符号应该是 \r
,即回到当前行的起始位置,而我们通常了解的 \n
应该是回车换行符,因为它的功能既包括了回车,也包括了换行,即光标跳转到下一行的起始位置。
所以我们可以用 \r
来进行倒计时功能的实现:
void Count()
{
int i = 15;
while(i)
{
printf("%-2d\r", i); //注意这里的\r是关键,并且为了防止十位数变成个位数会多出个0,采取了-2d的写法
fflush(stdout); //对屏幕输出流进行刷新,使行缓冲区的内容显示出来
sleep(1);
i--;
}
}
进度条代码:
proc.h
-----------------------------------------------------------
#pragma once
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#define Max 5
extern void ProcBar();
proc.c
------------------------------------------------------------
#include "proc.h"
char style[Max] = {'>','+','$','~','#'};
void ProcBar()
{
int i = 0;
char proc[102] = {0};
const char* tmp = "|/-\\";
while(i <= 100)
{
printf("[%-100s][%d%%][%c]\r", proc, i, tmp[i%4]); //打印出进度条以及百分比和旋转的状态
fflush(stdout); //对屏幕输出流进行刷新,使行缓冲区的内容显示出来
proc[i++] = style[N]; //记得将每次i对应的数组位置置为'#'
usleep(50000);
}
printf("\n");
}
makefile
------------------------------------------------------------
myproc:main.c proc.c
gcc -o myproc main.c proc.c -DN=3
.PHONY:clean
clean:
rm -f *.o myproc
注意这里的 makefile
文件中的 -D
选项其实就是使用命令行来操作宏,这里 -DN
其实就是操作 proc.c
中的 N
,让其等于 3
,这就很方便!
1、关于 yum
的所有操作 必须保证主机(虚拟机)网络畅通 !!!
可以通过 ping
指令验证:
ping www.baidu.com
2、Centos
在任何时刻,只允许一个 yum
进行安装。
3、for
循环的循环控制变量,通常被 cpu
访问频繁,因此如果调度到寄存器中进行访问则不用每次从内存中取出数据,可以提高访问效率
4、强度削弱是指执行时间较短的指令等价的替代执行时间较长的指令,比如 num % 128 与 num & 127 相较,则明显&127更加轻量
5、死代码删除是编译最优化技术,指的是移除根本执行不到的代码,或者对程序运行结果没有影响的代码,而并不是删除被注释的代码