简体   繁体   English

无符号字符指向无符号整数

[英]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分配在低地址,然后是0000001000000011 ,最后是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.

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