Can someone explain this “endian-ness” function for me?

时光怂恿深爱的人放手 提交于 2019-11-29 18:03:23

问题


Write a program to determine whether a computer is big-endian or little-endian.

bool endianness() {
     int i = 1;
     char *ptr;
     ptr  = (char*) &i;
     return (*ptr);
}

So I have the above function. I don't really get it. ptr = (char*) &i, which I think means a pointer to a character at address of where i is sitting, so if an int is 4 bytes, say ABCD, are we talking about A or D when you call char* on that? and why?

Would some one please explain this in more detail? Thanks.

So specifically, ptr = (char*) &i; when you cast it to char*, what part of &i do I get?


回答1:


If you have a little-endian architecture, i will look like this in memory (in hex):

01 00 00 00
^

If you have a big-endian architecture, i will look like this in memory (in hex):

00 00 00 01
^

The cast to char* gives you a pointer to the first byte of the int (to which I have pointed with a ^), so the value pointed to by the char* will be 01 if you are on a little-endian architecture and 00 if you are on a big-endian architecture.

When you return that value, 0 is converted to false and 1 is converted to true. So, if you have a little-endian architecture, this function will return true and if you have a big-endian architecture, it will return false.




回答2:


If ptr points to byte A or D depends on the endianness of the machine. ptr points to that byte of the integer that is at the lowest address (the other bytes would be at ptr+1,...).

On a big-endian machine the most significant byte of the integer (which is 0x00) will be stored at this lowest address, so the function will return zero.

On a litte-endian machine it is the opposite, the least significant byte of the integer (0x01) will be stored at the lowest address, so the function will return one in this case.




回答3:


This is using type punning to access an integer as an array of characters. If the machine is big endian, this will be the major byte, and will have a value of zero, but if the machine is little endian, it will be the minor byte, which will have a value of one. (Instead of accessing i as a single integer, the same memory is accessed as an array of four chars).




回答4:


Whether *((char*)&i) is byte A or byte D gets to the heart of endianness. On a little endian system, the integer 0x41424344 will be laid out in memory as: 0x44 43 42 41 (least significant byte first; in ASCII, this is "DCBA"). On a big endian system, it will be laid out as: 0x41 42 43 44. A pointer to this integer will hold the address of the first byte. Considering the pointer as an integer pointer, and you get the whole integer. Consider the pointer as a char pointer, and you get the first byte, since that's the size of a char.




回答5:


Sure,

Lets take a look

bool endianness() {
     int i = 1; //This is 0x1:
     char *ptr;
     ptr  = (char*) &i; //pointer to 0001
     return (*ptr);
}

If the machine is Little endian, then data will be in *ptr will be 0000 0001.

If the machine is Big Endian, then data will be inverted, that is, i will be

i = 0000 0000 0000 0001 0000 0000 0000 0000 

So *ptr will hold 0x0

Finally, the return *ptr is equivalent to

if (*ptr = 0x1 ) //little endian

else //big endian



回答6:


Assume int is 4 bytes (in C it may not be). This assumption is just to simplify the example...

You can look at each of these 4 bytes individually.

char is a byte, so it's looking at the first byte of a 4 byte buffer.

If the first byte is non 0 then that tells you if the lowest bit is contained in the first byte.

I randomly chose the number 42 to avoid confusion of any special meaning in the value 1.

int num = 42;
if(*(char *)&num == 42)
{
      printf("\nLittle-Endian\n");
}
else
{
      printf("Big-Endian\n");
}

Breakdown:

int num = 42; 
//memory of the 4 bytes is either: (where each byte is 0 to 255)
//1) 0 0 0 42
//2) 42 0 0 0

char*p = #/*Cast the int pointer to a char pointer, pointing to the first byte*/
bool firstByteOf4Is42 = *p == 42;/*Checks to make sure the first byte is 1.*/

//Advance to the 2nd byte
++p;
assert(*p == 0);

//Advance to the 3rd byte
++p;
assert(*p == 0);

//Advance to the 4th byte
++p;
bool lastByteOf4Is42 = *p == 42;
assert(firstByteOf4Is42 == !lastByteOf4Is42);

If firstByteOf4Is42 is true you have little-endian. If lastByteOf4Is42 is true then you have big-endian.



来源:https://stackoverflow.com/questions/2531515/can-someone-explain-this-endian-ness-function-for-me

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!