K&R第2版中的疑问

Doubts in K&R edition 2

1. 8.2 第 171 页 Low Level I/O - Read and Write

    #include "syscalls.h"  
    int getchar(void)  
    {  
        char c;  
        return (read(0, &c, 1) == 1) ? (unsigned char) c : EOF;  
    }  

Casting c to unsigned char in the return statement eliminates any problem of sign extension.

我们在这里讨论什么问题?为什么是 unsigned char 呢?没有演员表会发生什么事 unsigned char?

2。 A7.4.8 第 204 页 Sizeof Operator

When applied to a structure or union, the result is the number of bytes in the object, including any padding required to make the object tile an array: the size of an array of n elements is n times the size of one element

将对象平铺成数组是什么意思?我们正在谈论结构和联合,突然这个 array 怎么会出现在这里?这个肯定看起来像一个错字,但我已经检查了 Errata for K&R 的所有查询。所以很可能我遗漏了一些东西或者我的非母语英语我无法正确掌握它。

3。 A7.17 第 209 页 Assignment Expressions

One of the following must be true: <snip>; or both operands are pointers to functions or objects whose types are the same except for the possible absence of const or volatile in the right operand.

请用代码说明。 int a, b 之类的东西是具有相同类型的两个对象。等等

4. A12.5 第 232 页 Conditional Compilation

Text controlled by inactive arms of the conditional is ignored except for checking the nesting of conditionals.

再次请用代码说明

5. B1.4 第 247 页 ungetc(int c, FILE *stream)

Only one character of pushback per stream is guaranteed.

这是否意味着我只能在 program/software 中使用一次 ungetc

6. B.1.1 第 242 页 File Operations

int rename (const char *oldname, const char *newname)

rename 是一个 stdio 库例程那么为什么它不在 man -s3 rename 中而是在 man -s2 rename 中?我正在使用 Ubuntu 13.10 顺便说一句。

  1. 如果 EOF 定义为 -1,并且如果在此编译器实现中 char 默认为 signed(它是实现定义的不合格的 char 是否为 signed or unsigned;GCC 甚至允许使用 -funsigned-char/-fsigned-char 为许多目标更改它),然后 如果不转换为 (unsigned char),读取字节 255 将是 与文件末尾无法区分。

  2. 平铺数组的对象意味着你有:

    struct foo {
        int a, b;
        char c;
    };
    struct foo bar[5];
    

    即结构数组;整个数组的大小是 sizeof(struct foo) 乘以数组中元素的数量;和推论,如果有对齐要求,sizeof(struct foo) 必须考虑这些。在这台计算机上 int 是 4 个字节而 char 1;但是该结构的大小为 12 个字节(sizeof(struct foo) == 12);数组的大小恰好是 sizeof(struct foo) * 5,而不是 sizeof(struct foo) * 5 + some

  3. 据我了解,这意味着,该段中的所有前面的都失败了,如果类型完全相同,则可以从另一个指针分配指针, 左手指针使用 volatileconst 限定指向的类型,而右手类型不存在:

    int a = 42;
    const volatile int *b = 0;
    b = &a;
    

    可以;因为左侧尺寸的类型为 const volatile int *,而右侧尺寸为 int *constvolatile 在 RH 上不存在是可以的,wheras

    const volatile int a = 42;
    int *b = 0;
    b = &a;
    

不行,因为左边是 int * 而 RH 的类型是 const int *;这样的分配会丢弃限定符; gcc 发出警告:

warning: initialization discards ‘const volatile’ qualifier from pointer target type [enabled by default]

  1. 表示如果你有

    #if 0
    
    // this is the inactive arm of #if
    // the code here is ignored *except* for checking
    // for closing #endif; and #if/#ifdef for nesting
    
    #if 0
    #endif // so that the preprocessor knows that this #endif
           // does not yet end the inactive arm of #if 
    
    #else
    // but here is an active arm
    #endif
    
  2. 一个ungetc之后必须至少读1次;不能保证您可以在另一个 ungetc.

  3. 之后成功地完成 ungetc
  4. 直接来自 Linux 系统调用的所有内容都在手册第 2 节中。rename 是一个系统调用,尽管它也符合 C89、C99。