C 中 EOF 和“\0”的值是什么

What is value of EOF and '\0' in C

提问人:theReverseFlick 提问时间:1/16/2011 最后编辑:Keith ThompsontheReverseFlick 更新时间:7/14/2015 访问量:116598

问:

我知道并且是整数类型,但如果是这样,它们不应该有一个固定的值吗?EOF'\0'

我打印了两者,并得到了 -1 和 0 的 .但这些值是固定的吗?EOF'\0'

我也有这个

int a=-1;

printf("%d",a==EOF); //printed 1

和 的值是固定整数吗?EOF'\0'

C++ C EOF

评论

0赞 Martin York 1/17/2011
注意:字符文本中的“\\”表示转义序列。因此,“\0”是值为 0 的八进制转义序列。
4赞 Keith Thompson 6/12/2013
在 C 中,和 是 类型的表达式。说它们是“整数类型”没有多大意义;、 等都是整数类型。(虽然这个名字起源于“integer”的缩写,但 C 中的“integer”是一个比 .EOF'\0'intintlongunsigned charintint

答:

6赞 Leo Izen 1/16/2011 #1

'\0' 始终是 null 字符或 0。EOF 取决于编译器,但通常为 -1,并且始终是 无法保留的值。不要依赖EOF的价值,因为它可以改变。始终执行 x == EOF 而不是 x == -1。“\0”的值始终为 0。你可以指望这一点。unsigned char

评论

2赞 Keith Thompson 6/12/2013
EOF是 的 类型 。由于它是负数,因此根据定义,它是 an 无法保持的值。但是,由于 和 可能具有相同的大小 (if ),因此可能无法区分 和 有效结果。这是带内信令的一个缺点。但是忽略这一点是 99.99+% 安全的,因为唯一具有 DSP 的实际系统,无论如何您都不会期望便携式 I/O 代码在这样的系统上运行。intunsigned charunsigned charintCHAR_BIT >= 16EOFgetchar()CHAR_BIT >= 16
70赞 CB Bailey 1/16/2011 #2

EOF是一个宏,它扩展为具有类型和与实现相关的负值的整数常量表达式,但通常为 -1。int

'\0'在 C++ 中值为 0,在 C 中值为 0。charint

导致的原因是您没有将值分配给 。相反,您检查是否等于,并且由于这是真的(),它打印了.printf("%d",a==EOF);1EOFaaEOFa == -1 == EOF1

评论

2赞 CB Bailey 1/16/2011
@ShyamLovesToCode:您不一定能区分 0 和 NULL,因为 NULL 可能会扩展到 0。我看不出你如何或为什么需要,你能澄清一下吗?
5赞 OrangeDog 1/16/2011
@Shyam - 为什么有这样的需求?如果您谈论指针,如果您谈论的是字符,请使用,并在检查文件末尾时使用。这样做可以减少代码的混乱。NULL'\0'EOF
4赞 CB Bailey 1/16/2011
@ShyamLovesToCode:如果每个整数都可以取其范围内的任何值,那么根据定义,任何有效的整数都不能是哨兵值。如果要存储“不是值”标志,则必须使用其他数据项执行此操作。
2赞 James Greenhalgh 1/16/2011
如果需要能够存储任何整数值,则需要额外的数据结构。如果能够存储几乎任何整数值是可以的,那么您可以使用INT_MAX来表示无效数据。
1赞 OrangeDog 1/17/2011
@Shyam - 在这种情况下,我通常用作无效值。这有一个令人愉快的副作用,即使整数对称。但是,如果您需要将所有 s 作为可能的值,那么您将需要一个带有附加“无效”标志的结构。INT_MINint
0赞 BlackBear 1/16/2011 #3

是的,他们是。 具有相同的值,其值为 0(但它们的含义不同),而 EOF 通常为 -1。'\0'NULL

printf("%d",a==EOF); //printed 1

在这种情况下,您会问:== EOF 是吗?如果它是打印 1(为 true),则它不是打印 0(为 false)。

评论

0赞 theReverseFlick 1/16/2011
是的,我只是想问一下 EOF 是否总是 -1
1赞 Matteo Italia 1/16/2011
'\0'并且可能碰巧总是具有相同的值,但它们具有非常不同的含义。 是字符串终止符,而 是 null(无效)指针。NULL'\0'NULL
0赞 BlackBear 1/16/2011
@ShyamLovesToCode:通常是这样。
0赞 theReverseFlick 1/16/2011
但是,如果需要区分 EOF 和 -1 怎么办?
0赞 Matteo Italia 1/16/2011
@BlackBear:但不能保证是这样; 扩展为一个整数常量表达式,类型为 int 和一个负值,该表达式由多个函数返回以指示文件结束,即不再来自流的输入(C99,§7.19.1:3)。-编辑-编辑得很好。:)EOF
-1赞 Kumar Alok 1/16/2011 #4

'\0' 始终为 0

EOF 依赖于编译器

最常见的是 -1(在 GCC 和 G++ 中为 -1)。

评论

