我环顾四周,发现更复杂的帖子涉及指针。我正在学习C,只是想证实我对一些例子的理解。 (这些示例假设int和short int大小分别为32位和16位。)
初始代码:
int int1 = 70000;
int int2;
short int shortInt1 = -70;
short int shortInt2, shortInt3;
一些示例转换:
shortInt2 = int1 / shortInt1;
我的理解:
一世。进行分部(70000 / -70),产生-1000的值
II。因为int的优先级高于short int,所以结果将分配给匿名的signed int
III。匿名签名的int被强制转换为匿名签名的短int
IV。匿名签名的short int的值被分配给shortInt2
v。匿名签名int和匿名签名short int是垃圾收集
六。结果:-1000
shortInt3 = (short) int1 / shortInt1;
我的理解:
一世。因为强制转换优先于算术,所以int1被强制转换为匿名签名的short int。发生溢出,使其值为4464
II。进行除法,将-63的结果分配给第二个匿名签名的短int
III。第二个匿名签名的short int的值被分配给shortInt3
IV。这两个匿名签名的短整数都是垃圾收集的
v。结果:-63
int2 = (short)(int1 / shortInt2);
这是我最困惑的例子。我知道转换优先于算术,但是在这里,似乎算术周围的括号给出了对转换的算术优先级。 (我认为这是有道理的,因为施法操作需要一些值来施放。)
所以,我的理解:
一世。执行除法,并且由于int具有更高的优先级,除法的值被分配给匿名签名的int
II。匿名签名的int被强制转换为匿名签名的短int
III。对匿名签名的short int执行算术右移,将其扩展为另一个匿名签名的int
IV。第二个匿名signed int的值分配给int2
v。匿名签名int(第一个),匿名签名short int和匿名签名int(第二个)是垃圾收集
六。值:-1000
答案 0 :(得分:2)
您的问题会产生许多不正确的假设,并使用不正确的术语。我将从解释C标准中有关您的示例代码的内容开始。
您可以获取C标准的最新草稿N1570的副本。 “通常的算术转换”在6.3.1.8节中描述; 整数促销在6.3.1.1中描述。
int int1 = 70000;
根据您的假设,int
是32位,所以它足以容纳值70000
。 (有些系统int
只有16位;在这样的系统上,这将给出一个实现定义的结果。)
int int2;
short int shortInt1 = -70;
70
是int
类型的常量。一元-
运算符应用于结果值,产生的int
值为-70。初始化导致int
值转换到目标对象的类型。转换会尽可能保留值,并且由于short
保证至少为16位宽,因此shortInt1
设置为明显的值。
short int shortInt2, shortInt3;
shortInt2 = int1 / shortInt1;
除法运算符将通常的算术转换应用于其两个操作数。这是一组中等复杂的规则,旨在保证两个操作数的类型相同(大多数情况下,C没有混合型算术运算符)。这种情况非常简单:short int
操作数转换为int
,然后/
应用于两个int
操作数并产生int
结果。值为-1000
。
然后,分配会将结果从int
转换为short
。同样,short
足以保持该值,因此shortInt2
获取值-1000
(类型为short
,而不是int
)。
C中的大多数表达式都是在不考虑它们出现的上下文的情况下进行评估的。赋值右侧的除法不受左侧类型的影响。如果需要,它将在隔离中进行评估,然后转换为目标类型。
shortInt3 = (short) int1 / shortInt1;
强制转换将int1
的值转换为short
类型,因此/
运算符有两个类型为short
的操作数。但整数操作数上的通常的算术转换包括整数提升,它将short
个操作数转换为类型int
。 int
- by - int
除法产生int
结果,然后转换为short
并分配给shortInt3
。
int2 = (short)(int1 / shortInt2);
除法int1 / shortInt2
应用通常的算术转换,它将右操作数从short
转换为int
。然后,int
- by - int
转化的结果会被演员转换为short
。然后,short
结果会转换为int
,因为它已分配给int
目标对象。
现在要澄清你写的一些事情:
因为int的优先级高于short int,所以结果将分配给匿名的signed int
类型没有优先权。经营者呢。 (类型具有 rank ,用于确定*通常的算术转换“。)
您似乎假设必须将评估表达式的结果分配给某个对象(变量)。事实并非如此。评估表达式会产生结果。该结果是一个特定的值,并且是某种特定类型,但它不需要存储在任何地方。 (也许它会暂时存储在寄存器中,甚至存储在某个内存位置,但这是我们可以放心忽略的实现细节。)没有必要发明一个“匿名”的东西来保存表达式的结果。结果只是是。最终它可能存储在一个对象中,或传递给一个函数,或者用作另一个运算符的操作数。完成的方式不是由C标准定义的。