C 关于EOF和ÿ的混淆;
在我的Windows GCC中,C 关于EOF和ÿ的混淆;,c,eof,C,Eof,在我的Windows GCC中,EOF的值是-1。我注意到“ÿ”的值也是-1。所以我做了下面的实验,结果让我完全困惑 int main() { int a = 'ÿ'; if (a == EOF) { putchar('a'); putchar(a); } char b = 'ÿ'; if (b == EOF) { putchar('b'); putchar(b); }
EOF
的值是-1
。我注意到“ÿ”
的值也是-1
。所以我做了下面的实验,结果让我完全困惑
int main() {
int a = 'ÿ';
if (a == EOF) {
putchar('a');
putchar(a);
}
char b = 'ÿ';
if (b == EOF) {
putchar('b');
putchar(b);
}
putchar('\n');
int c;
if ((c = getchar()) != EOF) {
putchar('c');
putchar(c);
}
char d;
if ((d = getchar()) != EOF) {
putchar('d');
putchar(d);
}
}
结果是
aÿbÿ // a == EOF b == EOF
ÿÿ //My input for int c and char d
cÿ // c != EOF
我的问题是:
1.当我直接给变量赋值时,无论类型是int还是char,它都等于EOF
。但是当我从stdin中将'ÿ
赋值给intc
时,结果是c
不等于EOF
。这里发生了什么事?
2.如果文件中有“ÿ”
,系统如何区分“ÿ”
和EOF
?是数字255的字符表示。它的char-literal值为-1
255
和-1
都具有相同的8位表示形式(11111111
),这取决于它是被解释为有符号值还是无符号值char
是有符号的,因此它作为char
的值是-1
当它被分配给char
变量时,它将按原样存储。将其分配给
int
变量时,该值将提升为int
,并且这不会改变其值,仅使用更多位(4字节)表示
顺便说一句,-1
也是的值(但您应该始终在代码中使用常量EOF
,并且永远不要依赖其数值)
返回一个
int
;对于“ÿ”
它返回255
将其分配给int
时,该值将保留
将其分配给char
时,行为未定义(因为char
变量的可能值范围为-128
。+127
)。似乎编译器选择将
255
中最右边的8位存储到char
变量中,并且由于char
是有符号的,因此该值被解释为-1
如果文件中有“ÿ”,系统如何区分“ÿ”和EOF
,以及其他读取字符的函数返回int
。这意味着当成功时,它们总是返回(包括)0
和255
之间的值;当到达文件末尾时,它们总是返回EOF
(具有负值)
EOF
的值为负数,不能与“ÿ”
相混淆是数字255的字符表示形式。它的char-literal值为-1
255
和-1
都具有相同的8位表示形式(11111111
),这取决于它是被解释为有符号值还是无符号值char
是有符号的,因此它作为char
的值是-1
当它被分配给char
变量时,它将按原样存储。将其分配给
int
变量时,该值将提升为int
,并且这不会改变其值,仅使用更多位(4字节)表示
顺便说一句,-1
也是的值(但您应该始终在代码中使用常量EOF
,并且永远不要依赖其数值)
返回一个
int
;对于“ÿ”
它返回255
将其分配给int
时,该值将保留
将其分配给char
时,行为未定义(因为char
变量的可能值范围为-128
。+127
)。似乎编译器选择将
255
中最右边的8位存储到char
变量中,并且由于char
是有符号的,因此该值被解释为-1
如果文件中有“ÿ”,系统如何区分“ÿ”和EOF
,以及其他读取字符的函数返回int
。这意味着当成功时,它们总是返回(包括)0
和255
之间的值;当到达文件末尾时,它们总是返回EOF
(具有负值)
EOF
的值为负值,不能将其与“ÿ”
C程序有一个执行字符集,这决定了字符文本如何映射到整数值
您的程序似乎是以iso-8859-1作为执行字符集进行编译的。在我的计算机上,gcc的默认值是utf-8,其中“ÿ”
映射到“多字符常量”50111。对于iso-8859-1,gcc将其映射到-1。我必须使用标志-fexec charset=iso-8859-1
来重现您看到的内容
从文件(或stdin)读取时,您将获得操作系统提供的任何字节(解释为无符号字符)。stdin和文件的编码通常独立于执行字符集
您观察到的是,执行字符集是iso-8859-1,映射到范围-128到127(而不是通常的0到255),其基本原理可能是char
在编译器上签名,因此可以表示执行字符集中的每个值。stdin的编码似乎也是iso-8859-1,只是它使用了通常的0到255。在您问题中的案例(d)中,值255被分配给char
(可能是有符号的,从-128到127),gcc正在包装它
总结:
- (a) 将-1分配给
a
- (b) 将-1分配给
b
- (c) 将255分配给
c
- (d) 将255转换为
,结果为-1。此-1分配给字符
d