20145212 《信息安全系统设计基础》第12周学习总结

20145212 《信息安全系统设计基础》第12周学习总结

学习总结

课堂学习内容

指针数组与数组指针
1.指针数组:即用于存储指针的数组,也就是数组元素都是指针
举例说明:
int *a[3]
表示:数组a中的元素都为int型指针
元素表示:a[i] (a[i])也是一样的,因[]优先级高于*
2.数组指针:即指向数组的指针,指针指向一个类型和元素个数都固定的数组
举例说明:
int (*a)[3]
表示:指向数组a的指针
元素表示:(*a)[i]

3.指针函数:即返回值是指针类型的函数
举例说明:
int *comp()
4.函数指针:即指向函数的指针,函数名就是函数指针
举例说明:
int (*comp)()

右左右左法

从变量名开始,先右再左地,交替地一个一个向外看,在纸上写下:“变量是”
若向右遇到左圆括号,在纸上写下:“函数,参数是”,并用同样的方法处理括号中每一个参数——在纸上写下:“返回”
若向右遇到方括号,在纸上写下:“数组,长度为{方括号的内容},元素类型为”
若向右遇到右圆括号,什么也不做
若向左遇到*,在纸上写下:“指针,指向”
若向左遇到任何类型,在纸上写下对应的类型名

举例说明:分析void ((*fp1)(int))[10]

从fp1开始——fp1是
向右,遇到右括号,什么也不做
向左,遇到*——指针,指向
向右,遇到左圆括号——函数,参数是int,返回
向左,遇到*——指针,指向
向右,遇到左方括号——数组,长度为10,元素类型为
向左,遇到*——指针,指向
向右,已经到声明结尾,什么也不做
向左,遇到void——void

结果是:fp1是 指针,指向 函数,参数是int,返回指针,指向数组,长度为10,元素类型为 指针,指向 void

代码在前几周的博客中均有分析

第9周博客总结
第10周博客总结
第11周博客总结

五次实验总结
实验总结

  • 嵌入式linux
1.在实验一、二、四、五中我们都需要配置开发环境,那么arm、linux系统、开发板之间的关系是什么?
开发板使用的是嵌入式linux系统,但是在开发板中没有足够的资源运行开发程序和调试工具,此时就需要pc端的linux中的交叉编译、汇编以及连接工具形成可执行的二进制代码,然后把可执行文件下载到开发板上并运行。交叉编译环境的配置在pc端的linux系统中,主编器为:armv4l-unknow-linux-gcc4l.
串行端口主要用于串列式逐位元数据传输,在实验中pc端和开发板通过串行端口的方式链接来传输数据。
“超级终端”的作用作为是调试开发板输出信息的监视器和键盘输入的工具。
2.linux、windows xp、超级终端如何实现文件共享。
linux/linux系统中使用nfs服务。它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件。
在本实验中,通过命令mount -t nfs -o nolock 虚拟机的ip地址:/home/bc /host(超级终端)在超级终端中挂载共享文件夹,实现虚拟机和开发板的通讯。
在Linux与Windows中间文件共享采用SAMBA服务;
本实验步骤中在windows 的cmd中输入命令\虚拟机的ip地址实现虚拟机和windows共享文件的过程就是SAMA服务。(实验中sam服务已经配置好)
  • 实验问题及解决方法
(1)配置编译器环境变量的问题
命令 PATH 变量为PATH=$PATH:$HOME/bin:/opt/host/armv4l/bin/注意语句中的“arm4l”中是字母“l”,不是数字“1”.
存盘后执行: source /root/.bash_profile,注意source后面的空格。
(2)在arm中运行可执行文件,执行./hello显示:cannot excute binary file.
因为命令`mount -t nfs -o nolock 虚拟机的ip地址:/home/bc /host(超级终端)将我们将bc文件挂载超级终端的host目录下,所以运行文件时应该在host目录下执行./hello命令。
(3)实验2中,在超级终端运行可执行文件term时出错,提示/dev/ttyS0: No such file or directory。
这个问题是因为在Linux下串口文件位于/dev下,一般在老版本的内核中串口一为/dev/ttyS0,串口二为 /dev/ttyS1, 在我们的开发板中串口设备位于/dev/tts/下,因为开发板中没有ttyS0这个设备,所以我们要建立一个连接。
按照实验指导书说的在超级终端中进入/dev文件夹中,输入命令ln –sf /dev/tts/0 ttyS0(注意空格与字母l、数字0。)
```

