第一章
一、系统编程课程主要目的:
1、教授学生计算机系统软件方面的广博只是以及高级编程技巧,使其能够与操作系统内核交互,从而有效利用系统资源来开发应用软件。
2、为学生打下扎实的专业基础,以便在操作系统、嵌入式系统、数据库系统、数据挖掘、人工智能、计算机网络、网络安全、分布式和并行计算等计算机科学/工程领域继续深造。
二、本书的目标
1、强化学生的编程背景知识
2、动态数据结构的应用
3、进程概念和进程管理
4、并发编程
5、定时器和定时功能
6、信号、信号处理和进程间通信
7、文件系统
8、TCP/IP和网络编程
三、Unix
诞生于20实际70年代早期,有肯·汤普森和丹尼斯·里奇采用贝尔实验室的PDP-11微型计算机开发。
四、Linux
是一个类Unix系统。最初由林纳斯·托瓦兹在1991年为基于Intel x86的个人计算机开发的一个实验性内核。
五、Ubuntu Linux
1、要运行任何特权命令,用户必须输入
sudo command
2、用户的“PATH”环境变量设置通常不包括用户的当前目录。为在当前目录下运行程序,用户每次都必须输入./a.out。为方便起见,用户应更改路径设置,已包含当前目录。在用户的主目录钟,船舰一个包含一下代码的.bashrc文件:
PATH=$PATH:./
用户每次打开伪终端时,sh都会先执行.bashrc文件来设置路径,以包含当前工作目录。
3、在64位Linux下,使用
gcc -m32 t.c # compile t.c into 32-bit code
生成32位代码。
4、Unix/Linux文件系统采用数形组织结构
5、文件类型
(1)目录文件:一个目录可能包含其他的目录和(非目录)文件。
(2)非目录文件
①常规文件:包含普通文本或包含可执行的二进制代码。
②特殊文件:特殊文件时/dev目录中的条目。
(3)符号链接文件:属于常规文件,其内容为其他文件的路径名。
Linux命令 ln -s aVeryLongFileName myLink
可创建一个符号链接文件“myLink”,指向“aVeryLongFileName”。
6、Unix/Linux文件系统树的根节点(用“/”符号表示)称为根目录,或简称为根。文件系统树的每个结点都有以下表单的路径名指定:
/a/b/c/d OR a/b/c/d
以“/”开头的路径名为绝对路径名,反之则为相对于进程当前工作目录(CWD)的相对路径名。
pwd可以打印CWD的绝对路径名
常用命令
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文件。
gunzip file.gz:解压.gz文件
tar -zcvf file.tgz .:从当前目录创建压缩tar文件
tar -zxvf file.tgz:从.tgz文件中解压文件
man:显示在线手册页
zip file.zip filenames:讲问价压缩为.zip文件
unzip file.zip:解压.zip文件
8、Linux手册页
man ls:显示man1中ls命令的手册页
man 2 open:显示man2中open函数的手册页。
man strtok:显示man 3中strtok函数的手册
第二章编程背景
(一)vim
1、移动光标的命令键:h 左移一个字符 l:右移一个字符
j:下移 k:上移
2、插入模式:i:插入文本 a:追加文本 esc:退出
3、输入“:”进入末行模式,将文本保存为文件或退出vim
:w:写入(保存)文件
:q:退出vim
:wq:保存并退出
:q!:不保存更改,强制退出
(二)WYSIWYG编辑器
(三)emacs
1、“Ctrl+X+C”保存文件并退出
(四)程序开发步骤
1、初始化的全局变量在编译时复制。未初始化的全局变量在程序执行开始时清零
2、gcc是一个程序,它主要包含三个主要步骤
3、虽然默认的二进制可执行文件名为a.out,但实际文件格式可变。其中包括
(1)二进制可执行平面文件
(2)a.out可执行文件
(3)ELF可执行文件(更适合动态链接)
4、a.out文件的内容
5、程序执行过程
(1)读取a.out文件头,以确定所需的总内存大小,包含栈空间大小:
TotalSize = _brk +stackSize
(2)sh从总大小中分配一个内存区给执行映像
(3)sh放弃旧映像,开始执行新映像
(4)执行从crt0.o开始,调用main()
(五)C语言中的函数调用
1、每个CPU都有以下寄存器或同等寄存器,括号中的条目表示x86CPU的寄存器:
PC(IP):指向CPU要执行的下一条指令。
SP(SP):指向栈顶
FP(BP):指向当前激活函数的栈帧
返回值寄存器(AX):函数返回值的寄存器。
当sub()执行C语句return x+y+u+v时,他对表达式求值,并将结果值放入返回寄存器(AX)。
(五)C语言程序与汇编代码的链接
1、GCC生成的汇编代码由三部分组成:
(1)入口代码:又叫作prolog,它建立栈帧,在堆栈上分配局部变量和工作空间。
(2)函数体代码:在AX寄存器中执行带有返回值的函数任务。
(3)退出代码:又叫做epilog,他释放堆栈空间并返回到调用者。
(六)链接库
连接库中包含预编译的目标代码。在链接期间,链接器使用链接库完成链接过程。在Linux中,有两种链接库:用于静态链接库和动态链接库。
1、静态链接库
在编译链接过程中,-L指定链接库路径(当前目录),-l指定链接库。注意,链接库(mylib)未指定前缀lib和后缀.a。
2、动态链接库
(七)GDB调试工具
1、创建makefile:
t: t.c
gcc -g -o t t.c
然后使用RMACS编辑c语言源文件。
2、编译源代码
打开Tools菜单,选择编译或
gccc -g -o t t.c
3、启动GDB
4、多窗口GDB:从GDB菜单中,选择Gud->GDB-MI->Display Other Windows
·Gud-t:用户命令和GDB消息的GDB缓冲区
·t.c:显示执行进度和程序源代码
·栈帧:显示函数调用序列和栈帧
·本地寄存器:显示当前执行函数中的局部变量
·输入/输出:程序I/O
·断电:显示当前断点设置
4、GDB命令
b main b sub b 10 设置断点
clear line#:清除line#的断点
clear name:清楚函数name()中的断点
set var a=100 设置变量a为100
watch c 监视变量c值改变,当c的值改变时,将显示其旧值和新值
bt stackFrame 回溯追踪栈帧
4、c语言程序中的常见错误
1、使用任何指针时,程序员必须确保指针部位NULL或被设置为执行有效的内存地址
2、数组下标越界
3、字符串指针和char数组使用不当
4、assert宏的用法
(八)结构体
1、定义结构体变量
struct node x,node;
NODE x,node;
2、typedef struct node{
struct node *next;
int key key;
char name[2];
}attribute((packed,aligned(1))) NODE;
PACKED属性定义C语言结构体,这可以防止C编译器用额外字节填充字段
3、联合体所有成员共享相同的存储区。
4、可扩充C语言结构体:要使用这类结构体,用户必须为实际结构体分配所需要的内存
(九)树和Linux
mkdir 路径名:为给定的路径名创建一个新目录。
rmdir 路径名:如果目录为空,则删除该目录
creat 路径名:创建一个FILE结点。
save 文件名:将当前文件系统树保存为文件
reload 文件名:从一个文件构造一个文件系统树
menu:显示有效命令菜单
quit:保存文件系统树,然后终止程序
最有收获的内容
本次学习感觉最有收获的内容就是对Linux下gdb相关命令的掌握和对Linux文件系统树的操作了,这一部分在大一的时候已经有过一定的了解,在学习了之后感觉收益颇深。
问题及解决思路
本次学习的内容主要是有关Linux的背景知识以及一些基础的命令操作并未遇到有价值的问题。课本上对于emacs的操作感觉和vim差不多,由于最先接触的编辑器是vim本人更倾向与vim的使用。对于第二章后面的链表操作和树操作由于数据结构之前已经有了一定的了解,于是在这里就忽略了一些基础的知识,只总结出了一些本人不太了解的内容。