首先p20页提到ISO C标准更新后新增了关键字restrict,restrict关键字的作用简单来说就是指明作用域内用此关键字修饰的指针不会指向同一个对象,这样可以让编译器掌握额外的信息后做优化。当然修饰时你要确保指针不会指向同一个地址,如果指向同一地址,那么该行为是未定义的。关于如何理解restrict可以参考这篇回答:https://www.zhihu.com/question/41653775/answer/92088248
幻数,在c语言中,把直接使用的常数叫做幻数。
p52 如何理解这句"其原因是这些函数无法判断该文件名是否被截断过?"
答:就是如果NAME_MAX是14,然后对于一个字符长度为14的文件名的文件,文件中和属性都没有标记其是否被截断过,我们就没办法知道该文件的原始名称是什么了。
Time-to-check-to-time-of-use 字面意思理解就是检查时间点到使用时间点中间有可能发生被检查的东西被篡改,即检查和使用不是一个完整的原子操作带来的问题。
P54 探究这句"lseek仅将当前的文件偏移量记录在内核中,它并不引起任何I/O操作。然后该偏移量用于下一个读或写操作"中文件偏移量是否记录在内核中。
答:虽然可以通过观察read函数不需要显式指出文件偏移量得出结论记录在内核中,但是我们还是做如下一个实验来探究一下。
我们打开一个文件,然后设置文件偏移量来跳过一段文字,然后将其余部分用read函数读入然后打印,看read函数是否直接从内核中获取偏移量。
实验中发现了一个有趣的地方,linux的文件如果全是英文,用file命令查看文件编码格式就是ASCII,如果在文件中插入中文格式就会变成utf-8,删掉中文字符后文件又会变回ASCII
ASCII编码格式字符是等长的,所以我们用它来测试read函数,第一行包括换行符一共有94个字符,我们用lseek函数将文件偏移符设到94个字符后,然后调用read发现第一行已经被跳过了,read并没有指明参数,说明偏移量是记录在内核中的。
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include"apue.h"
#define MaxSize 4096
int main(int argc,char* argv[])
{
if(argc!=2)
err_sys("argc is not 2");
int file_num=openat(AT_FDCWD,argv[1],O_RDONLY);
if(file_num==-1)
err_sys("file open error");
off_t off_num=lseek(file_num,(off_t)94,SEEK_CUR);
char Buffsize[MaxSize];
read(file_num,Buffsize,MaxSize);
printf("%s",Buffsize);
close(file_num);
return 0;
}