在C语言中,比较不同数据类型的一般规则是什么?

12

假设我有以下情景:

int i = 10;
short s = 5;

if (s == i){
   do stuff...
} else if (s < i) {
  do stuff...
}

在C语言中进行比较时,它会将较小的数据类型(在这种情况下是short)转换为较大的数据类型(int),还是将右侧的数据类型转换为左侧的数据类型(short)?


5
在 C 语言中,一般的规则是“请不要那样做”。但在您的示例中,short 类型会被提升为 int 类型。 - Frédéric Hamidi
4个回答

19
这由“常规算术转换”管理。对于简单情况,一般的经验法则是将具有“较少”精度的类型转换为与其“更高”精度的类型匹配,但当您开始混合使用“signed”和“unsigned”时,这变得有些复杂。 在C99中,这由第6.3.1.8节描述,以下是为了方便起见而包含在此处的内容:
如果其中一个操作数的对应实际类型为long double,则将另一个操作数转换为其对应的实际类型为long double的类型,而不更改类型域。
否则,如果其中一个操作数的对应实际类型为double,则将另一个操作数转换为其对应的实际类型为double的类型,而不更改类型域。
否则,如果其中一个操作数的对应实际类型为float,则将另一个操作数转换为其对应的实际类型为float的类型,而不更改类型域。
否则,在两个操作数上执行整数提升。然后将以下规则应用于提升的操作数:
如果两个操作数具有相同的类型,则不需要进一步转换。
否则,如果两个操作数具有带符号整数类型或都具有无符号整数类型,则将具有较低整数转换等级的操作数转换为具有较高等级的操作数的类型。
否则,如果具有无符号整数类型的操作数的等级大于或等于另一个操作数的类型的等级,则将具有带符号整数类型的操作数转换为具有无符号整数类型的操作数的类型。
否则,如果带符号整数类型的操作数的类型可以表示所有值如果操作数中有无符号整数类型的操作数,则将无符号整数类型的操作数转换为带符号整数类型的操作数类型。 否则,两个操作数都将转换为与带符号整数类型的操作数相对应的无符号整数类型。在第6.3.1.1节中定义了"整数转换秩"的概念,它基本上描述了您可能期望的内容(精度较低的类型具有比精度更高的类型更低的秩)。

5

来自类型转换页面:

第44页的隐式转换集,虽然没有正式说明,但现在要记住这些就足够了。如果您注意到作者所说的“较低”的类型被提升为“较高”的类型,那么它们很容易记忆,其中类型的“顺序”是

char < short int < int < long int < float < double < long double

这个规则很容易记住——“低到高”——但是对于有符号和无符号整数类型来说,它并没有太多帮助,Oli的文章中对此进行了详细解释。但它很容易记住,并在大多数情况下对你有所帮助。


unsigned 如何适用?-1 是否小于 2U - pmg
你是正确的,这只是整个故事的一部分。我会考虑到这一点的。 - emboss
+1:符号应该是<=,在C99中还有long long int,这会增加混淆的程度 :) - pmg

4

通常情况下,C语言只会比较相同类型的两个值,并且永远不会将变量隐式转换为精度更低的类型。在您的示例代码中,short被提升为int,这相当于写成:

int i = 10;
short s = 5;

if ((int)s == i){
   do stuff...
} else if ((int)s < i) {
  do stuff...
}

这将会完全按照你的期望执行,但是对于有符号/无符号比较来说情况并非如此。


2
数据类型是一种抽象,就计算机而言,没有int或short之类的东西。有内存和数据。
当你说“int x”时,你是在告诉计算机“给我足够的字节来存储一个整数”,当你说“short y”时,你是在说...你猜对了。
如你所料,short所占的字节数比int少,因此其通常包含相邻字节中的数据。当比较不同类型的数据时,问题在于“相邻位是否会导致结果偏斜”。
每当你比较两种不同的数据类型时,你实际上是比较存储在两个不同位置的位。为了使比较有效,表示数据所需的最大单独位数必须具有相同的大小。 强制转换可用于帮助解决这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接