-
系统编程第一天:
上周做了一周的项目,在老师的带领下终于完成大半了,就是总感觉自己的代码有问题,明天可能需要咨询一下老师了。今天讲的是系统编程,都是文字,没有代码,不知道是课程问题还是老师觉得没必要,感觉没代码参考不习惯,也不能有效回顾老师讲的内容。经过一晚上的查资料发现没有参考代码能够让我充分的利用网络资源来学习一些内容,不知道老师是不是这个意思,要我们学会利用资源。
一、重难点
重点:
a. 计算机基本组成
b. 计算机基本工作原理
c. 内存的作用
d. 冯 偌依曼的两大精髓贡献
e. 函数的两种工作形式
f. 函数的定义来源
g. 执行流分类
h. 多任务实现原理:分时机制
i. 源代码编译后生成的两种东西
j. 系统调用之文件操作函数
k. 文件描述符
难点:open函数的flags、mode参数和文件描述符
二、知识点
a. 计算机基本组成
- 计算机由硬件和软件组成
- 硬件核心部件:主板、电源、CPU、内存
除去核心部件,其它统称外设(即外部设备或I/O设备)
外设按作用大致分为:
输入设备(Input)
输出设备(Output)
外部存储设备等 - 软件按运行条件分为两种:
裸机软件:直接运行在硬件上(CPU要配套)
应用软件(app):运行于对应操作系统之上(CPU要配套,操作系统也要配套)
操作系统(OS):给App提供运行环境的裸机程序。
b. 计算机基本工作原理
1. CPU是奴隶
2. 内存是抽屉
3. 程序员是奴隶主
4. 奴隶主给奴隶下达的命令,以及奴隶完成该命令所要的材料,都要事先放在抽屉里
5. 奴隶完成一条命令的过程如下:
1) 从指定抽屉中取出命令(计算机专业称此动作为:取指)
2) 阅读命令(计算机专业称此动作为:译码)
3) 从指定抽屉中取出材料(计算机专业称此动作为:取数据)
4) 执行命令(计算机专业称此动作为:执行指令)
5) 将执行结果存放到指定抽屉(计算机专业称此动作为:存数据)
6. 本示例中:
抽屉---->内存 奴隶------->CPU
抽屉编码----->地址 命令------->指令 材料------>数据
c. 内存的作用
1. 存指令
2. 存数据(各种各样的数字)
d. 冯 偌依曼的两大精髓贡献
1. 二进制思想(信息------->数字--------->二进制)
1) 大大简化了计算机硬件制造难度
2) 冉生出公式:一切信息 = 二进制位 + 上下文
内存中:使用数据类型来决定二进制位的作用
外存中:使用文件格式来决定二进制位的作用
网络中:使用网络协议来决定被传输的二进制位的作用
2. 程序存储和程序控制
由奴隶的示例,可以看出,一个程序被执行之前,必须要将它所包含的指令存放到内存,然后才能从它的第一条指令开始执行
e. 函数的两种工作形式
1. 阻塞型
这些函数必须要某些条件满足(或称资源就位)才能继续正常执行,
此时函数采用的方式是等待到条件满足(或称资源就位)。
2. 非阻塞型
这些函数必须要某些条件满足(或称资源就位)才能继续正常执行,
此时函数采用的方式是立即返回,资源就位正常返回,否则立即错误返回。
f. 函数的定义来源
1. 自定义函数:即程序员自己实现函数体
2. C库函数(即这些函数体由C语言标准函数库提供)
3. 系统调用函数(即这些函数体由操作系统提供)
4. 第三方函数(即这些函数体由其他程序员提供)
g. 执行流分类
1. 任务流:(参与时间片轮转)
进程
线程
2. 异常流:主要由操作系统负责编写
h. 多任务实现原理:分时机制
分时机制:一种利用人类对时间敏感度以达到视觉欺骗的目的
假设现在有三个任务(T1,T2,T3),先让T1运行10ms,然后再运行T2任务10ms,再然后运行T3任务10ms,再运行T1任务10ms。。。。。。
这样循环往复的过程被称为:时间片轮转
i. 源代码编译后生成的两种东西
1. 可执行文件
2. 库文件
windows:.dll为动态库文件 .lib静态库文件
Linux:.so为动态库文件 .a静态库文件
j. 系统调用之文件操作函数
代码框架:
int fd = -1;//小于零表示是无效的文件描述符
fd = open(字符串所在空间的地址,表示文件操作权限和操作方式的flags);
//.......
read/write读写数据或lseek操作位置指示器
//......
fclose(fd);
```
stat函数可以帮我们获取一个文件的元信息(如文件大小、创建者、各种时间等非文件内容和文件名的信息)
系统调用这一套文件操作函数既可对普通文件做操作,也可对设备文件以及一些特殊文件做操作
C库中f开头那套文件操作函数是调用系统调用这套函数实现的,专门针对普通文件
C库中将普通文件分为两种情况:文本文件和二进制文件
文本文件:打开是需要指定"?t",t字母可省略,读写函数只能调用:
fprintf fscanf fgets fputs fgetc fputc
二进制文件:打开是需要指定"?b",b字母不可省略,读写函数只能调用:
fread fwrite
这些读写函数都依赖与系统调用函数read/write实现
fseek/ftell函数则依赖于系统调用函数lseek实现
fopen函数依赖于系统调用函数open实现
fclose函数依赖于系统调用函数close实现
实际应用过程中:如果操作的是普通文件建议使用C库中f开头的函数会更加简便些,其它情况则只能采用系统调用函数
k. 文件描述符
一个整型数,实际上是一个数组的下标,该数组由操作系统管理,数组里元素代表了打开的文件,
间接地我们当然也可以用该数组的下标代表打开后的文件了。
系统默认情况下,在任何程序的main被调用前,帮我们打开了三个文件:
0 为标准输入设备对应的文件描述符
1 为标准输出设备对应的文件描述符
2 为标准错误设备对应的文件描述符
>work:
1. 封装fgets函数,要求既能避免从键盘读字符串会越界又能清空输入的剩余内容
char *MyFGets(char *buf,int size) //第二天老师给我们的参考
{
char *pret = NULL;
int len = 0;
char p = buf;
pret = fgets(buf,size,stdin);
len = strlen(buf);
p = p + len - 1;
if(p != '\n')
{
while(getchar() != '\n')
{
;
}
}
else
{
*p = '\0';
}
return pret;
}
2. 调用stat计算文件大小
int main(int argc,char *argv[]) //第二天老师给我们的参考
{
struct stat data;
if(argc < 2)
{
printf("The argument is invalid\n");
return 1;
}
stat(argv[1],&data);
printf("the sizeof %s:%d\n",argv[1],data.st_size);
return 0;
}
老师留了两道作业,查了一晚上感觉完成起来有难度。