0

我正在研究 C 中的输入和输出方法,并且我看到了一段代码,其中包含我无法理解的元素。这段代码的目的是展示“回声”和“缓冲”输入/输出是如何工作的,并且在代码中,据我所知,它们有一个为字符声明的类型“int”:

#include <stdio.h>

int main(void){

    int ch;    //This is what I do not get: why is this type 'int'?

    while((ch = getchar()) != '\n'){
        putchar(ch);
    }
    return 0;
}

我在类型转换方面并没有站稳脚跟,这种“int”/“char”差异正在破坏我对数据类型和兼容性的所有概念。

4

3 回答 3

4

getchar()返回一个int类型,因为它被设计为能够返回一个不能用charto 表示的值EOF。(C.11 §7.21.1 ¶3 和 §7.21.7.6 ¶3)

您的循环代码应该考虑到getchar()可能返回EOF

while((ch = getchar()) != EOF){
    if (ch != '\n') putchar(ch);
}
于 2013-10-25T00:25:02.763 回答
3

,和函数返回 int getc,因为它们能够处理二进制数据,以及提供错误或数据结束条件的带内信号。fgetcgetchar

除了在某些具有异常字节大小的嵌入式平台上,该类型int能够将所有字节值表示0UCHAR_MAX正值。此外,它可以表示负值,例如常量的值EOF

该类型unsigned char只能将值表示0UCHAR_MAX,因此函数将无法使用返回值作为指示无法读取另一个数据字节的方式。该值EOF很方便,因为可以将其视为输入符号;例如,它可以包含在switch处理各种字符的语句中。

还有一点,因为在 C 的设计中,值shortchar类型(有符号或无符号)在表达式中求值时会进行提升。

在经典 C 中,在引入原型之前,当您将 a 传递char给函数时,它实际上是一个int被传递的值。具体来说:

int func(c)
char c;
{
   /* ... */
}

这种旧式定义没有引入有关参数类型的信息。当我们将其称为func(c), where chas typechar时,表达式c会受到通常的提升,并成为 type 的值int。这正是上述函数定义所期望的类型。type 的参数char实际上作为 type 的值传递int。如果我们为上述函数编写一个 ISO C 原型声明,它必须是,你猜怎么着:

int func(int); /* not int func(char) */

另一个遗留问题是字符常量'A'实际上有 typeint而不是char. 值得注意的是,这在 C++ 中发生了变化,因为 C++ 具有重载函数。鉴于重载:

void f(int);
void f(char);

我们想f(3)叫前者,f('A')又叫后者。

所以重点是C语言的设计者基本上认为char是面向表示一个紧凑的存储位置,以及最小的可寻址内存单元。但就处理器中的数据操作而言,他们认为这些值是字大小的int值:字符处理本质上是基于int.

这是 C 的低级方面之一。在字节寻址机器上的机器语言中,我们通常将字节视为存储单元,当我们将字节加载到寄存器中以使用它们时,它们会占用一个完整的寄存器,所以变成 32 位值(或者你有什么)。这反映在 C 中的提升概念中。

于 2013-10-25T00:37:19.087 回答
1

的返回类型getchar()int。它返回刚刚读取的字符的 ASCII 码。这(我知道有人会纠正我)与char表示相同,所以你可以自由地比较它们等等。

为什么会这样?这个getchar()函数是古老的——从 K&R C 的早期开始。putchar()同样需要一个int参数,当你认为它可能需要一个char.

希望有帮助!

于 2013-10-25T00:23:41.443 回答