隐式类型转换在C语言中是否保持char和short变量的相同等级?

huangapple go评论65阅读模式
英文:

Does implicit typecasting in C maintain the same rank for char and short variables?

问题

在C编程中,从高到低的隐式类型转换顺序如下:

隐式类型转换在C语言中是否保持char和short变量的相同等级?

在这里,char和short的等级相同,这意味着从char到short或从short到char没有隐式转换,对吗?

char占用1字节,
short占用2字节

由于这两种类型的大小不同,它们如何处于相同的等级?

英文:

In C programming the implicit typecasting order from Higher to lower:

隐式类型转换在C语言中是否保持char和short变量的相同等级?

is the rank of char and short same here, means there is no implicit conversion from char to short or short to char right?

char is - 1 byte,
short is - 2 bytes

since the size is different for both these types, how they would be in the same rank?

答案1

得分: 4

你提供的图表是错误的。首先,将short intchar类型进行排名是完全不正确的。根据C11标准(草案)中的6.3.1.1布尔、字符和整数,第1段规定:

> long long int的等级应高于long int的等级,long int的等级应高于int的等级,int的等级应高于short int的等级,short int的等级应高于signed char的等级。

C语言的数字类型比图表中简单的线性“等级”要复杂得多。

请注意,浮点类型floatdoublelong double与上述6.3.1.1中的整数类型不属于同一等级。如你的问题评论中所指出的,当混合使用数字类型时,它们受到所谓的通常的算术转换的影响:

> 许多期望算术类型的操作符会导致类似的转换,并以类似的方式产生结果类型。其目的是确定操作数和结果的共同的实数类型。对于指定的操作数,每个操作数都会被转换为其相应的实数类型,而不改变类型域,其相应的实数类型是共同的实数类型。除非另有明确说明,否则共同的实数类型也是结果的相应实数类型,其类型域是操作数的类型域,如果它们相同的话,否则是复数。这种模式称为通常的算术转换:
>
> - 首先,如果任一操作数的相应实数类型是long double,则另一个操作数将被转换为其相应实数类型,而不改变类型域。
> - 否则,如果任一操作数的相应实数类型是double,则另一个操作数将被转换为其相应实数类型,而不改变类型域。
> - 否则,如果任一操作数的相应实数类型是float,则另一个操作数将被转换为其相应实数类型,而不改变类型域。
> - 否则,对两个操作数执行整数提升。然后,将以下规则应用于提升后的操作数:
> - 如果两个操作数具有相同的类型,则无需进一步转换。
> - 否则,如果两个操作数都具有带符号整数类型,或者都具有无符号整数类型,则具有较低整数转换等级的操作数将被转换为具有较高等级的操作数的类型。
> - 否则,如果具有无符号整数类型的操作数的等级大于或等于另一个操作数的类型的等级,则具有带符号整数类型的操作数将被转换为具有无符号整数类型的操作数的类型。
> - 否则,如果具有带符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数的所有值,则具有无符号整数类型的操作数将被转换为具有带符号整数类型的操作数的类型。
> - 否则,将两个操作数都转换为具有带符号整数类型的操作数的类型所对应的无符号整数类型。

请注意那里的顺序 - 首先,如果适用,将类型转换为适当的浮点类型。

然后,“否则,对两个操作数执行整数提升。” 这很重要 - 类型小于int的变量在进行计算之前会提升为int(或unsigned int)。你提供的图表没有涉及到这一点。整数提升规定如下

> 如果int可以表示原始类型的所有值(如位域限制的宽度所限),则将该值转换为int;否则,将其转换为unsigned int。这被称为整数提升。

只有在这一切都完成后,整数等级才适用。

并且所有这些都是按操作符的优先级逐个执行的。如果你不了解这一点,有些结果可能会令人惊讶:

int a, b;
float x;

...

float y = x + a/b;

在这种情况下,计算a/b时使用整数算术,而不是浮点数。只有在将a/b计算为整数值后,它才会转换为float并添加到x中。因此,如果a小于b,则0.0将被添加到x

英文:

The image you have provided is wrong. First, it's flat-out incorrect to rank short int with char types. Per 6.3.1.1 Boolean, characters, and integers, paragraph 1 of the (draft) C11 standard:

> The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int, which shall be greater than the rank of short int, which shall be greater than the rank of signed char.

And C numeric types have a much more complex arrangement than the simple linear "rank" of the image.

Note that the floating point types float, double, and long double are not ranked with the integer types in 6.3.1.1 quoted above. As noted in the comments on your question, when numeric types are mixed they are subject to what are called usual arithmetic conversions:

> Many operators that expect operands of arithmetic type cause
> conversions and yield result types in a similar way. The purpose is to
> determine a common real type for the operands and result. For the
> specified operands, each operand is converted, without change of type
> domain, to a type whose corresponding real type is the common real
> type. Unless explicitly stated otherwise, the common real type is also
> the corresponding real type of the result, whose type domain is the
> type domain of the operands if they are the same, and complex
> otherwise. This pattern is called the usual arithmetic conversions:
>
> - First, if the corresponding real type of either operand is long double, the other operand is converted, without change of type domain,
> to a type whose corresponding real type is long double.
> - Otherwise, if the corresponding real type of either operand is double, the other operand is converted, without change of type domain,
> to a type whose corresponding real type is double.
> - Otherwise, if the corresponding real type of either operand is float, the other operand is converted, without change of type domain,
> to a type whose corresponding real type is float.62)
> - Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
> - If both operands have the same type, then no further conversion is needed.
> - Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser
> integer conversion rank is converted to the type of the operand with
> greater rank.
> - Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand,
> then the operand with signed integer type is converted to the type of
> the operand with unsigned integer type.
> - Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with
> unsigned integer type, then the operand with unsigned integer type is
> converted to the type of the operand with signed integer type.
> - Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer
> type.

Note the order there - first, types are converted to an appropriate floating point type, if applicable.

Then "Otherwise, the integer promotions are performed on both operands." That's important - variables of a type smaller than int are promoted to int (or unsigned int) before calculations are performed. The image you provided does not address that. Integer promotion is specified as:

> If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.

Only after all that are the integer ranks applicable.

And all of that is done on a per-operator basis, by precedence. Some results might be surprising if you weren't aware of that:

int a, b;
float x;

...

float y = x + a/b;

In that case, the calculation of a/b is done using integer arithmetic, not floating-point. Only after a/b is calculated as an integer value is it converted to a float and added to x. So if a is less than b, 0.0 will be added to x.

huangapple
  • 本文由 发表于 2023年5月29日 21:20:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357752.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定