说我有一个变量 a
char a = 0x01;
我希望将其转换为长篇,如
long b;
b = (long)a;
b 中的高3个字节是否保证为0?使用我的设置它们是0,但我不确定这是否依赖于编译器。
答案 0 :(得分:4)
是的,b
保证在此分配后具有值0x1
,即使没有强制转换。 c ++中的赋值运算符通常是语义或值驱动的,它将复制值或状态,而不是预先形成按位复制(即使两者有时是等价的,例如对于普通类型)。
在某些情况下,特别是由于操作员超载,情况可能并非如此。非常强烈鼓励开发人员在设计新类型时遵循这个概念,但是粗心的程序员可能会使非基本类型的赋值运算符超载以执行他/她想要的任何操作。
答案 1 :(得分:2)
由于long可以表示char的所有值(无论是有符号还是无符号),因此保证转换不会更改该值。
如果您最初有一个正值,因为任何一个char都在您的体系结构中签名,或者因为char值介于0到127之间(假设为8位字符),所以得到的长数保证为正数且小于256.所以在长4字节大的架构中,3个高阶字节保证为0。
如果char已签名且初始值为负,则情况会有所不同!该值将保持不变,仍然是负数。在通用的2'互补体系结构中,3个高阶位将为0xFF
答案 2 :(得分:0)
已经给出的答案是正确的,但我想我会为C ++添加它,建议使用一种特定于C ++的编译符号,以使其非常清楚你正在做什么。在这里,您将使用:
long b;
b = static_cast<long>(a);
这使得你非常清楚你正在做什么(一个演员如何在编译时计算演员表演到long
),你知道将会执行“正确”的演员表。
答案 3 :(得分:0)
char a = 0x01;
long b;
b = (long)a;
C和C ++是两种不同(但密切相关)的语言。在这种情况下,他们的规则恰好相同。
演员(不是&#34;类型转换&#34;)不是必需的。任务可以,也可能应该写成:
b = a;
导致从char
到long
的隐式转换。由于转换的值在long
类型的可表示范围内,因此转换结果为1
。转换结果是根据值指定的,而不是表示。
1
类型中值long
的表示可能在低位中有1
,而0
位于long
所有其他位。 (并且低位的位置可以变化;一些系统是 big-endian ,一些是 little-endian ,还有其他可能性。)
无法保证类型long
甚至有三个高位字节。类型char
至少为32位宽,但一个字节可以宽于8位。甚至可能有LONG_MAX
类型的值超过char
(如果明文long
已签名且CHAR_BIT >= 32
为1字节,则表示{{1} }})。
类型long
的表示也可能包括填充位,这些位对值没有贡献。它保证符号位为0
,低位值位为1
,所有其他值位为0
,但如果有填充位,则为其值不保证。 (填充位的某些组合可能导致陷阱表示不代表任何值,但在这种特定情况下不会发生。)
这些奇特的可能性大多不太可能在现实生活中发生。某些DSP的C实现确实有大于8位的字节,但您使用的任何系统几乎肯定都有8位字节。
重点是转换的结果是根据值而不是表示来定义的,并且99%的时间都需要关注。如果你写:
char a = 1; /* same as 0x01 */
long b = a;
printf("b = %ld\n", b);
它将打印b = 1
,即使您正在使用某些异常系统,其中值1
的表示方式很奇怪。
答案 4 :(得分:0)
b
将为1;这始终是编译器和字节顺序无关的,真实的。此外,以下表达式将成立:
b == 1
b == 01
b == 0x1
b == 0x00000001
b == 0x00000000000000000000000000000000000000000000000000001
在所有情况下,右侧都是int
常量,值为1;不多,不少。请注意,零不表示内存中的字节(int
很可能没有最后一个表达式显示的字节数)。十六进制表示法只是写下1的另一种方式,与1
完全相同。
特别是,我们不知道内存在哪里,值为1的字节位于内部,因为这取决于架构。它可能是int的地址,也可能是另一端,甚至介于两者之间。
现在出现了一件好事: C并不关心int
中的内存是如何布局的。编写整型常量的方法都不依赖于体系结构。这似乎是自我理解的十进制常量 - 我们是否期望int i = 1
的含义依赖于架构?当然不是。也不是int i = 0x00000001;
。对于位移运算符也是如此:<<
向更高有效位移位>>
,向更低有效位移位。 (十进制或十六进制)整数常量中的数字是有序的,因此最高有效数字位于左侧,与&#34;方向对齐&#34;由箭头状位移运算符表示。这可能会也可能不会反映您机器的int
代表性;在PC上却没有。
底线:如果您使用标准C(或C ++)方法来测试&#34;高3字节&#34;,您就可以免费使用,并且以下内容始终为真,与实现或体系结构无关:
char a = 0x01;
long b = a;
(b & 0x11) == 1 // least significant byte is 1
(b & 0x00000011) == 1 // exactly the same as above
(b & 0x11111100) == 0 // more significant three bytes are all 0
您的long
可能有更多位,但这取决于实现。还有多少:它们都是零,除了最不重要的一个。