gpt4 book ai didi

c - C 赋值和参数传递会导致隐式转换,还是我们应该显式转换?

转载 作者:太空宇宙 更新时间:2023-11-04 07:47:55 24 4
gpt4 key购买 nike

下面两段代码有什么区别吗?

答:

int x = get_some_int();
uint8_t y = x;

乙:

int x = get_some_int();
uint8_t y = (uint8_t) x;

此外,如果 y 是一个函数的 uint8_t 参数并且 x 被传递给它(有和没有显式转换)怎么办? ?

编辑:请允许我重新表述这个问题:在 C 语言中,在分配或传递给不同类型时始终显式转换变量是否是一种好的做法?还是将其留给编译器是一种好习惯?程序员应该“默认”做什么?

最佳答案

问题不是转换问题之一(不要求赋值是直接转换为 uint8_t C11 Standard - 6.5.16.1 Simple assignment(p2) ),问题是范围问题之一。 int x; 是一个 32 位有符号整数,能够保存 -2147483648 到 2147483647 范围内的值。相比之下,uint8_t y; 是一个无符号的 8 位值,能够保存值 0 - 255

您可以轻松地为 x 分配一个超出 y 范围的值。那么会发生什么呢?如果x的值超出y的范围,则x的值以1 + max_for_type为模减少为适合 y C11 Standard - 6.2.5 Types(p9)因此,对于超出 uint8_t 范围的 x 值,赋值等同于 y = x % 256;

例如 x = 25306708; 那么当 x 转换为 uint8_ty = x; x256 为模减少以适应 y。 (例如 y == 84)

如果您想避免静默减少值以适应 y,那么您需要测试 x 的值是否适合 >y 没有减少。您可以使用 stdint.h 中定义的简单条件和常量来做到这一点,例如

    y = x;  /* direct assignment, no cast required */

if (0 <= x && x <= UINT8_MAX) /* validate x within the range of uint8_t */
printf ("int x: %d is in range of uint8_t y: %" PRIu8 "\n", x, y);
else
/* handle the error as required */

将一个简短的例子放在一起展示行为,你可以这样做:

#include <stdio.h>
#include <inttypes.h> /* includes stdint.h */

int main (void) {

int x;
uint8_t y;

fputs ("enter a value: ", stdout);
if (scanf ("%d", &x) != 1) {
fputs ("error: invalid integer value.\n", stderr);
return 1;
}
y = x; /* direct assignment, no cast required */

if (0 <= x && x <= UINT8_MAX) /* validate x within the range of uint8_t */
printf ("int x: %d is in range of uint8_t y: %" PRIu8 "\n", x, y);
else
printf ("x: %d exceeds range of uint8_t, reduced modulo to y: %"
PRIu8 "\n", x, y);
}

示例使用/输出

$ ./bin/intuint8_t
enter a value: 254
int x: 254 is in range of uint8_t y: 254

$ ./bin/intuint8_t
.enter a value: 256
x: 256 exceeds range of uint8_t, reduced modulo to y: 0

$ ./bin/intuint8_t
enter a value: 25306708
x: 25306708 exceeds range of uint8_t, reduced modulo to y: 84

回答:

"Is it the good practice in C to always explicitly cast variables"

否。如果您正在执行的操作涉及不兼容的类型,转换将掩盖编译器将生成的警告。您应该很少进行转换,并且仅在库 API 等明确需要的地方进行转换。

检查一下,如果您还有其他问题,请告诉我。

关于c - C 赋值和参数传递会导致隐式转换,还是我们应该显式转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55768679/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com