对K& R版本2的怀疑

时间:2015-02-21 14:28:58

标签: c c89 kernighan-and-ritchie

1。 {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;  
    }  
  

在return语句中将c转换为unsigned char可消除任何符号扩展问题。

我们在这里谈论的是什么问题?为什么unsigned char完全正确?没有演员unsigned char会发生什么?

2。 A7.4.8 Page 204 Sizeof Operator

  

当应用于结构或联合时,结果是对象中的字节数,包括使对象平铺数组所需的任何填充:n个元素的数组的大小是n倍于一个元素的大小

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

第3。 A7.17 Page 209 Assignment Expressions

  

以下其中一项必须属实:<snip>;或者两个操作数都是指向函数或对象的指针,除了右操作数中可能缺少constvolatile之外,其类型相同。

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

4。 A12.5 Page 232 Conditional Compilation

  

除了检查条件的嵌套外,忽略条件的非活动臂控制的文本。

再次,请用代码解释。

5。 B1.4 Page 247 ungetc(int c, FILE *stream)

  

每个流只保留一个回退字符。

这是否意味着我只能在程序/软件中使用ungetc一次?


1。 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 BTW。

1 个答案:

答案 0 :(得分:6)

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

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

    255

    即结构阵列;整个数组的大小是struct foo { int a, b; char c; }; struct foo bar[5]; 乘以数组中元素的数量;如果有对齐要求,sizeof(struct foo)必须考虑这些因素。在这台计算机上sizeof(struct foo)是4个字节,int 1;但结构的大小为12个字节(char;数组的大小正好是sizeof(struct foo) == 12),而不是sizeof(struct foo) * 5

  3. 据我所知,这意味着,该段落中的所有先前的失败,指针可以从另一个指定,如果类型完全相同,左手指针使用右侧类型中不存在的sizeof(struct foo) * 5 + somevolatile限定指向类型:

    const

    没问题;因为左手大小的类型为int a = 42; const volatile int *b = 0; b = &a; ,而右手大小为const volatile int *;可以在RH上没有int *const,而且

    volatile
  4. 不行,因为左侧是const volatile int a = 42; int *b = 0; b = &a; 而RH的类型是int *;这样的任务会丢弃限定词; const int *会发出警告:

      

    警告:初始化从指针目标类型[默认启用]

    中丢弃'const volatile'限定符
    1. 这意味着如果你有

      gcc
    2. #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 后必须至少读取1次;我们无法保证您可以ungetc成功地ungetc成功完成ungetc

    3. 直接来自Linux系统调用的所有内容都在手册第2节中。rename是系统调用,但它也符合C89,C99。