我不明白为什么以下代码打印出来7 2 3 0
我希望它打印出1 9 7 1
。任何人都可以解释为什么打印7230
?:
unsigned int e = 197127;
unsigned char *f = (char *) &e;
printf("%ld\n", sizeof(e));
printf("%d ", *f);
f++;
printf("%d ", *f);
f++;
printf("%d ", *f);
f++;
printf("%d\n", *f);
答案 0 :(得分:3)
你不懂二进制。这是程序员应该知道的最基本的东西之一。计算机不能使用小数。
197127 10 = 00030207 16 = 0011 0000 0010 0000 0111 2
假设您的系统是x86,它是小端,因此0x00030207
将以0x07 0x02 0x03 0x00
的形式存储在内存中,并按预期打印出来(7 2 3 0)
答案 1 :(得分:2)
因为使用您的方法,您打印出unsigned
的内部表示而不是其十进制表示。
整数或任何其他数据在内部表示为字节。在这种情况下,unsigned char
只是“字节”的另一个术语。如果你在字符串
char E[] = "197127";
然后在字节中进行了一次异步遍历,你会看到字符的表示形式为数字。
答案 2 :(得分:2)
“197127”的二进制表示是“00110000001000000111”。 字节看起来像“00000111”(十进制7),“00000010”(是2),“0011”(是3)。剩下的就是0。
答案 3 :(得分:1)
为什么期望1 9 7 1
? 197127的十六进制表示为0x00030207
,因此在小端架构上,第一个字节为0x07
,第二个0x02
,第三个0x03
和第四个0x00
,这正是你得到的。
答案 4 :(得分:1)
e as 197127的值不是字符串表示。它存储为16/32位整数(取决于平台)。因此,在内存中,e被分配,比如堆栈上的4个字节,并且将在该内存位置表示为0x30207(十六进制)。在二进制文件中,它看起来像110000001000000111.注意“endian”实际上是向后的。请参阅此link account endianess.因此,当您将f指向& e时,您将引用数值的第一个字节,如果要将数字表示为字符串,则应该
char *e = "197127"
答案 5 :(得分:1)
数字e
的基础表示位于binary,如果我们将值转换为 hex ,我们可以看到该值为(假设为32 bit unsigned int ):
0x00030207
因此,当您遍历内容时,您将通过* unsigned char **逐字节读取。每个字节包含两个4位十六进制数字,并且该数字的字节顺序endiannes是小端,因为最低有效字节( 0x07 )是第一个所以记忆内容如下:
0x07020300
^ ^ ^ ^- Fourth byte
| | |-Third byte
| |-Second byte
|-First byte
请注意sizeof
返回size_t
,正确的格式说明符为%zu,否则您有undefined behavior。
您还需要修复此行:
unsigned char *f = (char *) &e;
为:
unsigned char *f = (unsigned char *) &e;
^^^^^^^^
答案 6 :(得分:1)
这与存储整数的方式有关,更具体地说是字节排序。您的系统恰好具有小端字节排序,即多字节整数的第一个字节最不重要,而最后一个字节最重要。
你可以试试这个:
printf("%d\n", 7 + (2 << 8) + (3 << 16) + (0 << 24));
这将打印197127
。
详细了解字节顺序字节顺序here。
答案 7 :(得分:1)
无符号整数197127
的字节布局为[0x07, 0x02, 0x03, 0x00]
,您的代码打印出四个字节。
如果您想要小数位数,则需要将数字分解为数字:
int digits[100];
int c = 0;
while(e > 0) { digits[c++] = e % 10; e /= 10; }
while(c > 0) { printf("%u\n", digits[--c]); }
答案 8 :(得分:1)
您知道int
的类型经常发生四个字节。这意味着197127
在内存中显示为00000000 00000011 00000010 00000111
。从结果来看,您的记忆地址为Little-Endian
。这意味着,低字节0000111
分配在低地址,然后是00000010
和00000011
,最后是00000000
。因此,当您首先输出f为int
时,通过type cast
获得7
。截至f++
,f指向00000010
,输出为2
。其余的可以通过类比推断出来。
答案 9 :(得分:0)
因为e
是一个整数值(可能是4个字节)而不是一个字符串(每个字符1个字节)。
要获得您期望的结果,您应该更改e
的声明和作业:
unsigned char *e = "197127";
unsigned char *f = e;
或者,将整数值转换为字符串(使用sprintf())并让f
指向该字符串:
char s[1000];
sprintf(s,"%d",e);
unsigned char *f = s;
或者,使用数学运算从整数中获取单个数字并将其打印出来。
或者......,