当前位置: 首页 > 知识库问答 >
问题:

还有关于整数提升的问题,C语言中的转换

姚树
2023-03-14

这个话题已经在很多场合被大量讨论过。当我搜索和阅读一些帖子时。我被下面的帖子搞糊涂了。

C语言中的有符号到无符号转换——总是安全的吗?

以下是原题。

unsigned int u = 1234;
int i = -5678;
unsigned int result = u + i;

答案只是引用了“6.3.1.8通常算术转换”第3点,即,

否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数类型的秩,则具有有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型。

然而,如果我的理解是正确的,整数提升应该在考虑“常用算术转换”之前进行。

这方面的规则是

如果int可以表示原始类型的所有值,则该值将转换为int。否则,它将转换为无符号整数。这些转换规则称为积分升级

因此,这意味着添加是使用有符号int类型而不是无符号int类型完成的。当将负数赋值为无符号int结果时,会发生向大值的转换。

我对自己的理解有点不自信。有人在那篇帖子上有类似的困惑吗?

欢迎任何回复或评论。感谢提前!

杰夫

共有3个答案

景永望
2023-03-14

我将使用十六进制表示来解释这个问题...

假设int变量的大小为32位:

  • 1234=0x000004D2
  • -5678=0xFFFFE9D2

当执行ab时,它们中的每一个如何表示都无关紧要(有符号的无符号的)。如果将上述两个值相加,并将结果存储int变量中,则无论每个操作数的符号是什么,它都将保留0xFFFFEEA4的值:

  • 如果输出变量是有符号的,那么它(在其他操作中)将被视为-4444
  • 如果输出变量无符号,则它将被视为(在其他操作中)4294962852
朱通
2023-03-14

然而,如果我的理解是正确的,整数提升应该在考虑“常用算术转换”之前进行。

正确,但是整数升级规则定义的整数升级只适用于小整数类型,例如char和short。你只引用了这一段的一半,这可能会让你感到困惑。让我完整地引用这一段:

C116.3.1.1/2

在表达式中使用int或unsigned int时,可以使用以下内容:

>

  • 整数类型(int或unsigned int除外)的对象或表达式,其整数转换秩小于或等于int和unsigned int的秩。

    类型为_Bool、int、signed int或unsigned int的位字段。

    如果一个int可以表示原始类型的所有值(受宽度限制,对于一个位字段),则该值将转换为int;否则,它将被转换为无符号整数。这些被称为整数。所有其他类型都不受整数升迁的影响。

    因此,整数提升不适用于int无符号int,因为它们没有较小的转换排名。

    因此,这意味着添加是使用有符号int类型而不是无符号int类型完成的。当将负数赋值为无符号int结果时,会发生向大值的转换。

    不正确,由于通常的算术转换,加法是在usigned int上完成的。

  • 许俊晤
    2023-03-14
    unsigned int result = u + i;
    

    我们有一个加法运算符。算术型操作数的加法运算符首先执行通常的算术转换。

    通常的算术转换分两步进行:

    第一个整数提升应用于每个操作数:

    • u不会升级为int,因为它是无符号int

    由于操作数实际上具有等于int的类型秩,因此不执行整数提升。

    第二,将操作数转换为公共类型。常见的类型是无符号int

    • u已经是unsigned int
    • i是类型int并转换为无符号int

    在通常的算术转换之后,添加类型为无符号int的两个值,并将结果分配给result

     类似资料:
    • 主要内容:整型的长度,sizeof 操作符,不同整型的输出整数是编程中常用的一种数据,C语言通常使用 来定义整数(int 是 integer 的简写),这在《 大话C语言变量和数据类型》中已经进行了详细讲解。 在现代操作系统中,int 一般占用 4 个字节(Byte)的内存,共计 32 位(Bit)。如果不考虑正负数,当所有的位都为 1 时它的值最大,为 2 32-1 = 4,294,967,295 ≈ 43亿,这是一个很大的数,实际开发中很少用到,而诸

    • 老师们好, 下面这段代码,解码这样一段base64编码的字符串(KioqKipAI++/pSXigKbigKYmKiPvv6Ul4oCm4oCmJio=), 后面多了个“)” 解码正确的内容是:*****@#¥%……&*#¥%……&* 解码错误的内容是:*****@#¥%……&*#¥%……&) 找不到原因了, 请老师们帮忙看看。

    • 本文向大家介绍C语言将数组中元素的数排序输出的相关问题解决,包括了C语言将数组中元素的数排序输出的相关问题解决的使用技巧和注意事项,需要的朋友参考一下  问题描述:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{32,  321},则输出这两个能排成的最小数字32132。请给出解决问题的算法,并证明该算法。       思路:先将整数数组转为字符串数组

    • 问题内容: 我有一些旧的(损坏的)代码,使用* =进行了联接 这是左外部连接还是右外部连接?(我的错误消息表明它是其中之一) 问题答案: 而是利用

    • 场景: 如下图, 红框中的数据是后台传过来的时间, 因为是一串字符串, 在 ts 中我就没办法对这个时间做处理 (例如转成数字、获取年月日等) 对应的 ts 代码 问题简述1: 我在model中定义的 createTime 和 updateTime, 都是 number 类型, 并且我在接收 res 时候已经指定接收对象是一个 Icon 类型的数组了, 但为什么我最终 res.icons[0].c

    • 我们在前面学习了 C 语言的数据类型,那么变量在参与运算的时候类型是始终如一不变的吗? 带着这个疑问,我们可以先看一个例子: #include <stdio.h> #define typename(x) _Generic((x), /* Get the name of a type */