Litterales

Les valeurs entières.

Les operations entre deux valeurs nécessitent de trouver un type commun entre les deux opérandes, de convertir chacun des opérandes vers ce type puis retourne le résulatat de l’opération vers ce type commun.

Le type d’un litéral entier est de type int, sauf si un int ne peut pas le contenir auquel cas il est converti vers un type défini par l’implémentation qui peut le contenir :

#include <stdio.h>
#define ptype(val) printf("%d est de type ", val); _Generic(val,  \
    signed char: printf("signed char"),  \
    unsigned char: printf("unsigned char"),  \
    signed short: printf("signed short"),  \
    unsigned short: printf("unsigned short"),  \
    signed: printf("signed int"),  \
    unsigned: printf("unsigned int"),  \
    signed long: printf("signed long"),  \
    unsigned long: printf("unsigned long"),  \
    signed long long: printf("signed long long"),  \
    unsigned long long: printf("unsigned long long"),  \
    default: printf("not found")  \
);  \
printf("\n");

int main(void) {
    ptype(0); // signed int
    ptype(12); // signed int
    ptype(-12); // signed int
    ptype(123); // signed int
    ptype(130); // signed int
    ptype(-130); // signed int
    ptype(1000); // signed int
    ptype(100000000000); // signed long long
}

Pour pouvoir transformer un littéral en un type différent à int on peut ajouter un modificateur à sa droite, soit u ou U pour unsigned, l ou L pour un long et ll ou LL pour long long

#include <stdio.h>
#define ptype(val) printf("%d est de type ", val); _Generic(val,  \
    signed char: printf("signed char"),  \
    unsigned char: printf("unsigned char"),  \
    signed short: printf("signed short"),  \
    unsigned short: printf("unsigned short"),  \
    signed: printf("signed int"),  \
    unsigned: printf("unsigned int"),  \
    signed long: printf("signed long"),  \
    unsigned long: printf("unsigned long"),  \
    signed long long: printf("signed long long"),  \
    unsigned long long: printf("unsigned long long"),  \
    default: printf("not found")  \
);  \
printf("\n");

int main(void) {

    ptype(12);  // signed int
    ptype(13u);  // unsigned int
    ptype(14l);  // signed long
    ptype(15ul);  // unsigned long
    ptype(16ll);  // signed long long
    ptype(17ull);  // unsigned long long
    ptype(18ULL);  // unsigned long long
}

Les caractères sont de type int, Il est possible d’avoir des caractères sur 16 et 32 bits avec les préfixes u et U, de type char16_t et char42_t, et des caractères de type wchar_t avec le préxie ‘L’. En C23 il sera possible d’avoir le prefixe u8 pour avoir des caractères sur 8 bits de type char8_t.

#include <stdio.h>
#define ptype(val) printf("%d est de type ", val); _Generic(val,  \
    signed char: printf("signed char"),  \
    unsigned char: printf("unsigned char"),  \
    signed short: printf("signed short"),  \
    unsigned short: printf("unsigned short"),  \
    signed: printf("signed int"),  \
    unsigned: printf("unsigned int"),  \
    signed long: printf("signed long"),  \
    unsigned long: printf("unsigned long"),  \
    signed long long: printf("signed long long"),  \
    unsigned long long: printf("unsigned long long"),  \
    default: printf("not found")  \
);  \
printf("\n");

int main(void) {

    ptype('a');  // signed int
    ptype(u'b');  // unsigned short
    ptype(U'c');  // unsigned int
    ptype(L'd');  // unsigned short
}

A noter que les types char, unsigned char et signed char sont de types différents, le premier peut être signé ou non selon l’implémentation et il est de type « caractère » et sert à afficher du texte, alors que signed char et unsigned char sont des types entiers et servent a stocker des nombres sur un seul octet.

#include <stdio.h>
#define ptype(val) printf("%d est de type ", val); _Generic(val,  \
    signed char: printf("signed char"),  \
    unsigned char: printf("unsigned char"),  \
    signed short: printf("signed short"),  \
    unsigned short: printf("unsigned short"),  \
    signed: printf("signed int"),  \
    unsigned: printf("unsigned int"),  \
    signed long: printf("signed long"),  \
    unsigned long: printf("unsigned long"),  \
    signed long long: printf("signed long long"),  \
    unsigned long long: printf("unsigned long long"),  \
    default: printf("not found")  \
);  \
printf("\n");

int main(void) {

    ptype((char)'a');  // 97 est de type char
    ptype((signed char)'b');  // 98 est de type signed char
    ptype((unsigned char)'c');  // 99 est de type unsigned char
    ptype('d');  // 100 est de type signed int

    puts("");

    ptype((short)12);  // 12 est de type signed short
    ptype((signed short)13);  // 13 est de type signed short
    ptype((unsigned short)14);  // 14 est de type unsigned short

    puts("");

    ptype((int)20);  // 20 est de type signed int
    ptype((signed int)21);  // 21 est de type signed int
    ptype((unsigned int)22);  // 22 est de type unsigned int

}