C 短类型变量是否自动扩展为整数类型?
我想打印b[FFFC]的值,如下所示C 短类型变量是否自动扩展为整数类型?,c,C,我想打印b[FFFC]的值,如下所示 short var = 0xFFFC; printf("%d\n", b[var]); 但它实际上打印了b[FFFF FFFC]的值 为什么会这样 我的计算机由Windows XP以32位体系结构操作。您希望在32位对齐的内存中只存储16位变量。。。您可以看到,每个内存地址都包含一个完整的32位字(硬件) 额外的FFFF来自这样一个事实:short是一个有符号的值,当分配给int时(在printf调用时),它被符号扩展。当将两个补码从16位扩展到32位时,
short var = 0xFFFC;
printf("%d\n", b[var]);
但它实际上打印了b[FFFF FFFC]的值
为什么会这样
我的计算机由Windows XP以32位体系结构操作。您希望在32位对齐的内存中只存储16位变量。。。您可以看到,每个内存地址都包含一个完整的32位字(硬件) 额外的FFFF来自这样一个事实:short是一个有符号的值,当分配给int时(在printf调用时),它被符号扩展。当将两个补码从16位扩展到32位时,扩展是通过将最后的N位复制到它左边的所有其他M-N来完成的。当然,你不是有意的
因此,在本例中,您对绝对数组位置感兴趣,因此您应该将索引器声明为无符号在当前编译器中,如果write
short
使用32位,则不能使用short
(16位)例如,我在Ubuntu Linux 32位中使用gcc4编译相同的代码:
int main(int argc, char** argv)
{
short var = 0xFFFC;
printf("%x\n", var);
printf("%d\n", var);
return (EXIT_SUCCESS);
}
输出为:
fffffffc
-4
您可以看到cast short to 32位normal,并在2的补码中使用符号扩展名使用%hx或%hd来表示您有一个短变量,例如:
printf("short hex: %hx\n", var); /* tell printf that var is short and print out as hex */
编辑:哎呀,我把问题搞错了。这与我所想的printf()无关。所以这个答案可能有点过分
New:由于您使用var作为数组的索引,因此应将其声明为无符号短(而不是短):
“短期var”可以解释为负数
更准确地说:
您正在“下溢”到负值范围:0x0000到0x7FFF范围内的值将正常。但从0x8000到0xFFFF的值将为负值
以下是一些用作数组b[]索引的var示例:
short var=0x0000;; // leads to b[0] => OK
short var=0x0001; // leads to b[1] => OK
short var=0x7FFF; // leads to b[32767] => OK
short var=0x8000; // leads to b[-32768] => Wrong
short var=0xFFFC; // leads to b[-4] => Wrong
short var=32767; // leads to the same as b[0x7FFF] => OK
short var=32768; // compile warning or error => overflow into 32bit range
作为C可用数据类型的复习,请看一看。 有一条规则与C的使用有关,例如,某些数据类型被提升为其整数类型 char ch = '2'; int j = ch + 1; char ch='2'; int j=ch+1; 现在查看表达式的RHS(右侧),注意
ch
将自动升级为int,以便在表达式的LHS(LHS)上生成所需的结果。j
的值是多少?“2”的ASCII码为50十进制或0x32十六进制,再加上1,j
的值为51十进制或0x33十六进制
理解该规则很重要,这也解释了为什么一个数据类型会被“提升”为另一个数据类型
什么是b
?我想这是一个包含655532个元素的数组,对吗
无论如何,使用格式说明符%d
表示int类型,首先将值提升为int,其次将数组下标提升为int类型int
,因此提升了short var
的使用,因为int的数据大小为4字节,它已升级,因此您将看到值0xFFFF 0xFFFC的其余部分
这就是使用强制转换的原因,告诉编译器将一种数据类型强制转换为另一种数据类型,这与上面Gregory Pakosz的回答相结合
希望这有帮助,
顺致敬意,
Tom.
short
是一种有符号类型。在你的实现中有16位。0xFFFC表示整型常量65532,但当转换为16位有符号值时,结果为-4
因此,您的行short var=0xFFFC代码>将var设置为-4(在您的实现中)
0xFFFFFC是-4的32位表示形式。所发生的一切就是将您的值从一种类型转换为更大的类型,以便将其用作数组索引。它保留其值,即-4
如果确实要访问阵列的65533元素,则应:
- 对
var
使用较大的类型int
在32位窗口上就足够了,但通常size\u t
是一种无符号类型,它保证足够大,可以用于非负数组索引
- 使用一个
无符号的short
,它只为本例提供了足够的空间,但如果您想再向前走4步,则会出错
在您的问题主题中,您已经猜到这里发生了什么:是的,类型short
的值“自动扩展”为类型int
的值。这个过程被称为整体提升。这就是它在C语言中的工作原理:每次使用小于int
的整数值时,该值总是隐式提升为int
类型的值(无符号值可以提升为unsigned int
)。值本身不会更改,当然,只会更改值的类型。在上面的示例中,pattern0xFFFC
表示的16位short
值与pattern0xFFFFFC
表示的32位int
值相同,即小数形式的-4
。顺便说一句,这让你的问题的其余部分听起来很奇怪:不管是否升级,你的代码正在试图访问b[-4]
。升级到int
不会改变任何事情。你的编译器是什么?也许你的编译器不支持short
请给我举一个世界上不支持short
类型的C编译器…@Pakosz cool-down@SjB short是通用C标准的保证。。。比如:现在是刀枪不入的时候,但在C语言中仍然有short=16位。长=32位,等等,等等。。。int,是机器相关的。@jpinto3912:短和长也不是保证固定大小的。您从观察中得出的结论是错误的。。。短变量为16位。执行var++循环,查看溢出的位置。@jpinto3912您的co是什么
char ch = '2';
int j = ch + 1;