-1

我想知道在各种位的无符号整数(即 uint8_t、uint16_t 等)之间的表达式的情况下如何隐式转换工作以及显式避免它的方法。为此,我总结了以下案例:

  • 在 uint8_t 加法、减法、乘法、除法的情况下,隐式转换如何工作?

    uint8_t A;
    uint8_t B;
    uint16_t C;
    
    C= A+B; (uint8_t + uint8_t )
    C= A-B; (uint8_t + uint8_t )
    C= A*B; (uint8_t + uint8_t )
    C= A/B; (uint8_t + uint8_t )

显式声明是 C= static_cast<uint16_t>A+B; 或 C= static_cast<uint16_t>(A+B);. 这是正确的吗?C= static_cast<uint16_t>A+B; 之间有什么区别吗?还是 C= static_cast<uint16_t>(A+B)?

  • 在 unsigned int(使用 U 文字)和 uint8_t 表达式的情况下,隐式转换如何工作?重要的顺序之间是否也有区别,即 1U B;(unsined int * uint8_t ) 或 B 1U;(uint8_t * uint8_t )

    C= A+1U;(uint8_t + uint8_t )
    C= A-1U;(uint8_t - uint8_t )
    C= 1U*B;(uint8_t * uint8_t )
    C= 1U/B;(uint8_t / uint8_t )

显式转换为 C= static_cast<uint16_t>A+1U; 或 C= static_cast<uint16_t>(A+1U); C= static_cast<uint16_t>1UB ;或 C= static_cast<uint16_t>(1UB );. 这是正确的这些行之间有什么区别吗?

  • 表达式的隐式转换如何工作。是否考虑到正常顺序?表达式的最终类型是什么?

    C= 1U/(A-1U);  (unsigned int / (uint8_t -(unsigned int))
    C= (C-(A/B))/B; (uint8_t -(uint8_t /(unsigned int))/(uint8_t)

在这种情况下 static_cast 应该如何看待?只有第一个变量(1U 或 C)将为其余变量定义 C= static_cast<uint8_t >(1U)/(A-1U);

  • 标准函数的隐式转换如何工作

    sizeof(A) returns size_t 
    C=abs(-1*A) returns int in case of int parmaters    

        

显式转换为 C= static_cast<uint16_t>sizeof(A) 和 C= static_cast<uint16_t>abs(-1*A)。那是对的吗?C= static_cast<uint16_t>abs(-1)*A) 怎么样?

  • 函数参数的隐式转换如何工作。

    uint16_t sum(uint16_t C1,uint16_t C2);
    C=sum(A,B-1U/2U);           
    C=sum(A,1U/2U-B);

显式转换为 C= sum(static_cast<uint16_t>(A),static_cast<uint16_t>(B-1U/2U))。那是对的吗?

我在 Opencv 中看到了一个类似于 static_cast 的函数,称为 saturate_cast。在上述任何情况下,这会是更好的解决方案吗?

4

1 回答 1

0

在 uint8_t 加法、减法、乘法、除法的情况下,隐式转换如何工作?

uint8_t转换等级低于type并且inttypeint总是可以容纳 的整个值范围uint8_tUINT8_MAX为 255 并且至少int具有16 位。将在运营商之前通过积分晋升。cppreference 积分提升基本类型cstdintuint8_tint

显式声明是 C= static_cast<uint16_t>A+B; 或 C= static_cast<uint16_t>(A+B);。这个对吗?

不,这些不是声明示例,缺少类型说明符。他们operator=用来为 object 赋值C。“显式声明”是使用auto关键字的声明。cppreference 声明

C= static_cast<uint16_t>A+B; 之间有什么区别吗?还是 C= static_cast<uint16_t>(A+B)?

是的,在int不能容纳所有值范围的架构上uint16_t。在这种特殊情况下,第一个表达式首先将+operator 的操作数提升为unsigned int,而第二个表达式使用int类型进行操作。第二个表达式与 相同C = A + B,因为C有类型uint16_t。除了这种特殊情况,在int可以保存 的所有值范围的架构上uint16_t,两个操作数都将提升为intC= static_cast<uint16_t>(A+B)是一样的C = A + B

在 unsigned int(使用 U 文字)和 uint8_t 表达式的情况下,隐式转换如何工作?

首先,两个操作数都经过积分提升unsigned int留下并uint8_t晋升为int。然后操作数进行整数转换。因为其中一个操作数是unsigned并且两个操作数具有相同的转换等级,所以有符号操作数被转换为无符号类型,即。int被转换为unsigned int算术运算符和算术转换

重要的顺序之间是否也有区别,即1U*B;(unsined int * uint8_t )B*1U;(uint8_t * uint8_t )

不,操作数的顺序无关紧要。

显式转换为 C= static_cast<uint16_t>A+1U; 或 C= static_cast<uint16_t>(A+1U); C= static_cast<uint16_t>1UB;或 C= static_cast<uint16_t>(1UB);。这是正确的这些行之间有什么区别吗?

static_cast<uint16_t>1UB是语法错误。C = static_cast<declatype(C)>(expr)总是等于C = expr

表达式的隐式转换如何工作。是否考虑正常顺序?

我不明白什么是“正常订单”。操作数和表达式根据它们的优先级进行计算。

表达式的最终类型是什么?

 C= 1U/(A-1U);  (unsigned int / (uint8_t -(unsigned int))

右侧的表达式operator=unsigned int类型的右值。

 C= (C-(A/B))/B; (uint8_t -(uint8_t /(unsigned int))/(uint8_t)

右侧的表达式operator=unsigned int类型的右值。

在这种情况下 static_cast 应该如何看待?

和其他任何地方一样static_cast<type>(expr)

只有第一个变量(1U 或 C)将为其余变量定义 C= static_cast<uint8_t >(1U)/(A-1U);

每个运算符分别计算其操作数,一次计算一个或两个表达式。评估(以及提升)的顺序是根据运算符的优先级排序的。评估顺序优先级和关联性

标准函数的隐式转换如何工作?

与根据整数促销规则的任何其他类型一样。size_t只是一个实现定义的无符号整数类型。

显式转换为 C= static_cast<uint16_t>sizeof(A) 和 C= static_cast<uint16_t>abs(-1*A)。那是对的吗?

两个表达式都是语法错误。是static_cast<type> ( expression )。大括号是强制性的。答案见上文-doingC = static_cast<decltype(C)>(expr)就等于C = expr

C= static_cast<uint16_t>abs(-1)*A) 怎么样?

怎么样?

函数参数的隐式转换如何工作。

当参数不是可变参数函数调用中省略号的一部分时,参数将转换为参数类型。

显式转换为 C= sum(static_cast<uint16_t>(A),static_cast<uint16_t>(B-1U/2U))。那是对的吗?

是的,但是为了什么?uint16_t无论如何,它们将被转换为。

我在 Opencv 中看到了一个类似于 static_cast 的函数,称为saturate_cast. 在上述任何情况下,这会是更好的解决方案吗?

“更好”是基于意见和模糊的。这取决于您想要达到的目标。这saturate_cast是一个简单的模板,专门处理具有范围刨丝器然后是目标范围的类型。在这种情况下,参数将转换为该类型的最大值/最小值。

为进一步研究,。c++ 标准草案可在线获取

于 2020-06-27T12:21:24.263 回答