我最近正在阅读Kernighan的C编程语言。
有一个例子将变量定义为int类型,但使用getchar()
存储在其中。
int x;
x = getchar();
为什么我们可以将char
数据存储为int
变量?
我唯一能想到的就是ASCII和UNICODE。
我是对的吗?
答案 0 :(得分:5)
由于int
,getchar
函数(和类似字符输入函数)返回EOF
。在某些情况下(char) EOF != EOF
(例如char
为unsigned
类型时)。
此外,在许多使用char
变量的地方,无论如何它都会默默地promoted到int
。包含常量字符文字的Ant,如'A'
。
答案 1 :(得分:1)
getchar
是一个旧的C标准函数,当时的哲学更接近于语言如何转换为汇编而不是类型的正确性和可读性。请记住,编译器并没有像现在这样优化代码。在C中,int
是默认的返回类型(即如果你没有在C中声明一个函数,编译器会认为它返回int
),并且返回一个值就完成了使用寄存器 - 因此返回char
而不是int
实际上会生成额外的隐式代码来掩盖值的额外字节。因此,许多旧的C函数更喜欢返回int
。
答案 2 :(得分:1)
C要求int
至少与char
一样多。因此,int
可以存储与char
相同的值(允许签名/无符号差异)。在大多数情况下,int
比char
大很多。
char
是一个整数类型,用于存储来自实现定义字符集的字符代码,该字符代码需要与C的抽象基本字符集兼容。 (ASCII符合条件,编译器允许的source-charset和execution-charset也是如此,包括你实际使用的那个。)
有关整数类型的大小和范围(包括char
),请参阅<limits.h>
。这是别人的limits.h。
答案 3 :(得分:1)
getchar()
尝试从标准输入流中读取一个字节。返回值可以是unsigned char
类型(从0
到UCHAR_MAX
)的任何可能值,也可以是指定为负数的特殊值EOF
。
在大多数当前系统中,UCHAR_MAX
为255
,因为字节有8位,EOF
定义为-1
,但C标准不保证这一点:系统有较大的unsigned char
类型(9位,16位......),尽管我从未见过它,但EOF
被定义为另一个负值。
将getchar()
(或getc(fp)
)的返回值存储到char
会阻止正确检测文件结尾。考虑这些情况(在常见系统上):
如果char
是8位有符号类型,则字节值255
(ISO8859-1字符集中的字符ÿ
)具有该值转换为-1
时char
。将此char
与EOF
进行比较将产生误报。
如果char
未签名,则将EOF
转换为char
将生成值255
,这与EOF
不同,从而阻止检测文件结尾。
这些是将getchar()
的返回值存储到int
变量中的原因。一旦文件结束测试失败,该值稍后可以转换为char
。
如果int
类型已签名且char
的值超出{{1}的范围,则将char
存储到int
会有实施定义的行为}类型。这是一个技术问题,应该强制char
类型为无符号,但C标准允许签署char
类型的许多现有实现。这种简单的转换会产生意想不到的行为,这需要恶意的实施。
char
的值确实取决于执行字符集。大多数当前系统使用ASCII或一些ASCII扩展,如ISO8859-x,UTF-8等。但C标准支持其他字符集,如EBCDIC,其中小写字母不形成连续范围。
答案 4 :(得分:-1)
C被设计为一种非常低级的语言,因此它非常接近硬件。通常,经过一些经验,您可以预测编译器将如何分配内存,甚至可以准确地预测机器代码的外观。
你的直觉是对的:它回归到ASCII。 ASCII实际上是一个简单的1:1映射,从字母(在人类语言中有意义)到整数值(可由硬件处理);对于每个字母,都有一个唯一的整数。例如,'字母'CTRL-A由十进制数'1'表示。 (由于历史原因,许多控制字符首先出现 - 因此CTRL-G在旧的电传终端上敲响了铃声,是ASCII码7.大写'A'和剩下的25个UC字母从65开始,所以请参阅http://www.asciitable.com/以获取完整列表。)
C允许您将变量强制转换为其他类型。换句话说,编译器关心(1)var的内存大小(参见K&amp; R中的'pointer arithmetic'),以及(2)你可以对它做什么操作。
如果内存对我有用,你就不能对char进行算术运算。但是,如果你把它称为int,你可以。因此,要将所有LC字母转换为UC,您可以执行以下操作:
char letter;
....
if(letter-is-upper-case) {
letter = (int) letter - 32;
}
如果在添加/减去之前没有将var重新解释为int,则某些(或大多数)C编译器会抱怨。
但是,最后,类型'char'只是int的另一个术语,实际上,因为ASCII为每个字母分配一个唯一的整数。