20191323王予涵第一、二章学习笔记
20191323王予涵第一、二章学习笔记
一、知识点总结与收获
-
第一章 引言
本书目标:
- 强化学生的编程背景知识,为学生提供高级编程所需的背景知识和技能
- 动态数据结构应用,扩展分区会在磁盘中形成一个“链表”
- 进程概念和进程管理
- 并发编程
- 定时器和计时功能
- 信号、信号处理和进程间通信
- 文件系统
- TCP/IP网络编程
关于Linux:
- Debian Linux
- Ubuntu Linux
- Linux Mint
- 基于RPM的Linux
- Slackware Linux
虚拟机的种类:
- VirtualBox(之前使用过,但因为性能原因放弃使用)
- VMware Workstation(现在使用,性能相较于VirtualBox更好)
注:sudo apt-get install emacs安装emacs编辑软件,在第二章的GDB调试将会用到
Unix/Linux文件系统组织:
Unix/Linux系统采用树形组织结构,在Linux中文件系统树中的每一个节点都是由文件组成的,包括目录、叶节点。用tree命令可以打印文件树,方便查看整体结构储存
同时文件类型还可以细分为:
-
目录文件
-
非目录文件
特殊文件
常规文件
-
符号链接文件(类似与快捷方式)
文件路径名:
- 以“/"开头的为绝对路径名
- 反之为当前工作目录的相对路径名
注:pwd命令可以打印cwd的绝对路径名,有助于快速定位。
Unix/Linux命令:
常用命令:
- touch filename:新建文件或修改文件时间戳
- ls [dirname]:列出cwd或指定目录内容(可以与tree配合使用)
- cat filename:显示文件内容(若显示为乱码则可以用od命令查看进制文件)
- mkdir [dirname]:创建目录
- history:查看历史命令
........
用户账户管理:
添加新用户:
- sudo adduer username
确保用户可以发出sudo:
- 用户名必须保存在/etc/sudoers文件中
- sudoers文件中必须包含 username ALL(ALL) ALL
切换至根用户(书中不方便透露的内容):
- sudo su
密码管理:
passwd username:修改用户密码
网上查找到关于passwd命令的参数:
-k ##keep-tokens keep non-expired authentication tokens 注:保留即将过期的用户在期满后能仍能使用;
-d ##delete delete the password for the named account (root only) 注:删除用户密码,仅能以root权限操作;
-l ##lock lock the named account (root only) 注:锁住用户无权更改其密码,仅能通过root权限操作;
-u ##unlock unlock the named account (root only) 注:解除锁定;
-f ##force force operation 注:强制操作;仅root权限才能操作;
-x ##maximum=DAYS maximum password lifetime (root only) 注:两次密码修正的最大天数,后面接数字;仅能root权限操作;
-n ##minimum=DAYS minimum password lifetime (root only) 注:两次密码修改的最小天数,后面接数字,仅能root权限操作;
-w ##warning=DAYS 注:在距多少天提醒用户修改密码;仅能root权限操作;
-i ##inactive=DAYS 注:在密码过期后多少天,用户被禁掉,仅能以root操作;
-S ##status report password status on the named account (root only) 注:查询用户的密码状态,仅能root用户操作;
第二章 编程背景
Linux中的文本编辑器:
VIM:
Linux中标准内置编辑器(目前正在学习),其分为三种模式分别是:
- 命令模式:用于输入命令
- 插入模式:用于输入和编辑文本
- 末行模式:用于保存文件并退出
gedit:
GNOME桌面环境默认的文件编辑器
emacs:
书中推荐的编辑器,在书中的c代码、makefile、GDB都会涉及到。
- 使用sudo apt-get emacs命令即可安装
- 使用emacs filename即可编辑相应文件
程序开发:
C语言中需要注意的两种变量:
- 静态全局变量:仅对定义他们的文件可见
- 非静态全局变量:对同一程序的所有变量可见
在编程中需要注意这两种变量的使用,若其他文件使用非静态全局变量,则要在文件中添加extern外部变量声明。
GCC编译C语言的运行过程:
-
预处理:gcc -E xx.c -o xx.i
-
编译:gcc -s xx.i xx.s
-
汇编:gcc -c xx.s xx.o
-
链接:
静态链接:gcc -static xx.c -L[dirname] -l[libname]
动态链接: gcc xx.c -L[dirname] -l[libname]
汇编部分:
与上学期所学的先修课程计算机组成原理相同,一个a.out文件是由:
- 文件头
- 代码段
- 数据段
组成,其中根据上学期对汇编的掌握,第2、3的位置可以对调,我一般喜欢将数据段作为第二项。
同时书中所采用的汇编语言为CISC,而我们所学的MIPS汇编则为RISC,二者在语法和所具有的指令有一些差别,如对压栈操作CISC采用subl、pushl指令,而RISC则采用add、sw指令。
C语言中函数的调用:
在C程序中函数的调用主要是执行映像上栈的变化,即保存现场,恢复现场。
Code | Data | Heap | Stack |
---|
和MIPS结构相同,CISC同样也有四种寄存器来处理过程调用(没有将参数寄存器算入其中):
-
PC
-
SP
-
FP
-
AX
但是与CISC不同的是,MIPS进行过程调用时会将当前PC存储到$ra寄存中,若涉及到递归的话则作为现场存储到栈中,而不是一开始就将PC作为现场一起存储。我觉得MIPS在对叶过程的调用效率可能相对于CISC较高。
makefile:
makefile文件是在linux系统下设计大型项目所必须的文件,makefile可以使整个工程编译自动化,极大提升开发效率。
makefile文件格式如下:
目标项 | 依赖项列表 |
---|---|
target: | file1 file2 file3...fileN |
规则 | |
command1 | |
........ |
一些自动变量:
- $@:当前目标名
- $<:第一个依赖名
- $^:所有依赖名
- $*:不包含扩展名的当前依赖名
- $?:比当前目标更新的依赖项列表
书中对于makefile的讲解不是很完全,在看书的过程中对实例中的一些语法不太了解,目前只会编写一些简单语法的makefile文件,还需深入学习。
GDB调试工具
emacs中gdb常用命令:
- r:run
- c:continue
- n:next
- p:print
- clear:clear line | clear name
- b:set break point
数据结构:
- 链表操作
- 队列操作
- 树
三、问题与解决思路
在使用apt-get安装软件的过程中我遇到了有一些软件缺少相应依赖项的问题,这些依赖项往往提示缺少很多依赖项,所以我就想是否可以批量解决缺少依赖项下载的问题。经过在网上的搜寻我发现可以通过aptitude来对依赖项进行批量下载,而且aptitude可以在删除一个包时,会同时删除本身所依赖的包。这样可以使系统更为干净。
aptitude install pkgname//安装包
aptitude remove pkgname//删除包
四、实践基于emacs的GDB调试
makefile代码:
t: t.c
gcc -g -o $@ $<
c代码:
#include <stdio.h>
int add();
int main(void){
int a,b;
a =10;
b = 20;
int c;
c = add(a,b);
printf("%d",c);
return 0;
}
int add(int a, int b)
{
return a + b;
}
开始调试
- 启动gdb调试并设置断点
2、单步模式执行
3、对变量单独设值
4、打印未执行到变量的值
5、简单调试完成