[英]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
参数并将其格式化为十进制数字。
因此,回顾一下:假设您有一台机器,
short int
是2个字节 ...然后,此程序将输出-108
(如果char
是有符号类型)或148
(如果char
是无符号类型)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.