比较C中不同数据类型的一般规则是什么?
可以说我有以下场景:
int i = 10; short s = 5; if (s == i){ do stuff... } else if (s < i) { do stuff... }
当C进行比较时,它会转换较小的数据类型,在这种情况下,short是int还是将右边的数据类型转换为左边的数据类型? 在这种情况下int为short?
这由通常的算术转换控制 。 对于简单的情况,一般的经验法则是将具有“较小”精度的类型转换为匹配具有“更多”精度的类型,但是一旦开始混合有signed
和unsigned
,它就会变得有些复杂。
在C99中,这由6.3.1.8节描述,为方便起见,我在此处包含:
首先,如果任一操作数的相应实数类型是
long double
,则另一个操作数在不改变类型域的情况下被转换为其对应的实类型为long double
类型。否则,如果任一操作数的对应实数类型为
double
,则将另一个操作数转换为对应的实类型为double
的类型,而不更改类型域。否则,如果任一操作数的相应实数类型为
float
,则另一个操作数在不更改类型域的情况下转换为对应的实类型为float
类型。否则,将对两个操作数执行整数提升。 然后将以下规则应用于提升的操作数:
- 如果两个操作数具有相同的类型,则不需要进一步转换。
- 否则,如果两个操作数都具有有符号整数类型或两者都具有无符号整数类型,则具有较小整数转换等级类型的操作数将转换为具有更高等级的操作数的类型。
- 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则具有有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型。
- 否则,如果带有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数将转换为带有符号整数类型的操作数的类型。
- 否则,两个操作数都转换为无符号整数类型,对应于带有符号整数类型的操作数的类型。
我已经突出显示了适用于您的特定示例的部分。
整数转换等级的概念在6.3.1.1节中定义,它基本上描述了您可能期望的内容(具有较低精度的类型具有比具有更高精度的类型更低的类别)。
来自类型转换 :
第44页的隐式转换集虽然是非正式的,但却是现在要记住的集合。 如果你注意到它们很容易记住,正如作者所说,
the `lower' type is promoted to the `higher' type,'' where the
顺序”是
char < short int < int < long int < float < double < long double
这个规则很容易记住 - “从低到高” - 但是对于有符号和无符号整数类型它没有多大帮助,这些在Oli的post中得到了很好的解释。 但在大多数情况下,它很容易记住并帮助您。
作为一般规则,如果它们不是同一类型,C将不会比较两个值,并且永远不会将变量隐式转换为精度较低的类型。 在您的示例代码中, short
被提升为int
,这相当于编写:
int i = 10; short s = 5; if ((int)s == i){ do stuff... } else if ((int)s < i) { do stuff... }
这将完全符合您的预期,但签名/无符号比较也是如此。
数据类型是各种类型的抽象…就计算机而言,没有int
或short
。 有记忆,有数据。
当你说int x
,你对计算机说“给我足够的字节来存储一个int”,当你说short y
,你说…你猜对了。
short
,正如您所期望的那样占用较少的字节然后是一个int
,因此可能(并且经常)包含相邻字节中的数据。 在比较不同类型的数据时,问题是“相邻位会导致结果偏差吗?”
无论何时比较两种不同的数据类型,您实际上都在比较存储在两个不同位置的位。 存储以表示数据的各个比特的最大数量需要是相同的大小,以便进行比较
铸造用于帮助解决这个问题。