C program to check little vs. big endian [duplicat

2019-01-08 04:16发布

问题:

Possible Duplicate:
C Macro definition to determine big endian or little endian machine?

int main()
{
  int x = 1;

  char *y = (char*)&x;

  printf("%c\n",*y+48);
}

If it's little endian it will print 1. If it's big endian it will print 0. Is that correct? Or will setting a char* to int x always point to the least significant bit, regardless of endianness?

回答1:

In short, yes.

Suppose we are on a 32-bit machine.

If it is little endian, the x in the memory will be something like:

       higher memory
          ----->
    +----+----+----+----+
    |0x01|0x00|0x00|0x00|
    +----+----+----+----+
    A
    |
   &x

so (char*)(&x) == 1, and *y+48 == '1'.

If it is big endian, it will be:

    +----+----+----+----+
    |0x00|0x00|0x00|0x01|
    +----+----+----+----+
    A
    |
   &x

so this one will be '0'.



回答2:

The following will do.

unsigned int x = 1;
printf ("%d", (int) (((char *)&x)[0]));

And setting &x to char * will enable you to access the individual bytes of the integer, and the ordering of bytes will depend on the endianness of the system.



回答3:

This is big endian test from a configure script:

#include <inttypes.h>
int main(int argc, char ** argv){
    volatile uint32_t i=0x01234567;
    // return 0 for big endian, 1 for little endian.
    return (*((uint8_t*)(&i))) == 0x67;
}


回答4:

Thought I knew I had read about that in the standard; but can't find it. Keeps looking. Old; answering heading; not Q-tex ;P:


The following program would determine that:

#include <stdio.h>
#include <stdint.h>

int is_big_endian(void)
{
    union {
        uint32_t i;
        char c[4];
    } e = { 0x01000000 };

    return e.c[0];
}

int main(void)
{
    printf("System is %s-endian.\n",
        is_big_endian() ? "big" : "little");

    return 0;
}

You also have this approach; from Quake II:

byte    swaptest[2] = {1,0};
if ( *(short *)swaptest == 1) {
    bigendien = false;

And !is_big_endian() is not 100% to be little as it can be mixed/middle.

Believe this can be checked using same approach only change value from 0x01000000 to i.e. 0x01020304 giving:

switch(e.c[0]) {
case 0x01: BIG
case 0x02: MIX
default: LITTLE

But not entirely sure about that one ...