(Voir aussi type pour une vue d'ensemble du système de types et la liste des utilitaires liés aux types qui sont fournis par la bibliothèque C)..

Type booléen

  • _Bool (également accessible comme la macro bool) - type, capable de contenir une des deux valeurs : 1 et 0 (également accessible comme les macros true et false).

Notez que la conversion en _Bool ne fonctionne pas de la même manière que la conversion en d'autres types entiers : (bool)0.5 s'évaluation à 1alors que (int)0.5 est évalué à ​0​.

(depuis C99)

Types de caractères

  • signed char - type pour la représentation des caractères signés.
  • unsigned char - type pour la représentation des caractères non signés. Également utilisé pour inspecter les représentations d'objets (mémoire brute).
  • char - Type pour la représentation des caractères. Équivalent à signed char ou unsigned char (lequel est défini par l'implémentation et peut être contrôlé par un commutateur de ligne de commande du compilateur), mais char est un type distinct, différent à la fois de signed char les deux unsigned char

Notez que la bibliothèque standard définit également des noms typiques wchar_t , char16_t, et char32_t(depuis C11) pour représenter les caractères larges.

Types de nombres entiers

  • short int (également accessibles en tant que short, peuvent utiliser le mot-clé signed)
  • unsigned short int (également accessible sous la forme unsigned short)
  • int (également accessible en tant que signed int)
  • unsigned int (également accessible en tant que unsigned), la contrepartie non signée de intqui implémente l'arithmétique modulo. Convient pour les manipulations de bits.
  • long int (également accessible en tant que long)
  • unsigned long int (également accessible en tant que unsigned long)

Il s'agit du type d'entier le plus optimal pour la plate-forme, et il est garanti d'être au moins de 16 bits. La plupart des systèmes actuels utilisent 32 bits (voir Modèles de données ci-dessous).

  • long long int (également accessible sous la forme long long)
  • unsigned long long int (également accessible en tant que unsigned long long)
(depuis C99)

Note : comme pour tous les spécificateurs de type, n'importe quel ordre est autorisé : unsigned long long int et long int unsigned long nomment le même type.

Le tableau suivant résume tous les types d'entiers disponibles et leurs propriétés :

Spécification de type Type équivalent Largeur en bits par modèle de données
Norme C LP32 ILP32 LLP64 LP64
short short int au moins
16
16 16 16 16
short int
signed short
signed short int
unsigned short unsigned short int
unsigned short int
int int au moins
16
16 32 32 32
signed
signed int
unsigned unsigned int
unsigned int
long long int au moins
32
32 32 32 64
long int
signed long
signed long int
unsigned long unsigned long int
unsigned long int
long long long long int
(C99)
au moins
64
64 64 64 64
long long int
signed long long
signed long long int
unsigned long long unsigned long long int
(C99)
unsigned long long int

Outre le nombre minimal de bits, le standard C garantit que 1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long).

Note : ceci permet le cas extrême dans lequel octets ont une taille de 64 bits, tous les types (y compris les types char) ont une largeur de 64 bits, et sizeof renvoie 1 pour chaque type.

Note : l'arithmétique des entiers est définie différemment pour les types entiers signés et non signés. Voir les opérateurs arithmétiques, en particulier les débordements d'entiers.

Modèles de données

Les choix faits par chaque implémentation sur les tailles des types fondamentaux sont collectivement connus sous le nom de... modèle de données. Quatre modèles de données ont trouvé une large acceptation :

les systèmes à 32 bits :

  • LP32 ou 2/4/4 (int est 16 bits, long et pointeur sont 32 bits)
    • API Win16
  • ILP32 ou 4/4/4 (int, long, et pointeur sont 32 bits) ;
    • API Win32
    • Unix et systèmes similaires à Unix (Linux, Mac OS X)

Systèmes à 64 bits :

  • LLP64 ou 4/4/8 (int et long sont 32 bits, le pointeur est 64 bits).
    • API Win64
  • LP64 ou 4/8/8 (int est 32-bit, long et pointeur sont 64-bit)
    • Unix et systèmes similaires à Unix (Linux, Mac OS X)

Les autres modèles sont très rares. Par exemple , ILP64 (8/8/8: int, long et pointeur sont 64 bits) n'est apparu que dans certains des premiers systèmes Unix 64 bits (par exemple, les Unicos sur Cray).

Notez que les types d'entiers de largeur exacte sont disponibles en depuis C99.

Types réels flottants

Le C dispose de trois types pour représenter les valeurs réelles à virgule flottante :

  • float - type de virgule flottante de précision simple. Correspond au type de virgule flottante IEEE-754 32 bits s'il est supporté.
  • double - Type de virgule flottante à double précision. Correspond au type de virgule flottante IEEE-754 64 bits s'il est pris en charge.
  • long double - Type de virgule flottante à précision étendue. Correspond au type de virgule flottante étendue IEEE-754 s'il est pris en charge, sinon correspond à un type de virgule flottante étendue non standard tant que sa précision est supérieure à double et que sa plage soit au moins aussi bonne que doublesinon, il correspond au type double. Certaines implémentations x86 et x86_64 utilisent le type de virgule flottante x87 de 80 bits.

Les types à virgule flottante peuvent supporter des valeurs spéciales :

  • infini (positif et négatif), voir INFINITY
  • le zéro négatif, -0.0. Il compare égal au zéro positif, mais est significatif dans certaines opérations arithmétiques, par ex. 1.0/0.0 == INFINITY, mais 1.0/-0.0 == -INFINITY)
  • pas un nombre (NaN), qui ne se compare à rien (y compris à lui-même). Plusieurs motifs binaires représentent les NaN, voir nan, NAN. Notez que le C ne prend pas spécialement en compte la signalisation des NaN (spécifiée par IEEE-754), et traite tous les NaN comme des silences.

