Début de la boite de navigation du chapitre
Types
Icône de la faculté
Chapitre no 5
Leçon : Introduction au langage C
Chap. préc. :Variables et constantes
Chap. suiv. :Opérateurs
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Introduction au langage C : Types
Introduction au langage C/Types
 », n'a pu être restituée correctement ci-dessus.

Définition

modifier

En C, contrairement à PHP ou à JavaScript, une variable est dite typée et ne peut contenir que des valeurs de ce type. On peut déjà classer les types numériques en 2 catégories :

  • Les types contenant des entiers (short, integer, long)
  • Les types contenant des décimaux (float, double : à virgule flottante)

En clair, un type est un attribut de la variable.

Conseils de codage à respecter : c_num_1, c_num_2

Types de base

modifier
  Plus de précision dans WikiLivre Programmation C, chapitre types de base.

Différents types

modifier

Le tableau suivant présente quelques types du langage C. Les tailles et valeurs sont données à titre d'exemple et dépendent de votre architecture informatique. Les limites de chaque type sont données dans le fichier d'include limits.h : CHAR_BIT, CHAR_MAX, CHAR_MIN...

Type Description Taille (*) Valeur
void Type générique
char caractère/octet (†) 1 octets comme signed ou unsigned char
unsigned char caractère/octet (†) non signé 1 octets 0 à 255
signed char caractère/octet (†) signé 1 octets -128 à 127[1][2]
short entier court signé 2 octets -32 768 à 32 767
unsigned short entier non signé 2 octets 0 à 65 535
int entier signé 2 ou 4 octets (en fonction du compilateur)
unsigned entier non signé 2 ou 4 octets (en fonction du compilateur)
long entier signé long 4 octets -2 147 483 648 à 2 147 483 647
unsigned long entier non signé long 4 octets 0 à 4 294 967 295 (2^32-1)
float flottant (‡) 4 octets Mantisse : +- 6 chiffres significatifs
double flottant (‡) 8 octets Mantisse : +- 12 chiffres significatifs
long double flottant (‡) 10 octets


Remarques :

  • (†) Pour des raisons historiques on appelle caractère ce qui en pratique est un octet. Le caractère d'une application utilisateur peut maintenant être codé autrement lorsqu’il nécessite plusieurs octets.
  • (*) Le nombres d'octets de chaque type dépend du compilateur, de ses options et de l'architecture de la machine cible.
    • L'opérateur sizeof retourne la taille en bytes de son paramètre : type ou variable. Cette taille est de type size_t, le type char est l'unité de mesure.
    • Une règle : sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
    • Les valeurs min et max des types caractère et entier se trouvent dans des constantes du fichier d'include limits.h : INT_MIN, INT_MAX, LONG_MIN...
  • (‡) Pour les flottants, voir float.h : FLT_MIN, FLT_MAX, DBL_MIN...

Conversion de type

modifier

En C, les changements de type dans les expressions sont réalisées de façon automatique avec parfois des pertes de précision dans les calculs et d’autre problèmes numériques. Pour rendre les expressions homogènes, on convertit les variables dans le même type. On parle de cast pour cette conversion en écrivant (type_souhaité)variable.

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
  (void)printf("4 / 5 = %f ou (float)4 / (float)5 = %f\n",
               (float)(4/5), (float)4 / (float)5);
  return EXIT_SUCCESS;
}

Affiche :

4 / 5 = 0.000000 ou (float)4 / (float)5 = 0.800000

Nouveaux types introduits par C99

modifier

La norme ISO C99, section 7.8 a introduit de nouveaux types, pour les entiers signés ou non, qui permettent d'améliorer la portabilité des programmes. Les includes stdint.h et inttypes.h permettent de les utiliser.

