在下面的示例中:

int main(int argc, char *argv[])
{
    int16_t array1[] = {0xffff,0xffff,0xffff,0xffff};
    char array2[] = {0xff,0xff,0xff,0xff};
    printf("Char size: %d \nint16_t size: %d \n", sizeof(char), sizeof(int16_t));

    if (*array1 == *array2)
        printf("They are the same \n");
    if (array1[0] == array2[0])
        printf("They are the same \n");

    printf("%x \n", array1[0]);
    printf("%x \n", *array1);

    printf("%x \n", array2[0]);
    printf("%x \n", *array2);
}

输出:
Char size: 1
int16_t size: 2
They are the same
They are the same
ffffffff
ffffffff
ffffffff
ffffffff

为什么打印charint16_t的32位值,为什么可以比较它们并认为它们相同?

最佳答案

它们是相同的,因为它们都是-1的不同表示。
它们打印为32位的ff值,因为您在32位计算机上,并且使用了%d并且发生了默认参数提升(基本上,所有较小的参数都会提升为int)尝试使用%hx(这可能会让您ffff;除了使用ff或使用unsigned char& 0xff掩蔽之外,我不知道还有什么方法可以获得printf("%x \n", array2[0] & 0xff)
扩展到“它们是相同的,因为它们都是-1的不同表示”:
int16_t是有符号的16位类型。它可以包含-32768到+32767范围内的值。
char是一种8位类型,在您的机器上它显然也有签名所以它可以包含-128到+127范围内的值。
0xff是十进制255,不能用有符号字符表示的值。如果将0xff赋给一个有符号的字符,那么这个位模式最终会被解释为-1,而不是255(类似地,如果您分配了0xfe,则它将被解释为-2,而不是254。)
0xffff是十进制65535,不能用int16_t表示。如果将0xffff赋给int16_t,则该位模式最终将被解释为-1,而不是65535(类似地,如果您分配了0xfffe,则它将被解释为-2,而不是65534。)
所以当你说

int16_t array1[] = {0xffff,0xffff,0xffff,0xffff};

基本上就像你说的
int16_t array1[] = {-1,-1,-1,-1};

当你说
char array2[] = {0xff,0xff,0xff,0xff};

就好像你说过
char array2[] = {-1,-1,-1,-1};

所以这就是为什么。
另外,值得注意的是,所有这些都是因为*array1 == *array2array1[0] == array2[0]的类型如果你说
uint16_t array3[] = {0xffff,0xffff,0xffff,0xffff};
unsigned char array4[] = {0xff,0xff,0xff,0xff};

您将看到打印的值不同(array1array2),并且来自ffffff的值不会进行相同的比较。
另一个答案是“运行时C中没有类型信息”这是真的,但在这件事上有误导性当编译器生成代码来操作array3array4array1array2中的值时,它生成的代码(当然,这在运行时很重要!)将基于其类型特别是,当生成从array3array4获取值的代码(但不是array1array2)时,编译器将使用在分配给更大类型的对象(例如32位)时执行符号扩展的指令这就是0xff和0xffff如何变为0xFFFFFF的原因。

关于c - Char和int16数组元素都显示为32bit十六进制?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31562375/

10-10 21:24