Les nombres réels à virgule flottante peuvent être utilisés avec les opérateurs arithmétiques + - / * et diverses fonctions mathématiques de math.h. Les opérateurs intégrés et les fonctions de la bibliothèque peuvent lever des exceptions de virgule flottante et mettre errno comme décrit dans math_errhandling.

Les expressions en virgule flottante peuvent avoir une plage et une précision plus grandes que celles indiquées par leurs types, voir... FLT_EVAL_METHOD. L'assignation, le retour et le cast forcent la plage et la précision à celle associée au type déclaré.

Les expressions à virgule flottante peuvent également être contractées, c'est-à-dire calculées comme si toutes les valeurs intermédiaires avaient une étendue et une précision infinies, voir #pragma STDC FP_CONTRACT.

Certaines opérations sur les nombres à virgule flottante sont affectées par et modifient l'état de l'environnement à virgule flottante (plus particulièrement, le sens d'arrondi).

Des conversions implicites sont définies entre les types réels flottants et les types entiers, complexes et imaginaires.

Voir Limites des types à virgule flottante et la bibliothèque math.h pour des détails supplémentaires, les limites et les propriétés des types à virgule flottante.

Types complexes à virgule flottante.

Les types flottants complexes modélisent le modèle mathématique nombres complexes, c'est-à-dire les nombres qui peuvent s'écrire comme une somme d'un nombre réel et d'un nombre réel multiplié par l'unité imaginaire : a + bi.

Les trois types de complexes sont .

  • float _Complex (également disponible sous la forme floatcomplex si est inclus)
  • double _Complex (également disponible comme doublecomplex si est inclus)
  • long double _Complex (également disponible comme longdoublecomplex si est inclus)

Remarque : comme pour tous les spécificateurs de type, n'importe quel ordre est autorisé : longdoublecomplex, complexlongdoubleet même doublecomplexlong nomment le même type.

#include#includeintmain(void){double complex z =1+2*I;
    z =1/z;printf("1/(1.0+2.0i) = %.1f%+.1fin",creal(z),cimag(z));}

Sortie :

1/(1.0+2.0i)=0.2-0.4i
Si la macro-constante __STDC_NO_COMPLEX__(C11) est définie par l'implémentation, les types complexes (ainsi que l'en-tête de bibliothèque ) ne sont pas fournis. (depuis C11)

