开发者

Can someone explain this "endian-ness" function for me?

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?

Woul开发者_如何学运维d 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?


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.


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.


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).


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.


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.


Sure, let's 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