一、第一章重要知识点整理
1.Ubuntu Linux的特性
(1)在台式机或笔记本电脑上安装Ubuntu时,需要输入用户名和密码来创建一个默认主目录为“/home/username”的用户账户。当Ubuntu启动时,它会立即在用户环境中运行,因为其已自动登录默认用户。
(2)出于安全原因,用户应为普通用户,而不是根用户或超级用户。
要运行任何特权命令,用户必须输入
sudo command
(3)用户的“PATH”(路径)环境变量设置通常不包括用户的当前目录。为在当前目录下运行程序,用户每次必须输入./a.out。为方便起见,用户应更改路径设置,以包含当前目录。在用户的主目录中,创建一个包含以下代码的.bashrc文件:
PATH=$PATH:./
用户每次打开伪终端时,sh都会先执行.bashrc文件来设置路径,以包含当前工作目录。
(4)很多用户可能都安装了64位的Ubuntu Linux。本书中的一些编程练习和作业是针对32位机器的。在64位Linux下,使用
gcc -m32 t.c # compile t.c into 32-bit code
生成32位代码。若64位Linux不采用`-m32`选项,则用户必须安装适用于gcc的附加支持插件,才能生成32位代码。
(5)Ubuntu具有友好的GUI用户界面。许多用户都习惯于使用GUI,以至于产生了过度依赖,这往往需要反复拖动和点击指向设备,从而浪费了大量时间。在系统编程中,用户还需要学习如何使用命令行和sh脚本,它们比GUI要通用和强大得多。
## 1.15 Unix/Linux文件系统组织
Unix/Linux文件系统采用树形组织结构。
Unix/Linux将所有能够存储
2.Unix/Linux中最常用的命令:
ls:ls dirname:列出CWD或目录的内容。
cd dirname:更改目录。
pwd:打印CWD的绝对路径名。
touch filename:更改文件名时间戳(如果文件不存在,则创建文件)。
cat filename:显示文件内容。
cp src dest:复制文件
mv src dest:移动或重命名文件。
mkdir dirname:创建目录。
rmdir dirname:移除(空)目录。
rm filename:移除或删除文件。
ln oldfile newfile:在文件之间创建链接。
find:搜索文件。
grep:搜索文件中包含模式的行。
ssh:登录到远程主机。
gzip filename:将文件压缩为.gz文件。
tar -zcvf file.tgz.:从当前目录创建压缩tar文件。
tar -zxvf file.tgz.:从.tgz文件中解压文件。
man:显示在线手册页。
zip file.zip filenames:将文件压缩为.zip文件。
unzip file.zip:解压.zip文件。
3.课堂补充
Ubuntu的快捷键的使用:
CTRL+ALT+T
打开终端
CTRL+Shift+T
建立终端新标签页
ALT+1(2,3)
切换标签页
二、第二章重要知识点整理
1.部分Unix/Linux文件系统操作命令规范:
mkdir路径名:为给定的路径名创建一个新目录。
rmdir路径名:如果目录为空,则删除该目录。
cd[路径名]:将当前工作目录更改为路径名,如果没有路径名则更改为“/”。
ls[路径名]:列出路径名或当前工作目录的目录内容。
pwd:打印当前工作目录的(绝对)路径名。
creat路径名:创建一个FILE节点。
rm路径名:删除FILE节点。
save文件名:将当前文件系统树保存为文件。
reload文件名:从一个文件构造一个文件系统树。
menu:显示有效命令菜单。
quit:保存文件系统树,然后终止程序。
2.Makefile工作原理
在默认的方式下,当我们输入make命令时:
make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件声明make的终极任务,也就是执行文件edit了。
说明:make会一层一层地去找文件的依赖关系,直到编译出第一个目标文件,在找寻的过程中,如果出现错误,那么make就会直接退出,并报错;make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么make就不工作了。
3.gcc的使用
gcc -E xx.c -o xx.i
预处理
gcc -S xx.i -o xx.s
编译
gcc -c xx.s -o xx.o
汇编
gcc xx.o -o xx
链接
gcc -Iinclude -c src/xx.c -o libs/xx.o
指定头文件编译
*.c 文件放进文件夹src
*.o文件放进文件夹lib
*.h文件放进文件夹include
*.out文件放进文件夹bin
编译时用:gcc -Iinclude -c src/hello.c -o libs/hello.o
将模块进行编译。若不给出源代码而是给出库的.o文件,编译时用:gcc src/testhello.c libs/hello.o -Iinclude -o bin/hw1
其中-Iinclude
指示头文件的位置。
运行时用:bin/hw
注意所有操作均在项目根目录下进行就可以!
静态库:
将多个.o进行打包就成了静态库。使用ar rcs libhello.a xx.o yy.o
。注意静态库需用libxxx.a的格式进行规范命名。
用静态库编译:gcc src/testhello.c -Iinclude -Llibs -lhello -o bin/hw2
其中,-lhello
就是找libhello.a,并使用其进行编译。
动态库:
动态库不在编译时链接程序,在程序运行时才会进行加载和使用,所以在多次使用的情况下相比静态库更节省空间。
使用方法:
先编译为.o: gcc -c -fPIC hello.c
然后创建动态库.so: gcc -shared -o libmylib.so mysum.o
生成需要动态库的可执行文件:gcc t.c -L. -lmylib
执行
export LD_LIBRARY_PATH=./
./a.out
-o:用来指定生成的文件名。比如gcc hello.c -o hw
-E:执行预处理操作,即生成.i文件。比如gcc -E hello.c -ohello.i
-S:将.i文件转化为汇编代码.s文件。比如gcc -S hello.i -o hello.s
-c:将.s文件转化为机器能执行的二进制机器码。比如gcc -c hello.s -o hello.o
4.gdb断点设置指令总结:
(gdb)break 7 //以行号设置断点
(gdb)break function_name //以函数名设置断点
(gdb)clear 行号 //删除这行的断点
(gdb)clear 函数名 //删除该函数的断点
(gdb)delete breakpoints n //删除第n次(指定编号)设置的断点
(gdb)clear //删除程序中所有的基于行设置的断点
(gdb)delete //删除程序中所有的断点
(gdb)r //执行程序
(gdb)n //单步调试
(gdb)c //执行到下一个断点
(gdb)print 变量或表达式 //打印变量或表达式当前的值。
(gdb)print 变量=值 //对变量进行赋值
(gdb)whatis 变量或表达式 //显示变量类型
(gdb)set variable 变量=值 //变量赋值