Chaque type complexe a les mêmes exigences de représentation d'objet et d'alignement qu'un tableau de deux éléments du type réel correspondant (float pour floatcomplex, double pour doublecomplex, long double pour longdoublecomplex). Le premier élément du tableau contient la partie réelle, et le second élément du tableau contient la composante imaginaire.

float a[4]={1,2,3,4};float complex z1, z2;memcpy(&z1, a,sizeof z1);// z1 becomes 1.0 + 2.0imemcpy(&z2, a+2,sizeof z2);// z2 becomes 3.0 + 4.0i

Les nombres complexes peuvent être utilisés avec les opérateurs arithmétiques + - * et /, éventuellement mélangés avec des nombres imaginaires et réels. Il y a de nombreuses fonctions mathématiques définies pour les nombres complexes dans complex.h. Les opérateurs intégrés et les fonctions de bibliothèque peuvent lever des exceptions de virgule flottante et définir... errno comme décrit dans math_errhandling.

L'incrémentation et la décrémentation ne sont pas définies pour les types complexes.

Les opérateurs relationnels ne sont pas définis pour les types complexes (il n'y a pas de notion de "moins que") Des conversions implicites sont définies entre les types complexes et les autres types arithmétiques.

Afin de supporter le modèle d'une infinité de l'arithmétique des nombres complexes, C considère toute valeur complexe avec au moins une partie infinie comme une infinité même si son autre partie est un NaN, garantit que tous les opérateurs et fonctions honorent les propriétés de base des inifinités et fournit... cproj pour faire correspondre toutes les infinités à l'infini canonique (voir les opérateurs arithmétiques pour les règles exactes).

#include#include#includeintmain(void){double complex z =(1+0*I)*(INFINITY + I*INFINITY);// textbook formula would give// (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN// but C gives a complex infinityprintf("%f + i*%fn",creal(z),cimag(z));// textbook formula would give// cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN// but C gives  ±∞+i*nandouble complex y =cexp(INFINITY + I*NAN);printf("%f + i*%fn",creal(y),cimag(y));}

Sortie possible :

inf + i*inf 
inf + i*nan

C traite également les infinis multiples de manière à préserver l'information directionnelle lorsque cela est possible, malgré les limitations inhérentes à la représentation cartésienne :

La multiplication de l'unité imaginaire par l'infini réel donne l'infini imaginaire correctement signé : i × ∞ = i∞. De même, i × (∞ - i∞) = ∞ + i∞ indique le quadrant raisonnable.

Types flottants imaginaires

Les types flottants imaginaires modélisent les mathématiques. nombres imaginaires, c'est-à-dire les nombres qui peuvent être écrits comme un nombre réel multiplié par l'unité imaginaire : bi Les trois types imaginaires sont .

  • float _Imaginary (également disponible sous la forme floatimaginary si est inclus)
  • double _Imaginary (également disponible comme doubleimaginary si est inclus)
  • long double _Imaginary (également disponible comme longdoubleimaginary si est inclus)

Remarque : comme pour tous les spécificateurs de type, n'importe quel ordre est autorisé : longdoubleimaginary, imaginarylongdoubleet même doubleimaginarylong nomment le même type.

#include#includeintmain(void){double imaginary z =3*I;
    z =1/z;printf("1/(3.0i) = %+.1fin",cimag(z));}

Sortie :

1/(3.0i)=-0.3i

Un compilateur qui définit __STDC_IEC_559_COMPLEX__ est recommandé, mais pas obligatoire pour prendre en charge les nombres imaginaires. POSIX recommande de vérifier si la macro _Imaginary_I est définie pour identifier le support des nombres imaginaires.

