The C Programming Language Second edition K&R 第 1 章 1.5.1 中的示例,
Example in Chapter 1, 1.5.1, of The C Programming Language Second edittion K&R,
int c;
while ((c = getchar()) != EOF)
putchar(c);
"This value is called EOF, for "end of file". We must declare c to be
a type big enough to hold EOF in addition to any possible char.
Therefore we use int."
如有错误请指正:
- (有符号) char = [-128. +127]
- 无符号字符 = [0, 255]
- EOF = -1
当我在上面的程序中用 char
替换 int
时,它似乎按预期工作,但经过一些研究我发现它不是因为变量 c
无法存储 -1 又名 EOF
(尽管使用 char
)。
我 运行 无论如何都试图让它崩溃,我试着输入负数,比如 -1 但它没有用。我相信这是因为它被解释为 2 个不同的字符 -
和 1
。我试了一下ÿ
根据http://ascii-code.com/是ascii值255对应的字符,
那么上面的程序(使用 char
而不是 int
)对于什么输入会崩溃?
(供参考,我使用的是 64 位软呢帽 Linux)
C char
中未指定有符号或无符号可能会崩溃的原因。它可以在您的机器上运行良好,但在其他机器上可能会失败。
还有 getchar()
函数 return int
值,所以你应该使用 int
变量来得到这个 returning 值。
之前在其他答案中已经解释过,但有时找到重复比给出答案更难。
普通 char
类型可以是有符号或无符号的。
函数 getchar()
returns EOF 或 ... 获取该字符作为 unsigned
char
转换为 int
... (引用 fgetc()
的标准,但它也适用于 getchar()
)。
如果你有一个无符号的普通 char
类型,那么赋值将生成一个值 0..255 然后将其提升为 int
以与 EOF 进行比较,并且由于 [=值 0..255 中的 40=] 是负数,测试将始终失败 — 并且循环不会停止,直到您通过其他方式(中断、重启等)终止程序。
如果你有一个带符号的普通 char
类型,那么赋值将同时处理一个有效字符(通常是 ÿ — U+00FF,带分音符的拉丁文小写字母 Y,如果你使用的是单字节代码集(例如 ISO 8859-15)和 EOF 作为标记 EOF,因此循环可能会在某些文件上过早终止。
因此,根据机器,循环:
char c;
while ((c = getchar()) != EOF)
;
可能是无限循环,也可能在某些数据文件的 EOF 之前终止。两者都不是正确的行为——而且这两种行为都不是崩溃。 (问题中的代码不会崩溃。)将 c
的类型更改为 int
可以可靠且可移植地解决这两个问题。
请注意,如果您使用的是 UTF-8 语言环境,则不会生成十六进制 0xFF 字节;这不是 UTF-8 中的有效字节(U+00FF 在 UTF-8 中被编码为两个字节 0xC3 0xBF)。
int c;
while ((c = getchar()) != EOF)
putchar(c);
"This value is called EOF, for "end of file". We must declare c to be a type big enough to hold EOF in addition to any possible char. Therefore we use int."
如有错误请指正:
- (有符号) char = [-128. +127]
- 无符号字符 = [0, 255]
- EOF = -1
当我在上面的程序中用 char
替换 int
时,它似乎按预期工作,但经过一些研究我发现它不是因为变量 c
无法存储 -1 又名 EOF
(尽管使用 char
)。
我 运行 无论如何都试图让它崩溃,我试着输入负数,比如 -1 但它没有用。我相信这是因为它被解释为 2 个不同的字符 -
和 1
。我试了一下ÿ
根据http://ascii-code.com/是ascii值255对应的字符,
那么上面的程序(使用 char
而不是 int
)对于什么输入会崩溃?
(供参考,我使用的是 64 位软呢帽 Linux)
C char
中未指定有符号或无符号可能会崩溃的原因。它可以在您的机器上运行良好,但在其他机器上可能会失败。
还有 getchar()
函数 return int
值,所以你应该使用 int
变量来得到这个 returning 值。
之前在其他答案中已经解释过,但有时找到重复比给出答案更难。
普通 char
类型可以是有符号或无符号的。
函数 getchar()
returns EOF 或 ... 获取该字符作为 unsigned
char
转换为 int
... (引用 fgetc()
的标准,但它也适用于 getchar()
)。
如果你有一个无符号的普通 char
类型,那么赋值将生成一个值 0..255 然后将其提升为 int
以与 EOF 进行比较,并且由于 [=值 0..255 中的 40=] 是负数,测试将始终失败 — 并且循环不会停止,直到您通过其他方式(中断、重启等)终止程序。
如果你有一个带符号的普通 char
类型,那么赋值将同时处理一个有效字符(通常是 ÿ — U+00FF,带分音符的拉丁文小写字母 Y,如果你使用的是单字节代码集(例如 ISO 8859-15)和 EOF 作为标记 EOF,因此循环可能会在某些文件上过早终止。
因此,根据机器,循环:
char c;
while ((c = getchar()) != EOF)
;
可能是无限循环,也可能在某些数据文件的 EOF 之前终止。两者都不是正确的行为——而且这两种行为都不是崩溃。 (问题中的代码不会崩溃。)将 c
的类型更改为 int
可以可靠且可移植地解决这两个问题。
请注意,如果您使用的是 UTF-8 语言环境,则不会生成十六进制 0xFF 字节;这不是 UTF-8 中的有效字节(U+00FF 在 UTF-8 中被编码为两个字节 0xC3 0xBF)。