Chaines de caracteres
LSmi
-
LSmi -
LSmi -
Bonjour,
J'ai un petit problème avec des chaines de caracteres, j'ai une fonction de type : fct(char* str);
Lorsque je fais :
str[0] = ( str[0] << 2) | (str[1] >> 4);
printf("k : 0x%02X \n", str[0]);
J'obtiens à l'affichage :
# k : 0xFFFFFF86
Alors que je ne devrais avoir que 0x86... (sachant que str[0] = 0x84 et str[1] = 0x02)
Quelqu'un saurait-il me dire d'où ça vient ?
Merci.
LSmi
J'ai un petit problème avec des chaines de caracteres, j'ai une fonction de type : fct(char* str);
Lorsque je fais :
str[0] = ( str[0] << 2) | (str[1] >> 4);
printf("k : 0x%02X \n", str[0]);
J'obtiens à l'affichage :
# k : 0xFFFFFF86
Alors que je ne devrais avoir que 0x86... (sachant que str[0] = 0x84 et str[1] = 0x02)
Quelqu'un saurait-il me dire d'où ça vient ?
Merci.
LSmi
A voir également:
- Chaines de caracteres
- Recherche automatique des chaînes ne fonctionne pas - Guide
- Caractères spéciaux - Guide
- Caracteres speciaux - Guide
- Caractères ascii - Guide
- Caractères spéciaux mac - Guide
2 réponses
Prenons ceci:
Au moment ou c est passé à printf, il est implicitement transformé en int (entier signé 4 octets).
Comment se passe la conversion d'un entier signé d'un octet (char), à un entier signé de 4 octets (int) ?
En fait c'est très simple: on commence par copier l'octet du char dans le premier octet de poids faible du int.
Ensuite si l'octet de poids fort du char (8 ème bit) est à 1, alors on propage ce 1 dans tous les autres bits de poids fort de l'int.
Exemple avec 0x86:
Par contre si le bit de poids fort du char était à zero, alors on aurait étendu ce zero dans l'int.
Exemple avec 0x06:
Cette opération de copie avec étendue du signe est réalisée avec l'instruction movsx (move with Sign Extend) sur les processeurs Intel et Amd.
Si le code avait été fait avec un unsigned char:
Alors c aurait été converti en unsigned int pour le passer à printf. Et la conversion d'entier non-signé 1 octet à entier non-signé 4 octets est très simple: on copie l'octet du char dans l'octet de poids faible du int, et on mets tous ses autres bits de poids fort à zero. Cette opération se fait avec l'instruction movzx (move with Zero Extend) toujours sur les mêmes processeurs.
T'ai-je éclairé? :-)
char c = 0x86;
printf("k : 0x%02X \n", c);
Au moment ou c est passé à printf, il est implicitement transformé en int (entier signé 4 octets).
Comment se passe la conversion d'un entier signé d'un octet (char), à un entier signé de 4 octets (int) ?
En fait c'est très simple: on commence par copier l'octet du char dans le premier octet de poids faible du int.
Ensuite si l'octet de poids fort du char (8 ème bit) est à 1, alors on propage ce 1 dans tous les autres bits de poids fort de l'int.
Exemple avec 0x86:
char: 1000 0110 Le bit de poids fort du char (en gras) est à 1, on l'étends dans tous les bits de poids fort de l'int: int: 1111 1111 1111 1111 1111 1111 1000 0110
Par contre si le bit de poids fort du char était à zero, alors on aurait étendu ce zero dans l'int.
Exemple avec 0x06:
char: 0000 0110 Le bit de poids fort du char (en gras) est à 1, on l'étend dans tous les bits de poids fort de l'int: int: 0000 0000 0000 0000 0000 0000 0000 0110
Cette opération de copie avec étendue du signe est réalisée avec l'instruction movsx (move with Sign Extend) sur les processeurs Intel et Amd.
Si le code avait été fait avec un unsigned char:
unsigned char c = 0x86;
printf("k : 0x%02X \n", c);
Alors c aurait été converti en unsigned int pour le passer à printf. Et la conversion d'entier non-signé 1 octet à entier non-signé 4 octets est très simple: on copie l'octet du char dans l'octet de poids faible du int, et on mets tous ses autres bits de poids fort à zero. Cette opération se fait avec l'instruction movzx (move with Zero Extend) toujours sur les mêmes processeurs.
T'ai-je éclairé? :-)
Juste quelques erreurs sur les types qui en découlent, mais ça devrait être vite réglé !
Par contre comment est-il possible qu'un char, donc sur 1 seul octet donne une telle valeur ?