Cprogramming 简明教程
Integer Promotions in C
@ {s20} 为了在整数的 @ {s22} 中实现一致性,将某些 @ {s21} 提升到了更高的等级。
The C compiler promotes certain data types to a higher rank for the sake of achieving consistency in the arithmetic operations of integers.
除了标准的 int 数据类型之外,C 语言还允许你使用其子类型,例如 char、short int、long int 等。每种数据类型都占据不同的内存空间。例如,标准 int 的大小为 4 个字节,而 char 类型的长度为 2 个字节。当算术运算涉及长度不相等的整数数据类型时,编译器采用整数提升策略。
In addition to the standard int data type, the C language lets you work with its subtypes such as char, short int, long int, etc. Each of these data types occupy a different amount of memory space. For example, the size of a standard int is 4 bytes, whereas a char type is 2 bytes of length. When an arithmetic operation involves integer data types of unequal length, the compiler employs the policy of integer promotion.
Integer Promotions
作为一般原则,当对 @ {s23} 类型进行运算时,小于 @ {s24} 的类型会被提升。如果原始类型的所有值都可以表示为 int,则较小类型的值将转换为 @ {s25};否则,将转换为 @ {s26}。
As a general principle, the integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int.
必须理解 @ {s27} 的概念才能编写可靠的 C 代码,并避免与数据类型大小和较小整数类型的算术运算有关的意外问题。
One must understand the concept of integer promotion to write reliable C code, and avoid unexpected problems related to the size of data types and arithmetic operations on smaller integer types.
Example
在这个示例中,两个 @ {s30} @ {s28} 和 @ {s29} 似乎存储相同的值,但它们不相等。
In this example, the two variables a and b seem to be storing the same value, but they are not equal.
#include <stdio.h>
int main(){
char a = 251;
unsigned char b = a;
printf("a = %c", a);
printf("\nb = %c", b);
if (a == b)
printf("\n Same");
else
printf("\n Not Same");
return 0;
}
当你运行这段代码时,它将产生以下输出:
When you run this code, it will produce the following output −
a = √
b = √
Not Same
你会得到此输出,因为在比较期间“a”和“b”被视为整数。“a”是已转换为 int 为 -5 的有符号 char,而“b”是已转换为 int 为 251 的无符号 char。
You get this output because "a" and "b" are treated as integers during comparison. "a" is a signed char converted to int as -5, while "b" is an unsigned char converted to int as 251.
Example: Mechanism of Integer Promotions
让我们尝试使用此示例了解整数提升的机制:
Let us try to understand the mechanism of integer promotions with this example −
#include <stdio.h>
int main(){
char a = 'e', b = '2', c = 'M';
char d = (a * b) / c;
printf("d as int: %d as char: %c", d, d);
return 0;
}
运行代码并检查其输出:
Run the code and check its output −
d as int: 65 as char: A
When Integer Promotion is Applied?
在算术表达式“(a * b)/ c”中,先解决括号。所有变量都是有符号 char 类型,长度为 2 个字节,可以存储 -128 到 127 之间的整数。因此,乘法超出了 char 的范围,但编译器不会报告任何错误。
In the arithmetic expression "(a * b) / c", the bracket is solved first. All the variables are of signed char type, which is of 2 byte length and can store integers between -128 to 127. Hence the multiplication goes beyond the range of char but the compiler doesn’t report any error.
C 编译器在处理涉及 char 等小型类型的算术运算时应用 @ {s31}。在乘以这些 char 类型之前,编译器将它们更改为 int 类型。因此,在这种情况下,(a * b)将转换为可以容纳乘积结果的 int,即 1200。
The C compiler applies integer promotion when it deals with arithmetic operations involving small types like char. Before the multiplication of these char types, the compiler changes them to int type. So, in this case, (a * b) gets converted to int, which can accommodate the result of multiplication, i.e., 1200.
Example
整数提升作为对某些参数表达式的通常算术转换的一部分应用;一元 +、 - 和 ~ 运算符的操作数;以及 @ {s32} 的操作数。看看以下示例:
Integer promotions are applied as part of the usual arithmetic conversions to certain argument expressions; operands of the unary +, -, and ~ operators; and operands of the shift operators. Take a look at the following example −
#include <stdio.h>
int main(){
char a = 10;
int b = a >> 3;
printf("b as int: %d as char: %c", b, b);
return 0;
}
当你运行这段代码时,它将产生以下输出:
When you run this code, it will produce the following output −
b as int: 1 as char:
在上面的示例中,将 "a" 的位结构向左移动三比特时,其值仍处于 char 范围内(a << 3 导致 80)。
In the above example, shifting the bit structure of "a" to the left by three bits still results in its value within the range of char (a << 3 results in 80).
Example
在这个例子中,char 变量的等级被提升为 int,以便其左移操作超出 char 类型的范围。
In this example, the rank of the char variable is prompted to int so that its left shift operation goes beyond the range of char type.
#include <stdio.h>
int main(){
char a = 50;
int b = a << 2;
printf ("b as int: %d as char: %c", b, b);
return 0;
}
运行代码并检查其输出:
Run the code and check its output −
b as int: 200 as char: ╚
Integer Promotion Rules
提升规则帮助 C 编译器保持一致性并避免意外结果。提升规则背后的基本原则是确保表达式类型进行调整以适应所涉及的最宽数据类型,从而防止数据丢失或截断。
Promotion rules help the C compiler in maintaining consistency and avoiding unexpected results. The fundamental principle behind the rules of promotion is to ensure that the expression’s type is adjusted to accommodate the widest data type involved, preventing data loss or truncation.
以下是根据 C11 规范的提升规则摘要−
Here is a summary of promotion rules as per C11 specifications −
-
The integer types in C are char, short, int, long, long long and enum. Booleans are also treated as an integer type when it comes to type promotions.
-
No two signed integer types shall have the same rank, even if they have the same representation.
-
The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.
-
The rank of long int > the rank of int > the rank of short int > the rank of signed char.
-
The rank of char is equal to the rank of signed char and unsigned char.
-
Whenever a small integer type is used in an expression, it is implicitly converted to int which is always signed.
-
All small integer types, irrespective of sign, are implicitly converted to (signed) int when used in most expressions.
简而言之,我们有以下整数提升规则−
In short, we have the following integer promotion rules −
-
Byte and short values − They are promoted to int.
-
If one operand is a long − The entire expression is promoted to long.
-
If one operand is a float − The entire expression is promoted to float.
-
If any of the operands is double − The result is promoted to double.
Example
这里,变量 x 和 y 是 char 数据类型。当对其执行除法运算时,它们会自动提升为 int,并将结果值存储在 z 中。
Here, the variables x and y are of char data type. When the division operation is performed on them, they automatically get promoted to int and the resultant value is stored in z.
#include <stdio.h>
int main(){
char x = 68;
char y = 34;
printf("The value of x is: %d", x);
printf("\nThe value of y is: %d", y);
char z = x/y;
printf("\nThe value of z: %d", z);
return 0;
}
当你运行这段代码时,它将产生以下输出:
When you run this code, it will produce the following output −
The value of x is: 68
The value of y is: 34
The value of z: 2