0
  1. 为什么我们写 *bufp = buf 因为两者都是数组所以在我看来它应该是:

    static char bufp = buf;
    
  2. *bufp 如何“知道”从哪个位置开始显示?它不会以任何方式初始化为零。分配buf给后,bufp我希望在返回行中它以最后输入的字符开头。

  3. 此处使用 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] */
}
4

2 回答 2

1

buf是一个数组,所以它不是 char 类型,而是 char * 类型。

char *bufp声明 bufp 也是 type char *。通常,以下两种方法是相似的:

char *bufp = buf;   // Declare and assign in a single line

char *bufp;   // Declare
bufp = buf;   // Then assign

由于static修饰符,在您的示例中只有第一个选项是可能的。

bufp是一个与 具有相同值的指针buf,即buf是 中第一个元素的地址buf[BUFSIZ]bufp也指向这个地址。所以bufp“知道”“buf”知道的一切。你甚至可以使用类似的东西bufp[n],只要n不是超出范围。

总之, buf[BUFSIZ] 是一个数组,其地址为buf、 或&buf[0]、 或bufp&bufp[0]

EOF 不一定在所有系统中都相同,因此最后一行确保事情是一致的。

于 2012-08-18T15:28:09.627 回答
1

[1]char bufp = buf是不正确的,因为 buf 是一个 char 数组(并且在内部是一个地址,即指针的内容),并且char bufp会声明一个唯一字符。char *bufp相反,它是一个指向 char 的指针(指向第一个 char,但您也可以访问下一个 char)。

[2]bufp指向buf数组的开头,即它的第一个字符。并n设置为0bufp,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填充缓冲区bufbufp指向该数组的开头。
  • 那么只要缓冲区中的字符还没有被一个一个地全部返回(n > 0),*bufp就是下一个要返回的字符;*bufp++给出要返回的字符并将bufp指针加一。

[3]unsigned修饰符阻止编译器将*bufp字符(8 位)符号传播到int其他字节(通常是 32 位,即 24 个最高有效位),因为int返回的是 an。因此,任何代码大于 127 的字符(对于无符号字符,或对于有符号字符为负数)都将按原样返回(例如 (unsigned char)200 作为 (int)200 返回)。

于 2012-08-18T16:06:22.913 回答