为什么我们写* 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设置为0bufpbufn都是静态的,这意味着它们在函数返回后仍处于“活动”状态-程序加载时将初始化每个值,然后不再在每次调用函数时执行初始化。因此,它们“记住”缓冲区的状态:

`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)。

10-08 05:58