C 关于EOF和ÿ的混淆;

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

在我的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);
    }

    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

C程序有一个执行字符集,这决定了字符文本如何映射到