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 顺便说一句。
如果 EOF
定义为 -1
,并且如果在此编译器实现中 char
默认为 signed
(它是实现定义的不合格的 char
是否为 signed or unsigned
;GCC 甚至允许使用 -funsigned-char
/-fsigned-char
为许多目标更改它),然后
如果不转换为 (unsigned char)
,读取字节 255
将是
与文件末尾无法区分。
平铺数组的对象意味着你有:
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
。
据我了解,这意味着,该段中的所有前面的都失败了,如果类型完全相同,则可以从另一个指针分配指针,或 左手指针使用 volatile
或 const
限定指向的类型,而右手类型不存在:
int a = 42;
const volatile int *b = 0;
b = &a;
可以;因为左侧尺寸的类型为 const volatile int *
,而右侧尺寸为 int *
; const
和 volatile
在 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]
表示如果你有
#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
一个ungetc
之后必须至少读1次;不能保证您可以在另一个 ungetc
.
之后成功地完成 ungetc
直接来自 Linux 系统调用的所有内容都在手册第 2 节中。rename
是一个系统调用,尽管它也符合 C89、C99。
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 ofconst
orvolatile
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 顺便说一句。
如果
EOF
定义为-1
,并且如果在此编译器实现中char
默认为signed
(它是实现定义的不合格的char
是否为signed or unsigned
;GCC 甚至允许使用-funsigned-char
/-fsigned-char
为许多目标更改它),然后 如果不转换为(unsigned char)
,读取字节255
将是 与文件末尾无法区分。平铺数组的对象意味着你有:
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
。据我了解,这意味着,该段中的所有前面的都失败了,如果类型完全相同,则可以从另一个指针分配指针,或 左手指针使用
volatile
或const
限定指向的类型,而右手类型不存在:int a = 42; const volatile int *b = 0; b = &a;
可以;因为左侧尺寸的类型为
const volatile int *
,而右侧尺寸为int *
;const
和volatile
在 RH 上不存在是可以的,wherasconst 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]
表示如果你有
#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
一个
ungetc
之后必须至少读1次;不能保证您可以在另一个ungetc
. 之后成功地完成 直接来自 Linux 系统调用的所有内容都在手册第 2 节中。
rename
是一个系统调用,尽管它也符合 C89、C99。
ungetc