[英]Unsigned Char pointing to unsigned integer
I don't understand why the following code prints out 7 2 3 0
I expected it to print out 1 9 7 1
. 我不明白为什么以下代码打印
7 2 3 0
我希望它打印出1 9 7 1
。 Can anyone explain why it is printing 7230
?: 任何人都可以解释为什么它打印
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);
Computers work with binary, not decimal, so 197127 is stored as a binary number and not a series of single digits separately in decimal 计算机使用二进制,而不是十进制,因此197127存储为二进制数,而不是十进制分别存储的一系列单个数字
197127 10 = 00030207 16 = 0011 0000 0010 0000 0111 2 197127 10 = 00030207 16 = 0011 0000 0010 0000 0111 2
Suppose your system uses little endian , 0x00030207
would be stored in memory as 0x07 0x02 0x03 0x00
which is printed out as (7 2 3 0) as expected when you print out each byte 假设您的系统使用小端 ,
0x00030207
将作为0x07 0x02 0x03 0x00
存储在内存中,当您打印出每个字节时,它会按预期打印为(7 2 3 0)
Because with your method you print out the internal representation of the unsigned
and not its decimal representation. 因为使用您的方法,您打印出
unsigned
的内部表示,而不是其十进制表示。
Integers or any other data are represented as bytes internally. 整数或任何其他数据在内部表示为字节。
unsigned char
is just another term for "byte" in this context. unsigned char
只是这个上下文中“byte”的另一个术语。 If you would have represented your integer as decimal inside a string 如果您在字符串中将整数表示为十进制
char E[] = "197127";
and then done an anologous walk throught the bytes, you would have seen the representation of the characters as numbers. 然后在字节中完成一个异步遍历,你会看到字符的表示形式为数字。
Binary representation of "197127" is "00110000001000000111". “197127”的二进制表示是“00110000001000000111”。 The bytes looks like "00000111" (is 7 decimal), "00000010" (is 2), "0011" (is 3).
字节看起来像“00000111”(十进制7),“00000010”(是2),“0011”(是3)。 the rest is 0.
剩下的就是0。
Why did you expect 1 9 7 1
? 你为什么期望
1 9 7 1
? The hex representation of 197127 is 0x00030207
, so on a little-endian architecture, the first byte will be 0x07
, the second 0x02
, the third 0x03
, and the fourth 0x00
, which is exactly what you're getting. 197127的十六进制表示为
0x00030207
,因此在小端架构上,第一个字节将是0x07
,第二个0x02
,第三个0x03
和第四个0x00
,这正是您所获得的。
The value of e as 197127 is not a string representation. e为197127的值不是字符串表示。 It is stored as a 16/32 bit integer (depending on platform).
它存储为16/32位整数(取决于平台)。 So, in memory, e is allocated, say 4 bytes on the stack, and would be represented as 0x30207 (hex) at that memory location.
因此,在内存中,e被分配,比如堆栈上的4个字节,并且将在该内存位置表示为0x30207(十六进制)。 In binary, it would look like 110000001000000111. Note that the "endian" would actually backwards.
在二进制文件中,它看起来像110000001000000111.注意“endian”实际上是向后的。 See this link account endianess.
请参阅此链接帐户endianess。 So, when you point f to &e, you are referencing the 1st byte of the numeric value, If you want to represent a number as a string, you should have
因此,当您将f指向&e时,您将引用数值的第一个字节,如果要将数字表示为字符串,则应该具有
char *e = "197127"
The underlying representation of the number e
is in binary and if we convert the value to hex we can see that the value would be( assuming 32 bit unsigned int ): 数字
e
的基础表示是二进制的 ,如果我们将值转换为十六进制,我们可以看到该值将是( 假设32位无符号整数 ):
0x00030207
so when you iterate over the contents you are reading byte by byte through the *unsigned char **. 因此,当您遍历内容时,您将通过* unsigned char **逐字节读取。 Each byte contains two 4 bit hex digits and the byte order endiannes of the number is little endian since the least significant byte( 0x07 ) is first and so in memory the contents are like so:
每个字节包含两个4位十六进制数字,并且数字的字节顺序字节序是小端,因为最低有效字节( 0x07 )是第一个,因此在内存中内容如下:
0x07020300
^ ^ ^ ^- Fourth byte
| | |-Third byte
| |-Second byte
|-First byte
Note that sizeof
returns size_t
and the correct format specifier is %zu , otherwise you have undefined behavior . 请注意,
sizeof
返回size_t
,正确的格式说明符是%zu ,否则您有未定义的行为 。
You also need to fix this line: 您还需要修复此行:
unsigned char *f = (char *) &e;
to: 至:
unsigned char *f = (unsigned char *) &e;
^^^^^^^^
This has to do with the way the integer is stored, more specifically byte ordering. 这与存储整数的方式有关,更具体地说是字节排序。 Your system happens to have little-endian byte ordering, ie the first byte of a multi byte integer is least significant, while the last byte is most significant.
您的系统恰好具有小端字节排序,即多字节整数的第一个字节最不重要,而最后一个字节最重要。
You can try this: 你可以试试这个:
printf("%d\n", 7 + (2 << 8) + (3 << 16) + (0 << 24));
This will print 197127
. 这将打印
197127
。
Read more about byte order endianness here . 在这里阅读有关字节顺序字节序的更多信息。
The byte layout for the unsigned integer 197127
is [0x07, 0x02, 0x03, 0x00]
, and your code prints the four bytes. 无符号整数
197127
的字节布局是[0x07, 0x02, 0x03, 0x00]
197127
[0x07, 0x02, 0x03, 0x00]
,您的代码打印出四个字节。
If you want the decimal digits, then you need to break the number down into digits: 如果你想要十进制数字,那么你需要将数字分解为数字:
int digits[100];
int c = 0;
while(e > 0) { digits[c++] = e % 10; e /= 10; }
while(c > 0) { printf("%u\n", digits[--c]); }
You know the type of int
often take place four bytes. 你知道
int
的类型经常发生四个字节。 That means 197127
is presented as 00000000 00000011 00000010 00000111
in memory. 这意味着
197127
在内存中显示为00000000 00000011 00000010 00000111
。 From the result, your memory's address are Little-Endian
. 从结果来看,你的记忆地址是
Little-Endian
。 Which means, the low-byte 0000111
is allocated at low address, then 00000010
and 00000011
, finally 00000000
. 这意味着,低字节
0000111
分配在低地址,然后是00000010
和00000011
,最后是00000000
。 So when you output f first as int
, through type cast
you obtain a 7
. 因此,当您首先输出f作为
int
,通过type cast
获得7
。 By f++
, f points to 00000010
, the output is 2
. 通过
f++
,f指向00000010
,输出为2
。 The rest could be deduced by analogy. 其余的可以通过类比推断出来。
Because e
is an integer value (probably 4 bytes) and not a string (1 byte per character). 因为
e
是整数值(可能是4个字节)而不是字符串(每个字符1个字节)。
To have the result you expect, you should change the declaration and assignment of e
for : 要获得您期望的结果,您应该更改
e
的声明和分配:
unsigned char *e = "197127";
unsigned char *f = e;
Or, convert the integer value to a string (using sprintf() ) and have f
point to that instead : 或者,将整数值转换为字符串(使用sprintf() )并使
f
指向:
char s[1000];
sprintf(s,"%d",e);
unsigned char *f = s;
Or, use mathematical operation to get single digit from your integer and print those out. 或者,使用数学运算从整数中获取单个数字并将其打印出来。
Or, ... 要么, ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.