以下是使用CodeBlocks用c编写的以下代码:
#include <stdio.h>
void main() {
char c;
int i = 65;
c = i;
printf("%dn", sizeof(c));
printf("%dn", sizeof(i));
printf("%c", c);
}
为什么在为变量c
指定int值(c = i
(后打印该变量时,不需要进行强制转换?
强制转换是显式强制转换的一种方式。只有在没有进行隐式转换时,或者希望结果具有与隐式转换不同的类型时,才需要强制转换。
在这种情况下,C标准要求通过赋值运算符的规则进行隐式转换(C11 6.5.16.1/2(:
在简单赋值(=(中,右操作数的值转换为赋值表达式,并替换左侧指定的对象中存储的值操作数。
char
和int
都是整数类型。这反过来意味着在这种情况下,转换整数的规则被隐式调用:
6.3.1.3有符号和无符号整数
将具有整数类型的值转换为_Bool以外的其他整数类型时,如果值可以用新的类型表示,它是不变的。
否则,如果新类型是无符号的,则通过重复添加或比新类型中可以表示的最大值多减去一直到该值在新类型的范围内。
否则,将对新类型进行签名,并且无法在其中表示值;或者结果是定义了实现或者提出了定义了实现的信号。
在您的情况下,新类型char
可以是有符号的,也可以是无符号的,具体取决于编译器。值65可以由char
表示,而与签名无关,因此适用上面的第一段,并且该值保持不变。对于其他较大的值,可能会出现"值无法表示"的情况。
这是整数类型之间的有效转换,因此不需要强制转换。
请注意,严格来说,sizeof(c)
等的结果是类型size_t
,要使用printf
正确打印该结果,必须使用%zu
说明符。
此赋值是在兼容类型上执行的,因为char只不过是一个单字节整数,而int通常是4字节整数类型(取决于机器(。尽管如此,这种(隐式(转换不需要强制转换,但可能会丢失其中的一些信息(较高的字节会被截断(。
让我们检查一下您的程序:
char c; int i = 65; c = i;
此赋值中不需要强制转换,因为变量i
的整数类型int
已隐式转换为目标的整数类型。值65
可以用类型char
表示,因此该赋值是完全定义的printf("%dn", sizeof(c));
转换说明符%d
期望int
值。根据定义,sizeof(c)
具有值1
,但具有类型size_t
,其可能大于int
。您必须在此处使用强制转换:printf("%dn", (int)sizeof(c));
,或者可能使用C99特定的转换说明符:printf("%zun", sizeof(c));
printf("%dn", sizeof(i));
同上。输出将由实现定义,但大多数当前系统具有32位int
和8位字节,因此大小为4
printf("%c", c);
将char
作为变量自变量传递给printf
首先会将char
值提升为int
(或unsigned int
(并按原样传递。升级到unsigned int
发生在极为罕见的平台上,其中char
未签名,大小与int
相同。在其他平台上,不需要强制转换,因为%c
需要int
参数
还要注意,必须使用返回类型int
定义main
。
这是一个修改版本:
#include <stdio.h>
#include <limits.h>
int main() {
char c;
int i = 65;
c = i;
printf("%dn", (int)sizeof(c));
printf("%dn", (int)sizeof(i));
#if CHAR_MAX == UINT_MAX
/* cast only needed on pathological platforms */
printf("%cn", (int)c);
#else
printf("%cn", c);
#endif
return 0;
}