(depuis C99)
(jusqu'à C11)

Les nombres imaginaires sont supportés si __STDC_IEC_559_COMPLEX__ est défini.

(depuis C11)

Chacun des trois types imaginaires a la même représentation d'objet et la même exigence d'alignement que ses type réel correspondant (float pour floatimaginary, double pour doubleimaginary, long double pour longdoubleimaginary).

Note : malgré cela, les types imaginaires sont distincts et non compatibles avec leurs types réels correspondants, ce qui interdit l'aliasing.

Les nombres imaginaires peuvent être utilisés avec les opérateurs arithmétiques + - * et /, éventuellement mélangés avec les nombres complexes et réels. Il y a de nombreuses fonctions mathématiques définies pour les nombres imaginaires dans complex.h. Les opérateurs intégrés et les fonctions de bibliothèque peuvent tous deux lever des exceptions de virgule flottante et définir... errno comme décrit dans math_errhandling.

L'incrémentation et la décrémentation ne sont pas définies pour les types imaginaires Des conversions implicites sont définies entre les types imaginaires et les autres types arithmétiques.

Les nombres imaginaires permettent d'exprimer tous les nombres complexes en utilisant la notation naturelle. x + I*y (où I est défini comme _Imaginary_I). Sans types imaginaires, certaines valeurs complexes spéciales ne peuvent pas être créées naturellement. Par exemple, si I est défini comme _Complex_Ialors on écrit 0.0 + I*INFINITY donne NaN comme partie réelle, et CMPLX(0.0, INFINITY) doit être utilisé à la place. Il en va de même pour les nombres avec la composante imaginaire négative zéro, qui sont significatifs lorsque l'on travaille avec les fonctions de la bibliothèque avec des coupures de branche, telles que csqrt: 1.0 - 0.0*I donne la composante imaginaire zéro positive si I est défini comme _Complex_I et la composante imaginaire zéro négative nécessite l'utilisation de CMPLX ou conj.

Les types imaginaires simplifient également les implémentations ; la multiplication d'un imaginaire par un complexe peut être implémentée directement avec deux multiplications si les types imaginaires sont supportés, au lieu de quatre multiplications et deux additions.

(depuis C99)

Mots clés

char, int, short, long, signed, unsigned, float, double. _Bool, _Complex, _Imaginary.

Plage de valeurs

Le tableau suivant fournit une référence pour les limites des représentations numériques courantes. Comme la norme C autorise toute représentation d'entier signé, le tableau donne à la fois les exigences minimales garanties (qui correspondent aux limites des valeurs de complément à un ou signe et magnitude) et les limites de l'implémentation la plus couramment utilisée, complément à deux. Tous les modèles de données populaires (y compris tous les modèles ILP32, LP32, LP64, LLP64) utilisent cependant la représentation par complément à deux.

Type Taille en bits Format Plage de valeurs
Approximatif Exacte
caractère 8 signé (complément à un) -127 à 127
signés (complément à deux) -128 à 127
non signé 0 à 255
intégrale 16 signé (complément à un) ± 3.27 - 10 4 -32767 à 32767
signé (complément à deux) -32768 à 32767
non signé 0 à 6.55 - 10 4 0 à 65535
32 signé (complément à un) ± 2.14 - 10 9 -2,147,483,647 à 2,147,483,647
signé (complément à deux) -2,147,483,648 à 2,147,483,647
non signé 0 à 4.29 - 10 9 0 à 4,294,967,295
64 signé (complément à un) ± 9.22 - 10 18 -9,223,372,036,854,775,807 à 9,223,372,036,854,775,807
signé (complément à deux) -9,223,372,036,854,775,808 à 9,223,372,036,854,775,807
non signé 0 à 1.84 - 10 19 0 à 18,446,744,073,709,551,615
flottant
point
32 IEEE-754
  • min subnormal :
    ± 1.401,298,4 - 10 -45
  • min normal :
    ± 1.175,494,3 - 10 -38
  • max :
    ± 3.402,823,4 - 10 38
  • min subnormal :
    ±0x1p-149
  • min normal :
    ±0x1p-126
  • max :
    ±0x1.fffffep+127
64 IEEE-754
  • min subnormal :
    ± 4.940,656,458,412 - 10 -324
  • min normal :
    ± 2.225,073,858,507,201,4 - 10 -308
  • max :
    ± 1.797,693,134,862,315,7 - 10 308
  • min subnormal :
    ±0x1p-1074
  • min normal :
    ±0x1p-1022
  • max :
    ±0x1.fffffffffffffp+1023

Remarque : les plages réelles (par opposition aux plages minimales garanties) sont disponibles dans les en-têtes de la bibliothèque. et

Voir aussi