- [第一次实践](http://www.cnblogs.com/yayaer/p/6035914.html)
- [第二次实践](http://www.cnblogs.com/yayaer/p/6130446.html)
- [第三次实践](http://www.cnblogs.com/yayaer/p/6082119.html)
- [第四次实践](http://www.cnblogs.com/alovera/p/6105574.html)
- [第五次实践](http://www.cnblogs.com/alovera/p/6059385.html)

## 问题与解决

<font size=3>**1.想想who|sort是怎么实现的。**</font>

who把输出送给stdout,sort从stdin中读入数据,那也就是说who的stdout和sort的stdin连成了一个。

<font size=3>**2.在gdb中详细观察pid的变化**</font>
- 1.对代码testpid.c
![](http://images2015.cnblogs.com/blog/877181/201611/877181-20161128193112693-778646492.png)

- 2.在fork函数中,父进程返回子进程的pid,子进程的pid返回0,可以在gdb中进一步了解这种机制,在代码forkdemo1.c中,由于根据初始输出pid不为0,得知先返回的是父进程。
![](http://images2015.cnblogs.com/blog/877181/201611/877181-20161128195038162-308421375.png)

- 3.可以试着用gdb运行书上第493页的代码:

include "csapp.h"

void unix_error(char *msg)
{
fprintf(stderr,"fork error:%s ",strerror(errno));
exit(0);
}
pid_t Fork()
{
pid_t pid;
if((pid=fork())<0)
unix_error("Fork error");
return pid;
}
int main()
{
pid_t pid;
int x=1;
pid=Fork();
if(pid==0){
printf("child:x=%d ",++x);
exit(0);
}
printf("parent:x=%d ",--x);
}

![](http://images2015.cnblogs.com/blog/877181/201611/877181-20161128200451865-1664672074.png)
在这个例子中,fork函数被父进程调用一次,返回两次——一次返回父进程,一次返回新创建的子进程。其中这两个进程是并发运行的独立进程,它们有相同的用户栈、相同的本地变量值、相同的堆、相同的全局变量值,以及相同的代码,但是却拥有独立的地址空间。


<font size=3>**C语言编程实现who命令**</font>
- who命令是查询当前登录的每个用户,它的输出包括用户名、终端类型、登录日期及远程主机,在Linux系统中输入who命令:
![](http://images2015.cnblogs.com/blog/877181/201612/877181-20161204191854006-1599024617.png)
- 老师在之前给了who1.c的代码:
![](http://images2015.cnblogs.com/blog/877181/201612/877181-20161204192129927-1184870597.png)
- 与who命令相比,时间格式不一样.
- 执行的结果比who命令多了几条,原因是utmp中保存的用户不仅仅是已经登陆的用户,还有系统的其他服务所需要的“用户”,所以在显出所有登陆用户的时候,应该过滤掉其他用户,只保留登陆用户。
- 可以通过```ut_type```来区别,登陆用户的```ut_type```是```USER_PROCESS```
- 编写who代码:

include <stdio.h>

include <stdlib.h>

include <utmp.h>

include <fcntl.h>

include <unistd.h>

include <time.h>

define SHOWHOST

void show_time(long timeval){
char format_time[40];
struct tm *cp;
cp = localtime(&timeval);
strftime(format_time,40,"%F %R",cp);
printf("%s",format_time);
}

int show_info( struct utmp *utbufp )
{
if(utbufp->ut_type == USER_PROCESS){

printf("%-8.8s", utbufp->ut_name);  
printf(" ");                
printf("%-8.8s", utbufp->ut_line);  
printf("     ");                
show_time(utbufp->ut_time); 
printf(" ");                

ifdef SHOWHOST

printf("(%s)", utbufp->ut_host);    

endif

printf("
");               
}
return 0;

}
int main()
{
struct utmp current_record;
int utmpfd;
int reclen = sizeof(current_record);

if ( (utmpfd = open(UTMP_FILE, O_RDONLY)) == -1 ){
    perror( UTMP_FILE );    
    exit(1);
}
while ( read(utmpfd, &current_record, reclen) == reclen )
    show_info(&current_record);
close(utmpfd);
return 0;           

}

- 运行结果如下:
![](http://images2015.cnblogs.com/blog/877181/201612/877181-20161204192545974-105612844.png)


## 代码行数统计
![](http://images2015.cnblogs.com/blog/877181/201612/877181-20161204193029099-284489200.png)

## 学习进度条

|            | 代码行数(新增/累积)| 博客量(新增/累积)|学习时间(新增/累积)|重要成长|
| --------   | :----------------:|:----------------:|:---------------:  |:-----:|
| 目标        | 5000行            |   30篇           | 400小时            |       |
| 第一周      | 0/0           |   1/2            | 10/10             |   使用虚拟机安装linux系统   |
| 第二周      | 341/341           |   1/3           | 20/30             |   掌握核心的linux命令    |
| 第三周      | 177/518          |   2/5            | 16/46             |  学会了虚拟机上的VC编程     |
| 第五周      | 161/679          |   1/6            | 15/61             |      |
| 第六周      | 73/752         |   1/7            | 15/76             |    安装了Y86处理器   |
| 第七周      | 134/886         |   1/8            | 12/88             |   建立了项目结构   |
| 第八周      | 0/886         |   2/10            | 12/100              |   进行了系统的复习   |
| 第九周      | 61/947         |   2/12            | 10/110             |  学习Linux操作系统的基本I/O服务  |
| 第十周      | 502/1449         |   2/14            | 10/120             |  通过实践加深了对指令的理解  |
| 第十一周      | 667/2116         |   2/16            | 15/125             |  学习了异常,通过实践了解了进程的并发  |
| 第十二周      | 69/2185         |   4/16            | 15/140             |  通过对前三周代码的复习,加深了对教材内容的认识  |


## 参考资料
-  [《深入理解计算机系统V2》学习指导](http://www.cnblogs.com/rocedu/p/5826467.html)
原文地址:https://www.cnblogs.com/alovera/p/6119781.html