繁体   English   中英

以下C代码的输出

[英]Output of the following C code

以下C代码的输出是什么。 假设它在Little endian机器上运行,其中short int需要2字节,而char需要1字节。

#include<stdio.h>
int main() {
    short int c[5];
    int i = 0;
    for(i = 0; i < 5; i++)
        c[i] = 400 + i;
    char *b = (char *)c;
    printf("%d", *(b+8));
    return 0;
}

在我的机器上

-108

我不知道我的机器是Little Endian还是Big Endian。 我发现应该给的地方

148

作为输出。 因为404(即元素c [4])的低8位是148。但是我认为由于“%d”,它应该从c [4]的地址开始从内存中读取2个字节。

该代码在不同的计算机上提供不同的输出,因为在某些平台上, char类型默认情况下是带符号的,而在其他平台上则默认情况下是不带符号的。 这与字节序无关。 尝试这个:

    char *b = (char *)c;
    printf("%d\n", (unsigned char)*(b+8)); // always prints 148 
    printf("%d\n", (signed char)*(b+8));   // always prints -108 (=-256 +148)

默认值取决于平台和编译器设置。 您可以使用GCC选项-fsigned-char-funsigned-char来控制默认行为。

要查看系统中有哪些尺寸类型:

printf("char = %u\n", sizeof(char));    
printf("short = %u\n", sizeof(short));    
printf("int = %u\n", sizeof(int));    
printf("long = %u\n", sizeof(long));    
printf("long long = %u\n", sizeof(long long));  

更改程序中的行

unsigned char *b = (unsigned char *)c;
printf("%d\n", *(b + 8));

和简单的测试(我知道不能保证,但是我知道的所有C编译器都是这样做的,而且我并不关心具有不同地址和指向不同类型数据的指针的旧CDC或UNISYS计算机

printf(" endianes test: %s\n", (*b + (unsigned)*(b + 1) * 0x100) ==  400? "little" : "big");

另一句话:这仅仅是因为在您的程序中c [0] == 400

c[4]存储404 在两字节的Little-endian表示中,这意味着两个字节0x94 0x01或(十进制) 148 1

b+8寻址c[4]的内存。 b是指向char的指针,因此8表示添加8个字节(这是4个2个字节的短裤)。 换句话说, b+8指向c[4]的第一个字节,其中包含148

*(b+8) (也可以写为b[8] )取消引用指针,因此将值148作为char 这是由实现定义的:在许多常见平台上, char是带符号的类型(范围为-128 .. 127 ),因此实际上不能为148 但是,如果它是无符号类型(范围为0 .. 255 ),则148很好。

二进制148的位模式是10010100 将此解释为二进制补码可以得到-108

然后,此char值(为148-108 )将自动转换为int因为它出现在变量参数函数( printf )的参数列表中。 这不会更改值。

最后, "%d"告诉printf使用int参数并将其格式化为十进制数字。

因此,回顾一下:假设您有一台机器,

  • 一个字节是8位
  • 负数使用二进制补码
  • short int是2个字节

...然后,此程序将输出-108 (如果char是有符号类型)或148 (如果char是无符号类型)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM