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
}