1赞 Konrad Rudolph 1/16/2011
\0是 never(在 C 中,前者是 an,后者是指针;在 C++ 中,前者是 a,后者是 int/pointer/char,具体取决于上下文)。我意识到根据布尔代数,您的答案仍然严格正确,但这完全具有误导性,这里所做的任何提及都是无关紧要的。NULLintcharNULL
0赞 Christoph 1/16/2011
@Konrad:你错了:计算结果为实现定义的空指针常量,即值为 0 的整数常量表达式,或者 - 在 C 中 - 这样的表达式被强制转换为; 是有效的 null 指针常量,并且比较等于NULLvoid *'\0'NULL
0赞 CB Bailey 1/16/2011
@KonradRudolph:为什么不能C++?对我来说,这似乎是一个有效的定义。积分常量表达式(check),右值(check),计算结果为零(check)。NULL\0
0赞 Konrad Rudolph 1/16/2011
@Charles 是 .没有理由就此实施。虽然 C++ 宽松的转换规则确实允许这样做,但这只是荒谬的,恕我直言,在回答什么是价值的问题时非常具有误导性。\0charNULL\0
0赞 Konrad Rudolph 1/16/2011
@Christoph:“比较等于”与“总是”是根本不同的陈述。特别是,它是C++弱类型的产物,而不是这个答案中原始表述所暗示的因果关系。我非常喜欢更新后的答案:“'\0' 始终是 0”——这里根本不需要提及。NULL
30赞 Matteo Italia 1/16/2011 #5

NULL并保证计算结果为 0,因此(使用适当的强制转换)它们可以被视为值相同;但请注意,它们表示两个截然不同的东西:是 null(始终无效)指针,而 是字符串终止符。 相反,它是一个负整数常量,表示流的结束;通常它是-1,但标准没有说明其实际值。'\0'NULL'\0'EOF

C 和 C++ 在类型上有所不同:NULL'\0'

  • 在 C++ 中是 a ,而在 C 中是 ;这是因为在 C 中,所有字符文字都被视为 s。'\0'charintint
  • 在 C++ 中“只是”一个整数 0,而在 C 中,它可以定义为 0 强制转换为 ;这在 C++ 中是无法完成的(并且在注释中明确禁止),因为 C++ 在指针转换中更严格,a 不能隐式转换为任何其他指针类型,因此,如果是 ,则有必要在赋值时将其强制转换为目标指针类型:NULLvoid *void *NULLvoid *

    int * ptr = (void *) 0; /* valid C, invalid C++ */
    

相关标准报价:

C++98/03

NULL

NULL是保证计算结果为 0 的整数类型:

4.10 指针转换

空指针常量是整数类型的整数常量表达式 (5.19) 右值,其计算结果为零。空指针常量可以转换为指针类型;结果是该类型的 null 指针值,并且可与指向对象的指针或指向函数类型的所有其他值区分开来。两个相同类型的 null 指针值应相等比较。null 指针常量到指针的转换 对 CV 限定类型是单个转换,而不是指针转换后跟限定转换的序列 (4.4)。

18.1 类型

[...]宏 NULL 是本国际标准 (4.10) 中实现定义的 C++ 空指针常量。(可能的定义包括 0 和 0L,但不包括 (void*)0)。

'\0'

必须存在 0 值字符:

2.2 字符集

基本执行字符集和基本执行宽字符集应分别包含 [...] 一个 null 字符(分别为 null 宽字符),其表示形式具有所有零位。

'\0'是字面意思:char

2.13.2 字符文字

字符文字是用单引号括起来的一个或多个字符,如 ,可以选择在前面加上字母 L,如 L'x'。不以 L 开头的字符文本是普通字符文本,也称为窄字符文本。包含单个 c 字符的普通字符文本具有 类型 ,其值等于执行字符集中 c 字符编码的数值。'x'char

它的值是 0,因为该转义序列指定了它的值:

转义由反斜杠组成,后跟一个、两个或三个八进制数字,用于指定所需字符的值。\ooo

'\0'用于终止字符串文本:

2.13.4 字符串文字

在转换阶段 7 (2.1) 中,在进行任何必要的串联后,将附加到每个字符串文本中,以便扫描字符串的程序可以找到其末尾。'\0'

EOF

的定义委托给 C89 标准(如 §27.8.2 “C 库文件”中所述),其中它被定义为特定于实现的负整数。EOF

C99型

NULL

空指针是一个 0 整数,可以选择强制转换为 ; 是 null 指针。void *NULL

6.3.2.3 指针

[...]值为 0 的整数常量表达式或转换为类型的表达式称为空指针常量。(宏在(和其他标头)中被定义为空指针常量;参见 7.17。如果将 null 指针常量转换为指针类型,则保证生成的指针(称为 null 指针)与指向任何对象或函数的指针进行比较。void *NULL<stddef.h>

7.17 常见定义 <stddef.h>

[...]这些宏是

NULL

它扩展为实现定义的空指针常量;[...]

'\0'

'\0'是值为 0 的整数,用于终止字符串:

5.2.1 字符集

[...]所有位都设置为 0 的字节(称为空字符)应存在于基本执行字符集中;它用于终止字符串。

6.4.4.4 字符常量

整数字符常量是包含一个或多个多字节字符的序列 在单引号中,如 .[...]'x'

在八进制转义序列中,反斜杠后面的八进制数字被视为整数字符常量的单个字符构造或宽字符常量的单个宽字符构造的一部分。这样形成的八进制整数的数值指定了所需字符或宽字符的值。[...]

整数字符常量的类型为 。int

EOF

EOF是实现定义的负整数

7.19 输入/输出 <stdio.h>

7.19.1 简介

EOF

它扩展为一个整数常量表达式,具有类型和负值,由多个函数返回以指示文件结束,即不再有来自 流int

评论

1赞 Keith Thompson 6/12/2013
在 C 中,不一定计算为 转换后。如果定义为 ,则计算结果可能为 ,也可能不计算为 。有一个特殊情况规则用于将常量整数表达式转换为指针类型(这是空指针常量定义的一部分),但在相反的方向上没有这样的规则。在 null 指针不表示为 all-bits-zero 的罕见实现中,将 null 指针转换为整数类型可能会为您提供非零值。但这是真的,因为如果需要,会转换为指针。NULL0NULL((void*)0)(int)NULL0NULL == 00
0赞 Keith Thompson 6/12/2013
上述评论是狡辩,在大多数情况下并不是特别相关。