/*
 Nom : typec99.c
 Auteur : Thierry46
 Role : Manipulation de types C99
 Pour produire un exécutable avec le compilateur libre GCC :
 gcc -Wall -pedantic -std=c99 -o typec99.exe typec99.c
 Pour exécuter, tapez : ./typec99.exe
 Version : 1.0 du 14/5/2008
 Licence : GNU GPL
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
   int_fast16_t n1, n2, resu;
   n1 = INT16_C(300);
   n2 = INT16_C(400);
   
   resu = n1 + n2;
   
   (void)printf("n1 = %"PRIdFAST16"\n"
                "n2 = %"PRIdFAST16"\n"
                "n1 + n2 = %"PRIdFAST16"\n",
                n1, n2, resu);
   
   // Impression des limites pour les nombres entiers
   (void)printf("INT_FAST16_MAX = %"PRIdFAST16"\n", INT_FAST16_MAX);
   (void)printf("INTMAX_MAX = %"PRIdMAX"\n", INTMAX_MAX);
   
   return EXIT_SUCCESS;
}

Affiche :

n1 = 300
n2 = 400
n1 + n2 = 700
INT_FAST16_MAX = 32767
INTMAX_MAX = 9223372036854775807

Explications :

  • int_fast16_t n1, n2, resu; déclare trois entiers signés 16 bits. Il est demandé de choisir un type machine d'au moins 16 bits qui assure une bonne performance de calcul (fast).
  • n1 = INT16_C(300); initialise n1 en utilisant la macro INT16_C(valeur) pour créer une constante du type correspondant.
  • (void)printf("n1 = %"PRIdFAST16"\n" utilise dans le format d'impression de printf l'indicateur de conversion PRIdFAST16 défini dans inttypes.h qui signifie :
    • PRI : indicateur pour les fonctions de la famille printf. Pour la famille scanf se serait SCN
    • d : spécificateur classique de conversion, on pourrait aussi utiliser : i, o, x...
    • FAST : pour un type C99 fast (rapide à calculer). il existe aussi LEAST.
    • 16 : Nombre de bit minimum pour le stockage.
  • (void)printf("INT_FAST16_MAX = %"PRIdFAST16"\n", INT_FAST16_MAX); : cette instruction affiche le plus grand entier INT_FAST16_MAX stockable dans le type int_fast16_t en utilisant le spécificateur de format adapté PRIdFAST16. INT_FAST16_MIN contient elle la plus petite valeur négative de ce type.
  • (void)printf("INTMAX_MAX = %"PRIdMAX"\n", INTMAX_MAX); : cette instruction affiche le plus grand entier INTMAX_MAX stockable dans le type intmax_t en utilisant le spécificateur de format adapté PRIdMAX.
  • Pour utiliser des entiers non signés, faites précéder les types par u et les constantes par U.

Tableau

modifier
  Plus de précisions sur les tableaux dans le WikiLivre Programmation C, chapitre Tableaux.

Il existe trois types de tableaux :

  • les tableaux statiques, dont la taille est connue à la compilation;
  • les tableaux de longueur variable ou VLA (Variable Length Array) introduits par la norme C99.
  • les tableaux dynamiques, dont la taille est connue à l'exécution.

Nous ne nous intéresserons pour l'instant qu'aux tableaux statiques, les tableaux dynamiques seront présentés avec les pointeurs.

Note : les indices commencent à 0.

Exemple d’utilisation de tableau :

/*
Nom : tableau.c
Role : Utilisation de tableau.
Paramètres : non pris en compte.
Code retour : 0 (EXIT_SUCCESS)
Pour produire un exécutable avec le compilateur libre GCC :
   gcc -o tableau.exe tableau.c
Pour exécuter, tapez : ./tableau.exe
*/
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char argv[])
{
   /* Définition du tableau d'entiers et initialisation */
   int table[] = {0, 1, 2, 3, 4};

   /* Modification de l'élément d'indice 0 */
   table[0] = 5;

   /* Écriture des éléments d'indice 0 et 1 */
   (void)printf("table[0]=%d, table[1]=%d\n",
       table[0], table[1]);

   (void)puts("Fin du programme tableau"); 
   return EXIT_SUCCESS;
}

À l'exécution :

$ ./tableau.exe
table[0]=5, table[1]=1
Fin du programme tableau

Chaîne de caractères

modifier
  Plus de précisions sur les chaînes de caractères dans le WikiLivre Programmation C, chapitre Tableaux/Chaînes de caractères.

Une chaîne de caractère peut être considérée comme un tableau de caractères/octets ou un espace mémoire terminé par un caractère/octet de valeur 0. Elle peut être initialisée par une constante littérale entre guillemets doubles "…". Elles peuvent contenir des caractères spéciaux codés sous forme de séquence d'échappement. Elles peuvent aussi contenir des caractères normaux codés sous la forme de plusieurs octets, c’est typiquement le cas lors de l’utilisation du format utf8.

Séquences d'échappement

caractère signification caractère signification caractère signification caractère signification
\a Sonnerie \\ Trait oblique \b Curseur arrière \? Point d'interrogation
\t Tabulation \' Apostrophe \n Nouvelle ligne \" guillemets
\r retour au début de ligne \f saut de page (imprimante) \0 Fin d'une chaine de caractère \v Tabulation verticale

Les fonctions décrites dans l'include string.h facilitent la manipulation des chaines.

  Plus de précisions sur les fonctions de string.h dans le WikiLivre Programmation C, chapitre Bibliothèque/Chaînes.

Structure

modifier

Les structures représentent un type particulier. Elles sont un conteneur pour une ou plusieurs variables, pouvant être de types différents. On les définit dans les fichiers d'entête ou au début du programme.

/*
Nom : structure.c
Role : Utilisation de structure.
Paramètres : non pris en compte.
Code retour : 0 (EXIT_SUCCESS)
Pour produire un exécutable avec le compilateur libre GCC :
   gcc -o structure.exe structure.c
Pour exécuter, tapez : ./structure.exe
*/
#include <stdio.h>
#include <stdlib.h>


struct CLIENT
{
  char nom[30];
  float solde;
};

int main(int argc, char argv[])
{
  struct CLIENT cl={"Smith", 15.5}; // déclaration + initialisation

  /* Exemple d’utilisation des membres de la structure */
  (void)printf("Nom : %s\nSolde : %f\n", cl.nom, cl.solde);

   (void)puts("Fin du programme structure");  
   return EXIT_SUCCESS;
}

Le résultat :

$ ./structure.exe 
Nom : Smith
Solde : 15.500000
Fin du programme structure
  Faîtes les exercices du WikiLivre Exercices en langage C sur les types.


  1. https://www6.inrae.fr/mia-paris/content/download/4374/41417/version/1/file/Support_cours_MAPC_2016-web-sans-correction.pdf
  2. https://docs.microsoft.com/en-us/cpp/cpp/data-type-ranges?view=vs-2019