【问题标题】:Doubts in K&R edition 2K&R 第 2 版中的疑点
【发布时间】:2015-02-21 14:28:57
【问题描述】:

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;  
    }  

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

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

2。 A7.4.8 第 204 页 Sizeof Operator

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

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

3. A7.17 第209页Assignment Expressions

以下其中一项必须为真:<snip>;或者两个操作数都是指向类型相同的函数或对象的指针,但右侧操作数中可能缺少constvolatile

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

4. A12.5 第 232 页 Conditional Compilation

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

再次,请用代码解释。

5. B1.4 第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 顺便说一句。

【问题讨论】:

  • 这是一系列问题。你需要一个辅导员。
  • 谢谢,但现在我没有。帮助我解决任何一个问题怎么样? ;)
  • 你应该问一个问题。 “你能回答我所有的问题吗?”不算数:-)
  • rename2 中,因为它主要是一个系统调用——依赖于操作系统。这优先于“标准函数”,因为如果没有,“系统调用”部分将为空。无论如何,在man 页面的主题上问“为什么”通常会导致自以为是的讨论。
  • @juanchopanza- 发布 6 个标题为 "K&R edition 2 - Doubt %d", i 的问题对我来说似乎比发布一个汇总所有疑问的帖子更令人讨厌。也许这是一个错误的举动。

标签: c c89 kernighan-and-ritchie


【解决方案1】:
    1234563 GCC 甚至允许使用-funsigned-char/-fsigned-char) 为许多目标更改它,然后 如果不转换为(unsigned char),读取字节255 将是 与文件结尾无法区分。
  1. 对象平铺数组意味着你有:

    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

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

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

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

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

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

警告:初始化会丢弃指针目标类型中的“const volatile”限定符[默认启用]

  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 之后立即成功执行ungetc

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 2016-12-04
    • 2010-09-16
    • 2011-09-14
    • 2011-10-11
    相关资源
    最近更新 更多