今天花了点时间看了看第五章,唉~怎么说呢,虽然说看还是勉强可以看懂的,但是还
不是很深刻啊,而且,觉得不好表达啊,觉得理解上很抽象啊。
1.返回整数的getchar函数
getchar函数一般情况下返回的是标准输入文件中的下一个字符,当没有输入时返回EOF
(定义在stdio.h中,值为-1)。
例:
#inclide <stdio.h>
int main ()
{
char c;
while ( (c = getchar() ) != EOF )
putchar ( c );
return 0;
}
变量c定义为char类型时,由于返回值是int型,这就意味着变量无法容纳下所有可能
的字符,尤其是EOF。因此会出现三种情况。
1.某些合法的输入字符在被“截断”后使得变量的取值与EOF相同。程序将在文件复制中途
终止
2.变量根本不可能取到这个值。程序将陷入死循环
3.程序“正常工作”,但这是巧合。编译器将getchar函数的返回值“截断”处理,并将低端
字节部分赋给了变量c,但是比较表达式时并不是比较c与EOF,而是比较getchar的返回值
与EOF,这样,例子就能够“正常”运行了。
2.更新顺序文件
许多系统中的标准输入/输出库都允许程序打开一个文件同时进行写入和读出的操作,
但为了保持与过去的向下兼容性,一个输入操作不能随后直接紧跟一个输出操作,反之亦然。
如果要同时进行输入和输出操作,必须在其中插入fseek函数的调用。(fseek的第二个参数
是long类型;sizeof返回一个unsigned值)
FILE *fp;
struct record rec;
…
while (fread ( ( char * ) &rec , sizeof ( rec ) , 1 , fp ) == 1 ) {
/* 对rec执行某些操作 */
if ( /* rec必须重新写入 */ ) {
fseek ( fp , -( long ) sizeof ( rec ) , 1);
fwrite ( ( char * ) &rec , sizeof ( rec ) , 1 , fp );
fseek ( fp , 0L , 1 );
}
}
第二个fseek函数看起来什么也没做,但它改变了文件的状态,使得文件现在可以正常
的进行读取了。
3.缓冲输出与内存分配
一个程序生成输出时是否立刻将输出展示给用户,这是根据不同的程序而定的。程序的
输出有两种:一种是即时处理方式;另一种是暂时存起来,然后再大块写入的方式。前者往
往造成较高的系统负担。因此,C语言实现通常允许程序员进行实际的写操作之前控制产生
的输出数据量,而这种控制能力通常是通过库函数setbuf来实现的。如果用一个buf数组来
存放,那么这个缓冲区的大小已经由stdio.h文件中的BUFSIZE定义了。同时,为了别面在
程序将控制权交还给系统前就已经将数组清空这个问题,需要将buf数组定义为static类型
或者是放到main函数之外。
4.使用errno检测错误
我们应该首先检查作为错误指示的返回值,确定程序执行失败后在检查errno,来搞清
楚出错原因:
/* 调用库函数 */
if (返回的错误值)
检查errno并进行处理
5.库函数signal
signal作为捕获异步事件的一种方式,使用前要加上signal.h头文件。
处于安全考虑,不要使用该函数来捕获复杂的函数异步事件,同时,使用longjmp函数
退出signal函数也是不安全的,对于算术运算错误,signal函数处理的唯一安全、可移植的
操作就是打印一条出错消息,然后使用longjmp或exit函数退出程序。
信号非常复杂棘手,而且具有一些从本质上而言不可移植的特性。解决这个问题我们最
好采取“守势”,让signal处理函数尽可能简单,并将它们组织在一起。
这是第五章内容,由于对库函数不熟悉,所以,写的比较简单。

本文详细解读了C语言中几个关键库函数的用法,包括getchar用于读取输入字符,顺序文件的更新技巧,缓冲输出与内存分配策略,错误检测方法以及信号处理的基本概念。文章旨在帮助开发者深入理解并有效利用这些函数,提升编程实践能力。
286

被折叠的 条评论
为什么被折叠?



