Comportement défini, en passant caractère printf(“%02X”

Je suis récemment tombé sur cette question, où l'OP était d'avoir des problèmes d'impression de la valeur hexadécimale d'une variable. Je crois que le problème peut être résumé par le code suivant:

#include <stdio.h>

int main() {
    char signedChar = 0xf0;

    printf("Signed\n”);
    printf(“Raw: %02X\n”, signedChar);
    printf(“Masked: %02X\n”, signedChar &0xff);
    printf(“Cast: %02X\n", (unsigned char)signedChar);

    return 0;
}

Cela donne le résultat suivant:

Signed
Raw: FFFFFFF0
Masked: F0
Cast: F0

Le format de chaîne de caractères utilisée pour chacun des tirages est %02X, que j'ai toujours interprétée comme "l'impression fournis int comme une valeur hexadécimale avec au moins deux chiffres".

Le premier cas, passe le signedCharacter en tant que paramètre et affiche la valeur faux (parce que les trois autres octets de la int ont tous leurs bits).

Le second cas permet de contourner ce problème, par l'application d'un masque de bits (0xFF) contre la valeur de supprimer tous mais l'octet le moins significatif, où la char est stocké. Si cela fonctionne? Sûrement: signedChar == signedChar & 0xFF?

Le troisième cas contourne le problème en jetant le caractère d'une unsigned char (ce qui semble clair, les trois premiers octets?).

Pour chacun des trois cas ci-dessus, quelqu'un peut-il me dire si le comportement défini? Comment/Où?

Les types d'entiers plus petits que int obtenir une promotion à int lorsqu'il est passé à printf.
Depuis le sous-jacente représentation binaire des nombres n'est pas définie dans la norme C, la sortie exacte n'est pas spécifié.
R: Donc, dans le deuxième cas, la promotion de toujours avoir lieu avant que le masque est appliqué? Ou peut-il se produire après dans lequel le masque aurait aucun effet?
La ce paramètre de char la mise en œuvre est définie, par la manière. Si vous voulez signé un caractère, utilisez signed char.
vraiment? J'ai toujours supposé que les variables ont été signés par défaut à moins d'indication contraire. Est-il le même pour les entiers?

OriginalL'auteur forsvarir | 2011-05-20