代码:
typedef signed short SIGNED_SHORT; //16 bit
typedef signed int SIGNED_INT; //32 bit
SIGNED_SHORT x;
x = (SIGNED_SHORT)(SIGNED_INT) 45512; //or any value over 32,767
以下是我所知道的:
签名16位:
签名:从-32,768到32,767
无符号:从0到65,535
不要指望45512适合x
,因为x
被声明为16位有符号整数。
上面的双重演员如何以及做什么?
谢谢!
答案 0 :(得分:5)
当你施放两次时,按顺序施放石膏。
int a = 45512;
int b = (int) a;
short x = (short) b;
由于45512在大多数(但不是全部!)平台上都不适合short
,因此这些平台上的强制转换溢出。这将引发实现定义的信号或导致实现定义的值。
实际上,许多平台将结果定义为截断值,在这种情况下为-20024
。但是,有些平台会发出信号,如果未被捕获,可能会终止你的程序。
引用:n1525§6.3.1.3
否则,新类型已签名且值无法在其中表示;无论是 结果是实现定义的或引发实现定义的信号。
答案 1 :(得分:5)
typedef signed short SIGNED_SHORT; //16 bit
typedef signed int SIGNED_INT; //32 bit
这些typedef
并不是特别有用。 typedef只是为现有类型提供新名称。类型signed short
已经有一个非常好的名字:“signed short
”;称它为SIGNED_SHORT
也不会给你买任何东西。 (如果它抽象出一些关于类型的信息,或者类型是否可能会改变,那将是有意义的 - 但使用名称SIGNED_SHORT
作为signed short
以外的类型将非常 令人困惑。)
另请注意,short
和int
都保证至少 16位宽,int
至少与{{1}一样宽但是,不同的大小是可能的。例如,编译器可以同时生成short
和short
16位 - 或64位。但是我会假设编译器的大小与你说的一样。
此外,int
和signed short
是同一类型的名称,short
和signed int
也是。
int
强制转换指定转换为指定类型。两个演员指定两个这样的转换。值SIGNED_SHORT x;
x = (SIGNED_SHORT)(SIGNED_INT) 45512; //or any value over 32,767
将转换为45512
,然后转换为signed int
。
常量signed short
已经是45512
类型(int
的另一个名称),所以最里面的演员阵容是毫无意义的。 (请注意,如果signed int
仅为16位,则int
将为45512
类型。)
当您将一个数值类型的值分配给另一个数字类型的对象时,该值会隐式转换为对象的类型,因此最外层的强制转换也是多余的。
所以上面的代码片段完全等同于:
long
鉴于系统中short x = 45512;
和int
的范围,数学值short
无法在类型45512
中表示。语言规则声明这种转换的结果是实现定义的,这意味着由每个实现决定结果是什么,并且它必须记录该选择,但是不同的实现可以以不同的方式执行。 (实际上,这不是相当整个故事; 1999 ISO C标准增加了这种转换的许可,以提出实现定义的信号。我不知道有任何编译器这样做。)
这种转换最常见的语义是结果得到源值的低位。这将可能导致值short
被分配给-20024
。但是如果你想让你的程序最大程度地移植,你就不应该依赖它。
答案 2 :(得分:4)
双重铸造相当于:
short x = static_cast<short>(static_cast<int>(45512));
相当于:
short x = 45512;
可能会回滚,因此x
等于-20024
,但从技术上讲,如果short在您的平台上的最大值小于45512,则它是实现定义的行为。文字45512
的类型为int
。
答案 3 :(得分:2)
您可以假设它进行了两次类型转换(尽管{C}标准IIRC中signed int
和int
只分开了一次。
如果SIGNED_SHORT太小而无法处理45512,则结果是实现定义或引发实现定义的信号。 (在C ++中只有前者适用。)