为什么我们写* bufp = buf,因为它们都是数组,所以我认为应该是:
static char bufp = buf;
* bufp如何“知道”从哪个位置开始显示?它不会以任何方式初始化为零。将
buf
分配给bufp
之后,我希望返回的行以最后输入的字符开头。这里是否使用unsigned char修饰符来省略
-1
作为输入的情况-在大多数系统上表示EOF
?#include "syscalls.h"
/* getchar: simple buffered version */
int getchar(void)
{
static char buf[BUFSIZ];
static char *bufp = buf; /* [1] */
static int n = 0;
if (n == 0) { /* buffer is empty */
n = read(0, buf, sizeof buf);
bufp = buf; /* ? [1] here it is written like in my question so which is true ? */
}
return (--n >= 0) ? (unsigned char) *bufp++ : EOF; /* [2] & [3] */
}
最佳答案
[1] char bufp = buf
是不正确的,因为buf是一个char数组(在内部是一个地址,即指针的内容),并且char bufp
会声明一个唯一字符。相反,char *bufp
是指向char的指针(指向第一个char,但是您也可以访问下一个char)。
[2] bufp
指向buf
数组,即开头的第一个字符。并且n
设置为0
。 bufp
,buf
和n
都是静态的,这意味着它们在函数返回后仍处于“活动”状态-程序加载时将初始化每个值,然后不再在每次调用函数时执行初始化。因此,它们“记住”缓冲区的状态:
`n` is the number of characters in the buffer, ready to be returned one by one,
`bufp` points to the next character to be returned (when n > 0),
and `buf` the array just holds the characters in the buffer.
因此,要回答您的[2]问题,
当没有可用字符(n == 0)时,对
read
的调用将填充缓冲区buf
,而bufp
指向该数组的开头。那么只要缓冲区字符还没有全部被一个接一个地返回(n> 0),
*bufp
是下一个要返回的字符; *bufp++
给出要返回的字符,并将bufp
指针加1。[3]
unsigned
修饰符可防止编译器将*bufp
字符(8位)传播到int
其他字节(通常为32位,即24个最高有效位),因为返回了int
。因此,代码将大于127的任何字符(对于未签名的字符,或者对于签名的字符为负)都按原样返回(例如,(未签名的字符)200返回为(int)200)。