c语句算数运算中的隐式转换规则

算术转换规则

  1. 整型提升(Integer Promotion)

    • 在进行算术运算之前,小于 int 类型的整型(如 charshort)会被提升到 int 类型。如果 int 类型无法表示该值,则提升到 unsigned int
  2. 算术转换(Arithmetic Conversion)

    • 当两个操作数的类型不同且至少有一个操作数是 unsigned long long int 时,所有操作数都被转换为 unsigned long long int 类型。
    • 如果操作数中有 long long int,但没有 unsigned long long int,则所有操作数都会被转换为 long long int 类型。
    • 如果操作数中有 unsigned long,但没有 long long intunsigned long long int,则所有操作数都会被转换为 unsigned long 类型。
    • 如果操作数中有 long,但没有 unsigned longlong long intunsigned long long int,则所有操作数都会被转换为 long 类型。
    • 如果操作数中有 unsigned int,但没有 longunsigned longlong long intunsigned long long int,则所有操作数都会被转换为 unsigned int 类型。
    • 如果操作数中只有 int,则所有操作数都会被转换为 int 类型。

关键规则

  • 整型提升:较小的整型(如 charshort)在运算前会被提升到 int 类型。
  • 共同类型转换:不同类型的操作数会被转换为一个共同的类型,通常是其中范围最大的一种类型。

示例

考虑以下代码示例1:

#include <stdio.h>

int main() {
    char a = 100;
    unsigned long long b = 300;
    unsigned long long result = a * b; // 运算过程中发生类型转换

    printf("Result: %llu\n", result);
    return 0;
}
解释:
  1. 整型提升

    • achar 类型,会被提升到 int 类型。
  2. 算术转换

    • 运算 a * b 中,a 提升为 int,然后 int 类型的结果会被转换为 unsigned long long 类型进行乘法运算。
    • 最终的乘法结果是 unsigned long long 类型,存储在 result 中。

考虑以下代码示例2:

#include <stdio.h>

int main() {
    char c = 100;
    unsigned long long int b = c * 0xffffffffu;
    unsigned long long int d = c * 0xffffffffull;
    printf("%llu, %llu\n", b, d);
    return 0;
}

解释

  1. 类型提升和运算

    • char c = 100;cchar 类型,值为 100。
    • 在算术运算之前,c 会被提升为 int 类型。因此,100 作为 int 参与运算。
  2. 运算 c * 0xffffffffu

    • 0xffffffffu 是一个 unsigned int 类型的常量,值为 4294967295。
    • 由于 c 被提升为 unsigned int 类型,运算 100 * 4294967295unsigned int 类型中进行。
    • 计算结果是 429496729500,但由于 unsigned int 的范围有限(32 位),会发生溢出。溢出后的结果是 429496729500 % 4294967296,计算结果是 429496729500 - 42949672960 * 10 = 429496729500 - 42949672960 = 4294967196
  3. 运算 c * 0xffffffffull

    • 0xffffffffullunsigned long long int 类型的常量,值为 4294967295。ull 后缀表示 unsigned long long int 类型。
    • 运算 100 * 4294967295unsigned long long int 类型中进行,计算结果是 429496729500,没有溢出,因为 unsigned long long int 可以表示更大的值。
  4. 结果存储和打印

    • b 存储了 unsigned int 类型运算后的溢出结果 4294967196
    • d 存储了 unsigned long long int 类型的结果 429496729500
    • printf("%llu, %llu\n", b, d); 将输出 bd 的值。

总结

  • b 的结果100 * 0xffffffffuunsigned int 类型中计算,发生溢出,结果是 4294967196
  • d 的结果100 * 0xffffffffullunsigned long long int 类型中计算,没有溢出,结果是 429496729500
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值