web-dev-qa-db-fra.com

Programme C pour vérifier le petit vs big endian

Duplicate possible:
Définition de la macro C pour déterminer la machine big endian ou little endian?

int main()
{
  int x = 1;

  char *y = (char*)&x;

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

Si c'est un petit boutiste, il imprimera 1. S'il s'agit de gros endian, il affichera 0. Est-ce correct? Ou bien définir un caractère * sur int x pointera-t-il toujours sur le bit le moins significatif, indépendamment de la finalité?

60
ordinary

En bref, oui.

Supposons que nous sommes sur une machine 32 bits.

Si c'est un peu endian, le x dans la mémoire sera quelque chose comme:

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

alors (char*)(&x) == 1, et *y+48 == '1'.

Si c'est big endian, ce sera:

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

donc celui-ci sera '0'.

91
Marcus

Ce qui va faire.

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

Et en mettant &x à char * vous permettra d'accéder aux octets individuels de l'entier, et l'ordre des octets dépendra de l'endianité du système.

21
phoxis

Ceci est un test big endian à partir d'un script configure :

#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;
}
14
FamZheng

Je croyais savoir que j'avais lu cela dans la norme; mais je ne le trouve pas. Continue à chercher. Vieux; répondre à l'en-tête; pas Q-tex; P:


Le programme suivant déterminerait que:

#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;
}

Vous avez aussi cette approche ; de Quake II:

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

Et !is_big_endian() n'est pas à 100% d'être petit car il peut être mélangé/moyen.

Croyez que cela peut être vérifié en utilisant la même approche, changez seulement la valeur de 0x01000000 À i.e. 0x01020304 En donnant:

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

Mais pas tout à fait sûr de celui-là ...

10
user1668559