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

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_tC11 Standard - 6.5.16.1 Simple assignment(p2)),而是范围问题。int x;是一个32位有符号整数,能够保存-2147483648 to 2147483647范围内的值。相反,uint8_t y;是一个无符号的8位值,能够保存值0 - 255
您可以很容易地为x指定一个超出y范围的值。那么接下来会发生什么呢?如果x的值超过y的范围,则x的值将被减模1 + max_for_type以适合yC11 Standard - 6.2.5 Types(p9)的范围,因此对于超过y = x % 256;x的值,赋值等价于uint8_t
例如x = 25306708;然后当x转换为uint8_t时,将y = x;x的模256减小为适合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

回答:
“在C语言中,总是显式地转换变量是一种好的做法吗?”
不。如果您所做的操作涉及不兼容的类型,强制转换将屏蔽编译器将生成的警告。您应该只在库API等明确需要的地方进行很少的强制转换。。
再看一遍,如果你还有问题,请告诉我。

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

10-11 19:31
查看更多