Vous êtes sur la page 1sur 41

ECOLE SUPERIEURE D’ADMINISTRATION ET DE GESTION NOTRE DAME DE L’EGLISE

BP : 8019 * Tél : 22-21-68-58 * Lomé-TOGO / SITE WEB : www.esagnde.org / E-mail : esagnde@esag-.org

Semestre 3
Filières : TIG / ISI

Année académique : 2023-2024

SUPPORT DE COURS

LANGAGE C
MODULE 1

Simon Pierre EDOH


Ingénieur Génie Logiciel
CHAPITRE
INTRODUCTION
0
Un peu d’histoire
Le langage C a été inventé au cours de l'année 1972 dans les Laboratoires Bell. Il était
développé par Dennis Ritchie et Ken Thompson avec un objectif relativement limité : écrire
un système d’exploitation (UNIX). Mais ses qualités opérationnelles l’ont très vite fait
adopter par une large communauté de programmeurs Ken Thompson avait développé un
prédécesseur de C, le langage B, qui est lui-même inspiré de BCPL. Dennis Ritchie a fait
évoluer le langage B dans une nouvelle version suffisamment différente, en ajoutant
notamment les types, pour qu'elle soit appelée C.

Une première définition de ce langage est apparue en 1978 avec l’ouvrage de Kernighan et
Ritchie The C programming language. Mais ce langage a continué d’évoluer après cette
date à travers les différents compilateurs qui ont vu le jour. Son succès international a
contribué à sa normalisation, d’abord par l’ANSI (American National Standard Institute), puis
par l’ISO (International Standards Organization), plus récemment en 1993 par le CEN
(Comité européen de normalisation) et enfin, en 1994, par l’AFNOR. En fait, et fort
heureusement, toutes ces normes sont identiques, et l’usage veut qu’on parle de « C ANSI
» ou de « C norme ANSI ».

A la même époque (1983), Bjarne Stroustrup créa sa première version du langage C++.
Celui-ci est une extension du langage C afin de permettre la programmation orientée objets.
Plus tard, dans les années 95, Java prendra place parmi la grande lignée des langages
dérivés de C. Quoi qu'il en soit, C (voir C++) reste à l'heure actuelle, le langage
incontournable dans les domaines ou les performances (et les temps de réponses) sont de
mises.

Présentation
Un programme C est un ensemble d’instructions qui se saisit dans un fichier .c à l’aide d’un
éditeur (ex. : Notepad), ce type de fichier s’appelle une source. Les instructions qui y sont
écrites s’appellent du code ou encore le code source. Un compilateur est un logiciel qui lit
le code source et le convertit en un code exécutable, c’est-à-dire un ensemble d’instructions
compréhensible par le processeur. La compilation d’une source se fait en deux étapes : la
compilation proprement dite et le linkage. On utilise en général le terme compilation en
englobant les deux étapes précédemment citées.

–La compilation à proprement parler produit un fichier objet, dont l’extension est .obj.
– Les sources peuvent être réparties dans plusieurs fichiers, ceux-ci doivent tous ˆêtre
compiles s´séparément.
Ensuite, le linkage des différents fichiers objets est assemblage produisant un
exécutable .exe.

Les différents compilateurs C


Quand on parle de langages de programmation, on peut souvent les classer selon différents
critères. Par rapport à notre débat actuel, on peut opposer les langages de programmation
interprétés et les langages compilés. Un langage interprété (Javascript, basic, ...)

2
présuppose qu'un environnement d'exécution soit installé sur le poste pour interpréter les
différentes instructions du langage et les exécuter : ces langages ne permettent pas de
produire des exécutables très efficace (efficace certes, mais pas les plus efficaces). Au
contraire, les langages compilés (C, C++, ...) garantissent les meilleures performances étant
donné que le code source est traduit une fois pour toute (avant la première exécution) en
langage machine. Pour rappel, le langage machine est le seul langage qui puisse être
directement exécuté par votre processeur. Ainsi, les langages compilés évitent les étapes
de traduction du code durant l'exécution (l'interprétation).

Un compilateur est un outil qui permet donc la transformation d'un code source en langage
machine. Le langage C nécessite donc un compilateur pour traduire, une fois pour toute,
votre code source C. Il existe plusieurs compilateurs C, en fonction du système d'exploitation
utilisé et des sociétés d'édition logiciel retenues. Voici une description de quelques
compilateurs C.

gcc (Gnu C Compiler)


En premier lieu, il est important de noter que le terme gcc est ambigu : il est associé à deux
éléments.

 gcc - Gnu C Compiler : le compilateur C à proprement parlé. Historiquement, c'est le


premier compilateur de la collection GCC à avoir été développé.
 GCC - Gnu Compiler Collection : une collection d'outils de compilation pour différents
langages de programmation (C, C++, Java, Objective-C, Fortran, Ada, et Go). Bien
entendu, cette collection de compilateur inclu gcc, d'où l'ambiguïté.

Le compilateur gcc est développé sur les différentes plates-formes Linux/Unix. Il est connu
pour relativement bien supporter les différentes versions du standard ISO du langage C. Il
produit des exécutables efficaces. Il est considéré comme une référence en termes de
compilateur C. De plus, il permet de faire de la « cross-compilation » : cela permet de
travailler sur une plate-forme et d'y produire un exécutable pour une autre plate-forme.

MinGW (MINimalist Gnu for Windows)


Il s'agit d'un portage du compilateur gcc pour la plate-forme Microsoft Windows.

L'ensemble des options proposées par MinGW restent les mêmes que celles de gcc. Il en
résulte que les informations proposées tout au long de ce cours pour compiler vos
programmes s'appliquent donc parfaitement à MinGW. Il est intégré dans Code::Blocks.

Remarque : c’est l’éditeur Code ::Blocks que nous considérerons pour la compilation des
exemples de code tout au long de notre cours.

Clang
Ce compilateur est une alternative à gcc. Le site officiel de Clang est disponible à l'adresse
Internet suivante : http://clang.llvm.org. Il est notamment utilisé sur les plates-formes Mac,
mais peut aussi être utilisé sur d'autres plates-formes. Il permet aussi la cross-compilation.

Visual C++
Le terme « Visual C++ » est utilisé pour qualifier l'ensemble des outils liés au développement
C++ sous l'environnement Visual Studio de la société Microsoft. Dans cet ensemble d'outils,
vous trouverez notamment le compilateur C++ de la société Microsoft. Ce dernier est très
performant et supporte relativement bien les derniers standards du langage C. Sur
environnement Windows, il est donc en concurrence avec le compilateur MinGW.

3
Présentation de Code ::Block
 Téléchargement de Code::Blocks
Comme indiqué plus faut, nous allons utiliser l' IDE CODE::BLOCKS.
Il est en anglais mais nous irons rarement scruter les menus. Je l'ai choisi car il permet de
programmer en C et en C++.

De plus, c'est un IDE libre (open source) il peut donc être développé par n'importe qui, il
est gratuit, et ce que vous produisez avec vous appartient.

Si vous allez sur le site Code::Blocks pour le télécharger il y a deux Code::Blocks


différents :

 codeblocks-x.xx-setup.exe
 codeblocks-x.xx.mingw-setup.exe

Il faut prendre le deuxième car il inclue le compilateur et le débugger.

 Prise en main de Code::Blocks


Pour créer un nouveau projet, cliquez sur File puis New et Project..., certes,
c'est anglais, mais il ne faut pas abuser, c'est facile ça.

Une image pour ceux qui n'ont pas suivi...

Maintenant, on vous propose plusieurs modèles (templates).

Sans rentrer dans les détails, c'est pour se faciliter la vie, par exemple si vous
utilisez Console application, Code::Blocks va vous préparer le terrain et vous pourrez
programmer en console.

4
Oui, pour l'instant nous allons nous contenter de la console Windows...

Nous allons travailler sur cette console pendant un bon bout de temps et après vous
pourrez approfondir et passer à la programmation en fenêtre si ça vous tente. Vous
verrez qu'on peut créer des jeux avec cette console.

Elle reste cependant très théorique.

5
Code::Blocks nous demande notre langage, sélectionnez le C.

Ici, il vous faut donner un nom à votre projet et un chemin.


Je vous conseille de créer votre projet dans la même partition que votre
dossier Code::Blocks.

Ensuite, sélectionnez le compilateur que vous voulez utiliser, ici, c'est GNU GCC
Compiler qui nous intéresse puisqu'il est capable de compiler le C.

GCC est l'abréviation de GNU Compiler Collection (c'est le compilateur créé par le
projet GNU).

Il s'agit en réalité d'une collection de logiciels libres intégrés capables de compiler divers
langages de programmation comme le C et le C++. Dire que GCC est un compilateur est
donc un abus de langage adopté par la plupart des programmeurs.

6
Il faut aussi choisir une configuration de compilation...

 Debug, si vous voulez faire une recherche poussée de vos erreurs (on ne le fera jamais
donc un peu inutile). Ce mode alourdi l'exécutable puisqu'il conserve toutes les
informations pour débugger, mais la compilation est plus rapide.
 Et Release, si vous voulez optimiser votre programme au maximum pour qu'il puisse
être transporté de machine en machine.

En effet, pour partager un programme à vos amis, il faut compiler en Release et non pas
en Debug.

Je vous conseille donc de cocher soit Release ou soit Release et Debug.

Il est mieux de compiler en Debug pour tester votre programme mais une fois ce
dernier terminé, il faut le compiler en Release pour pouvoir le partager.

Maintenant nous allons faire une vérification pour voir si vous avez bien
votre compilateur prêt à l’emploi.

Allez dans Compiler and debugger... dans Settings.

Ensuite, dans Toolchain executables, cliquez sur Auto-detect.

Si ça ne détecte pas, aller chercher les executables un par un dans le répertoire


C:\Programm Files\CodeBlocks\MinGW\bin pour obtenir la fenêtre ci-dessous.

7
Bien sûr, avec un PC en 64 bits, l'autodection aurait fonctionnée. Mais si c'est trop
facile, ce n’est pas drôle.

Maintenant, à gauche dans l'onglet Projects, cliquez sur main.c dans l'arborescence de
votre projet.

Du code source doit s'afficher à droite. C'est le contenu du fichier main.c que vous
pouvez maintenant éditer !

8
Regardez ces boutons importants :

 Build permet de compiler (presque) tous les fichiers source de votre projet afin de créer
un exécutable.
S'il y a des erreurs lors de la compilation (ça arrive vite ça), la petite fenêtre tout en bas Build
messages vous informera des erreurs et affichera (dans le meilleur des cas) un carré
rouge au début d'une ligne dans votre code source (on en reparlera un peu plus loin).

 Run exécute le dernier exécutable créé.


Qu'il soit créé en mode Debug ou Release, il sera quand même exécuté.

 Build and run permet de réaliser la compilation puis l'exécution du programme.


Build est la traduction de compiler et run d'exécuter.

 Rebuild permet de compiler tous les fichiers sources sans exceptions.


En effet, le bouton Build compile seulement les fichiers ayant subis des modifications.
On l'utilise plus rarement mais est tout de même utilisé.

A droite de ces boutons, vous voyez Build target, c'est ici que vous devez choisir votre
mode de compilation, comme je veux compiler rapidement et que je n'ai pas envie de
transporter mon programme, j'utilise Debug.

Appuyez sur F9 pour faire un Build and run et admirez le résultat du code source par
défaut (le code source minimal) :

Ne vous occupez pas des deux dernières lignes, ce sont juste des informations générées
par Code::Blocks, elle n'apparaissent pas si vous lancez votre exécutable depuis
l'explorateur Windows.

9
Donc du coup, le programme ne se met pas en pause et vous ne pouvez pas lire ce qu'il
affiche.
On réglera ça dans le prochain chapitre, allons voir notre dossier de notre projet...

 Les fichiers *.C sont les fichiers que vous avez écrits à la main en C via votre IDE.
Je prends comme exemple main.c.
 Les fichiers dans le dossier obj portant l'extension *.O (ou *.OBJ) peuvent être
supprimés, ce sont des fichiers temporaires.

On les appelle généralement des objets (d'où obj) ou des relogeables.


Ce sont des fichiers (ici il y en a qu'un, main.o, car on a compiler qu'un fichier *.C) écrits
en langage machine ayant servis à la compilation (quand je vous disais que notre schéma
d'une compilation était incomplet ).

Voici notre nouveau schéma, toujours incomplet mais plus réaliste.

Le petit fichier *.O au milieu fait un peu tâche je vous l'accorde.

En effet, l'utilité du fichier *.O n'est pas compréhensible pour le moment, mais il ne va
pas tarder à l'être.

Nous sommes enfin prêts à programmer !

10
CHAPITRE
NOTION DE BASE
1
Pour n'importe quel programme, il faudra taper un minimum de code. Ce code ne fera rien
de particulier, mais il est indispensable.

C'est ce "code minimum" que nous allons découvrir maintenant. Il devrait servir de base
pour la plupart de vos programmes en langage C.

Demandez le code minimal à votre IDE


Selon l'IDE que vous avez choisi dans le chapitre précédent, la méthode pour créer un
nouveau projet n'est pas la même. Reportez-vous à ce chapitre précédent si vous avez
oublié comment faire.

Pour rappel, sous Code::Blocks (qui est l'IDE que je vais utiliser tout au long de ce cours),
il faut aller dans le menu File / New / Project, puis choisir Console
Application et sélectionner le langage C.

Code::blocks a donc généré le minimum de code en langage C dont on a besoin. Le voici :

Notez que la ligne :

... peut aussi s'écrire :

Les 2 écritures sont possibles, mais la seconde (la compliquée) est la plus courante. J'aurai
donc tendance à utiliser plutôt cette dernière dans les prochains chapitres. En ce qui nous
concerne, que l'on utilise l'une ou l'autre des écritures, ça ne changera rien pour nous.

Analysons le code minimal "Hello World !"


Ce petit programme a pour but d'écrire "hello world" sur l'écran.

En algorithmique, ce programme s'écrirait :


programme HELLO_WORLD
écrire "hello world"
fin programme

11
Traduit en C, cela devient :
#include <stdio.h>
main()
{
printf("hello world\n");
return 0;
}
On approfondira les composantes de ce programme dans la suite du chapitre...

1. Les composantes d'un programme en C


a. Les fonctions
En C, le programme principal et les sous-programmes sont définis comme fonctions. Il
n'existe pas de structures spéciales pour le programme principal ni les procédures (comme
en Pascal ou en langage algorithmique).
Le programme principal étant aussi une "fonction", nous devons nous intéresser dès le
début à la définition et aux caractéristiques des fonctions en C. Commençons par comparer
la syntaxe de la définition d'une fonction en C avec celle d'une fonction en langage
algorithmique:

Définition d'une fonction en algorithmique


fonction <NomFonction> (<NomVar1>,...) : <TypeRésultat>
<déclaration des paramètres (Var1 : TypeVar1...)>
<déclaration locale>
<instructions propres>
fin_fonction

Définition d'une fonction en C


<TypeRésultat> <NomFonction> (<TypeVar1> <NomVar1>,...)
{
<déclaration locales>
<instructions>
}
Avec :
<TypeRésultat> - le type du résultat de la fonction
< NomFonction> - le nom de la fonction
<TypeVar> - les types des paramètres de la fonction
<NomVar1> - les noms des paramètres de la fonction
<déclaration locales> - les déclarations des variables locales (soit celles qui sont
uniquement connues à l'intérieur de la fonction)
<instructions> - la liste des instructions qui définit l'action qui doit être exécutée

Résultat d'une fonction


Par définition, toute fonction en C fournit un résultat dont le type doit être défini.
Si aucun type n'est défini explicitement, C suppose par défaut que le type du résultat
est int (integer). Le retour du résultat se fait en général à la fin de la fonction par
l'instruction return.

Le type d'une fonction qui ne fournit pas de résultat (comme les procédures en langage
algorithmique ou en Pascal), est déclaré comme void (vide).

12
Paramètres d'une fonction
La définition des paramètres (arguments) d'une fonction est placée entre parenthèses ()
derrière le nom de la fonction.
Si une fonction n'a pas besoin de paramètres, les parenthèses restent vides ou
contiennent le mot void.
La fonction minimale qui ne fait rien et qui ne fournit aucun résultat est alors:
void dummy()
{
}

Instructions
En C, toute instruction simple est terminée par un point-virgule ; (même si elle se trouve
en dernière position dans un bloc d'instructions). Par exemple: printf("hello, world\n");

b. La fonction "main"
La fonction main est la fonction principale des programmes en C :
Elle se trouve obligatoirement dans tous les programmes.
L'exécution d'un programme entraîne automatiquement l'appel de la fonction main.
Dans les premiers chapitres, nous allons simplement "traduire" la structure programme du
langage algorithmique par une définition équivalente de la fonction main :

Définition du programme principal en langage algorithmique


programme <NomProgramme>
<déclarations>
<instructions>
fin_programme

Définition de la fonction main en C


main()
{
<déclarations>
<instructions>
return 0;
}

Résultat de la fonction « main » :


- En principe tout programme devrait retourner une valeur comme code d'erreur à son
environnement. Par conséquent, le type résultat de main est toujours int. En général, le
type de main n'est pas déclaré explicitement, puisque c'est le type par défaut.
Nous allons terminer nos programmes par l'instruction: "return 0;" qui indique à
l'environnement que le programme s'est terminé avec succès, sans anomalies ou erreurs
fatales.

Paramètres de main
- Si la liste des paramètres de la fonction main est vide, il est d'usage de la déclarer par ().
- Si nous utilisons des fonctions prédéfinies (par exemple : printf), il faut faire précéder la
définition de main par les instructions #include correspondantes (soit inclure la librairie qui
contient la fonction désirée).

Remarque avancée :
Il est possible de faire passer des arguments de la ligne de commande à un programme.
Dans ce cas, la liste des paramètres doit contenir les déclarations correspondantes.

13
Dans notre cours, nous n'allons pas utiliser des arguments de la ligne de commande.
Ainsi la liste des paramètres de la fonction main sera vide (void) dans tous nos exemples
et nous pourrons employer la déclaration suivante qui fait usage des valeurs par défaut :
main()
{
}

Voici un exemple de programme utilisant des arguments de la ligne de commande :


Avec la forme : int main(int arg_n ; char *arg_v[]), on peut passer des paramètres sur la
ligne d'exécution.

Ainsi, on a le programme MyProg.c :


#include <stdio.h>
int main(int arg_n ; char *arg_v[])
{
int i;
for (i=0 ; i < arg_n ; i++) { printf("Le paramètre %d est %s\n" , i , arg_v[i]); }
return 0;
}
Si j'execute MyProg de la facon suivante:
MyProg Param1 Param2 Param3
J'aurai comme resultat :
Le paramètre 0 est MyProg (MyProg étant la valeur renvoyée par MyProg, soit 0)
Le paramètre 1 est Param1
Le paramètre 2 est Param2
Le paramètre 3 est Param3

c. Les variables
Les variables contiennent les valeurs qui sont utilisées pendant l'exécution du
programme.
Les noms des variables sont des identificateurs quelconques.
Les différents types de variables simples et les opérateurs admissibles sont discutés au
chapitre 3.

d. Les identificateurs
Les noms des fonctions et des variables en C sont composés d'une suite de lettres et de
chiffres.
Le premier caractère doit être une lettre.
Le symbole '_' est aussi considéré comme une lettre.
* L'ensemble des symboles utilisables est donc: {0,1,2,...,9,A,B,...,Z,_,a,b,...,z}
* Le premier caractère doit être une lettre (ou le symbole '_')
* C distingue les majuscules et les minuscules, ainsi: "Nom_de_variable" est différent de
"nom_de_variable"
* La longueur des identificateurs n'est pas limitée, mais C distingue 'seulement' les 31
premiers caractères.

Remarques :- Il est déconseillé d'utiliser le symbole '_' comme premier caractère pour un
identificateur, car il est souvent employé pour définir les variables globales de
l'environnement C.

Le standard dit que la validité de noms externes (par exemple : noms de fonctions ou
variables globales) peut être limité à 6 caractères (même sans tenir compte des majuscules
et minuscules) par l'implémentation du compilateur, mais tous les compilateurs modernes

14
distinguent au moins 31 caractères de façon que nous pouvons généraliser qu'en pratique
les règles ci-dessus s'appliquent à tous les identificateurs.

Exemple :
Identificateurs corrects : nom1 / nom_2 / _nom_3 / Nom_De_Variable
Identificateurs incorrects : 1nom / nom.2 / -nom-3 / Nom De Variable

e. Les commentaires
Un commentaire commence toujours par les deux symboles "/*" et se termine par les
symboles "*/".
Il est interdit d'utiliser des commentaires imbriqués.
Exemples :
/* Ceci est un commentaire */

2. Discussion de l'exemple "Hello World"


#include <stdio.h>
main()
{
printf("hello world\n");
return 0;
}

Discussion :
- La fonction main ne reçoit pas de données, donc la liste des paramètres est vide.
- La fonction main fournit un code d'erreur numérique à l'environnement, donc le type du
résultat est int et n'a pas besoin d'être déclaré explicitement.
- Le programme ne contient pas de variables, donc le bloc de déclarations est vide.
- La fonction main contient deux instructions :

 l'appel de la fonction printf avec l'argument "hello world\n";

Effet : Afficher la chaîne de caractères "hello world", et passer à la ligne.

 la commande return avec l'argument 0;

Effet : Retourner la valeur 0 comme code d'erreur à l'environnement.

- L'argument de la fonction printf est une chaîne de caractères indiquée entre les guillemets.
Une telle suite de caractères est appelée chaîne de caractères constante (string constant).

- La suite de symboles "\n" à la fin de la chaîne de caractères "hello, world\n" est la notation
C pour passer à la ligne (angl: new line). En C, il existe plusieurs couples de symboles qui
contrôlent l'affichage ou l'impression de texte.

Ces séquences d'échappement sont toujours précédées par le caractère d'échappement


"\".
Les différentes séquences possibles sont :
\n - nouvelle ligne
\v - tabulation verticale
\t - tabulation
\b - curseur arrière
\r - retour au début de ligne
\" - guillemets

15
\0 - NULL
\a - sonnerie
\\ - trait oblique
\' - apostrophe
\? - point d'interrogation
\f - saut de page (imprimante)

printf et la bibliothèque <stdio.h> :


La fonction printf fait partie de la bibliothèque de fonctions standard <stdio.h> qui gère les
entrées et les sorties de données.

La première ligne du programme : #include <stdio.h> instruit le compilateur d'inclure le


fichier en-tête "STDIO.H" dans le texte du programme.

Le fichier "STDIO.H" contient les informations nécessaires pour pouvoir utiliser les
fonctions de la bibliothèque standard.

16
CHAPITRE
TYPE ET OPERATEURS
2
Introduction
Les variables et les constantes sont les données principales qui peuvent être manipulées
par un programme. Les déclarations introduisent les variables qui sont utilisées, fixent leur
type et parfois aussi leur valeur de départ. Les opérateurs contrôlent les actions que
subissent les valeurs des données. Pour produire de nouvelles valeurs, les variables et les
constantes peuvent être combinées à l'aide des opérateurs dans des expressions.

Le type d'une donnée détermine l'ensemble des valeurs admissibles, le nombre d'octets à
réserver en mémoire et l'ensemble des opérateurs qui peuvent y être appliqués.

Motivation
La grande flexibilité de C nous permet d'utiliser des opérandes de différents types dans un
même calcul.

Cet avantage peut se transformer dans un terrible piège si nous ne prévoyons pas
correctement les effets secondaires d'une telle opération (conversions de type
automatiques, arrondissements, etc.).

Une étude minutieuse de ce chapitre peut donc aider à éviter des phénomènes parfois
"inexplicables"...

1. Les différents types de variable


Nous avons vu une première définition d'une variable en nous aidant du fonctionnement de
la RAM.
Je vous ai dit qu'une variable est typée, nous allons voir les différents types de
variables les plus courants.
Chaque type peut stocker ses propres nombres, voyons ensemble les types principaux.

Type de donnée Signification Plage de valeurs acceptée

char Caractère -128 à 127

long Entier long (sur processeur 32 bits) -2147483648 à 2147483647

int Entier (sur processeur 16 bits) -32768 à 32768

float Flottant (réel) -3.4*10^38 à 3.4*10^38

double Flottant double -1.7*10^308 à 1.7*10^308

unsigned char Caractère non signé 0 à 255

unsigned long Entier long non signé 0 à 4294967295

unsigned int Entier non signé 0 à 4294967295

Oui, et il existe encore de nombreux types en langage C, j'ai conservé ici les principaux

17
Remarquez, les types précédés du terme unsigned n'ont pas de signe, on dit qu'ils sont non
signés mais peuvent donc stocker plus de nombres positifs (2 fois plus que le type
signé).
Pourquoi avoir créé plein de types ? Le type double n'aurait pas suffit ?
Oui, il aurait suffi mais je n'appelle pas ça économiser de la mémoire (c'est un peu le but),
effectivement, un double occupera plus de place en mémoire qu'un char.
Je vous présente les types de variables que nous allons utiliser le plus souvent dans ce
cours.

 char qui permet de stocker des lettres, en effet, il existe la table ASCII qui convertit
des nombres en lettres.
Par exemple, le nombre 65 correspond à la lettre A, 66 à la lettre B...
Le type char est donc utilisé 99% des cas pour stocker une lettre (oui, une seule
lettre).
 int qui permet de stocker des nombres entiers, le type long aurait été aussi bien, il
faut bien faire un choix.
Il y a quelques années, le type long comportait quelques différences avec le type int,
pour des raisons de compatibilité, il a été conservé. Le type int est agréable à utiliser,
on s'en sert pour stocker tous les nombres entiers (même 0 et 1).
Vous aurez peut-être l'impression de gâcher de la mémoire, mais ce n'est
vraiment pas ce qui manque sur un ordinateur.
 double qui permet de stocker des nombres décimaux, donc avec une virgule.
Attention, en programmation, la virgule est représentée par un point (.).
Comme pour le int, on s'en servira pour stocker tous les nombres décimaux.

Voilà en résumé les types que nous allons utiliser le plus souvent, avec ces 3 types on
peut faire des merveilles.
Nous allons maintenant programmer un peu !

2. La déclaration des variables


Maintenant que nous connaissons les principaux types de variables, il nous faut encore la

Syntaxe pour leur déclaration :


Déclaration de variables en algorithmique
<Type> <NomVar1>, <NomVar2>, ...

Déclaration de variables en C
<Type> <NomVar1>, <NomVar2>, ...
... en gros, il s'agit de la même architecture... (C’était vraiment très intéressant, merci, au
revoir...) ;)

Par exemple,
en algorithmique, on a : traduit en C, cela devient :

entier n1 , n2 int n1 , n2 ;
réel r1 , r2 float r1 ;
caractère c1 double r2 ;
boolléen b1 char c1 ;
char b1 ;

18
Remarques
 r1 est passé du type algo réel à float en C, alors que r2 est passé de réel à double.
Cela s'explique par le fait qu'on a choisi de coder r1 sur seulement 4 octets, et r2 sur
8 octets (on aurait donc besoin de pouvoir monter plus haut en valeur avec r2 qu'avec
r1...).
 le type algorithmique "booléen" (VRAI / FAUX) n'existe pas en C, on utilise alors un
type numérique (int ou char, qui se code sur moins d'octets) pour le représenter.
VRAI devient alors la valeur numérique 1, et FAUX devient 0.
 le type algorithmique "chaines de caractères" n'existe pas non plus, on utilise des
tableaux de caractères... mais on étudiera cela plus loin.

3. Initialisation de variables
Pour rendre notre programme plus propre et aux normes, il est préférable d'initialiser la
variable dès sa déclaration, elle n'aura même pas le temps de prendre une
valeur hasardeuse.

Exemples :
int MAX=1023;
char TAB="\t";
float X=1.05e-4;

int main()
{
int maVariable = 5;
printf("maVariable = %d", maVariable);
return 0;
}

4. Les constantes
Le mot clé const permet la déclaration des constantes.
En utilisant l'attribut const, nous pouvons indiquer que la valeur d'une variable ne change pas
au cours d'un programme. Il suffit d'ajouter le mot clé const devant le type de la variable lors
de la déclaration pour rendre la variable constante (sa valeur ne peut pas être modifiée).

Exemples :
const int MAX=767;
const double e=2.71828182845905;
const char NEWLINE="\n";

int main()
{
const int MA_CONSTANTE;
maConstante = 5;
printf("MA_CONSTANTE = %d", MA_CONSTANTE);
return 0;
}

Ici, j'ai changé le type d'écriture du nom de la variable, j'utilise les majuscules et
un underscore (_), prenez l'habitude de déclarer vos constantes avec des majuscules,
le code source sera par la suite plus clair.

Le compilateur nous sort une erreur nous demandant pourquoi on essaie de modifier la
valeur d'une constante (logique).

19
La variable MA_CONSTANTE comporte une valeur dès sa déclaration (qui peut être
n'importe quoi), il faut donc l'initialiser dès sa déclaration pour lui assigner une valeur de
notre choix.

const int MA_CONSTANTE = 5;

5. Les opérateurs
a. Les opérateurs arithmétiques
Les opérateurs de calcul arithmétiques permettent d'effectuer des opérations
mathématiques entre deux valeurs et seulement deux valeurs. Ils sont très simples à utiliser,
c'est comme les mathématiques à l’école.
Opérateurs Descriptions Exemples
int maVariable = 5 + 12;
+ addition
/* maVariable vaut 17 */
- int maVariable = 5 - 12;
soustraction
/* maVariable vaut -7 */
int maVariable = 3 * 4;
* multiplication
/* maVariable vaut 12 */
division int maVariable = 12 / 3;
/
/* maVariable vaut 4 */
int maVariable = 20 % 3;
%
Modulo (reste de la division entière) /* maVariable vaut 2
(car 20 = 3 * 6 + 2) */

b. Opérateurs d'Accumulation
Pour chacun des opérateurs de calcul, il existe un opérateur
d'accumulation permettant d'alléger l'écriture en évitant les opérations de la
forme maVariable = maVariable + 2.

Il existe également deux opérateurs spécifiques pour l'incrémentation (++) et


la décrémentation (--) unitaire.
Opérateurs Descriptions
Exemples
(i = 4)

+=
addition i += 5;
/* i vaut 9 */

++ incrémentation unitaire
i++;
/* i vaut 5 */

-= soustraction
i -= 3;
/* i vaut 1 */

-- décrémentation unitaire
i--;
/* i vaut 3 */

*= multiplication
i *= 4;
/* i vaut 16 */

20
/= division
i /= 2;
/* i vaut 2 */

i %= 3;
%= modulo /* i vaut 1
(car 4 = 3 * 1 + 1) */

Nota :
X = I++ passe d'abord la valeur de I à X et incrémente après
X = I-- passe d'abord la valeur de I à X et décrémente après
X = ++I incrémente d'abord et passe la valeur incrémentée à X
X = --I décrémente d'abord et passe la valeur décrémentée à X

c. Opérateurs Relationnels
Le résultat d'une opération relationnelle est une valeur booléenne.

Un booléen est une variable auquel on fait prendre les valeurs 0 et 1 (0 pour faux et 1 pour
vrai).

En réalité, toutes les valeurs différentes de 0 valent vrai mais on va éviter de compliquer les
choses.

En C, il n'y a pas de type consacré aux booléens, on utilisera donc un int qui peut prendre les
valeurs 0 et 1 pour simuler un booléen.

Tout d'abord, voilà le tableau :

Opérateurs Descriptions Exemples


== égal
int monBooleen = 8 == 7;
/* monBooleen vaut 0 */

!= différent
int monBooleen = 3 != 4;
/* monBooleen vaut 1 */

> supérieur
int monBooleen = 5 > 5;
/* monBooleen vaut 0 */

< inférieur
int monBooleen = 4 < 5;
/* monBooleen vaut 1 */

>= supérieur ou égal


int monBooleen = 5 >= 5;
/* monBooleen vaut 1 */

<= inférieur ou égal


int monBooleen = 5 <= 4;
/* monBooleen vaut 0 */

Avec les exemples du tableau, vous devez avoir compris pas mal de choses.

Voici un code source que j'ai écrit pour tester si l'utilisateur du programme est majeur.

21
int main()
{
int age = 0, majeur = 0;

printf("Quel age avez-vous ? ");


scanf("%d", &age);
majeur = age >= 18; // majeur vaut 1 (est vrai) si age est
supérieur ou égal à 18
printf("\nage = %d\nmajeur = %d", age, majeur);

return 0;
}

Cet exemple beaucoup plus concret nous affiche l'âge de l'utilisateur et la valeur du
booléen majeur (vaut 0 si age est inférieur à 18 et vaut 1 sinon).
Quel age avez-vous ? 43

age = 43
majeur = 1

On aura l'occasion d'en reparler au chapitre des conditionnelles, je n'insiste donc


pas, l'utilité de ces opérateurs ne doivent pas vous paraître évident tout de suite, retenez
juste que 1 veut dire vrai et 0 veut dire faux.

d. Opérateurs Logiques
Une opération logique est une opération booléenne qui renvoie une valeur booléenne.
Sans plus attendre, le tableau !

Opérateurs Descriptions Exemples


&& et
int monBooleen = 1 && 1;
/* monBooleen vaut 1 */

|| ou
int monBooleen = 0 || 0;
/* monBooleen vaut 0 */

! non
int monBooleen = !0;
/* monBooleen vaut 1 */

Voyons ensemble des exemples avec 3 variables, a, b et c.

a est le résultat d'une opération booléenne de b et c.


 a = b && c : a vaut 1 (est vrai) si et seulement si b et c valent 1 (sont vrais).
Si b vaut 0 (est faux) ou c vaut 0 (est faux), a vaut 0 (est faux).

 a = b || c : a vaut 1 si b vaut 1 ou si c vaut 1.


Si b et c valent 0, a vaut 0.

 a = !b : a vaut 1 si b vaut 0.
Si b vaut 0, a vaut 1.

22
Un exemple pour bien comprendre, on demande à l'utilisateur une boisson et une viande.
int main()
{
int boisson = 0, viande = 0, obese = 0;

printf("Que voulez-vous boire ?\n\n1. Eau\n2. Soda\n\n");


scanf("%d", &boisson);
printf("\nQue voulez-vous manger ?\n\n1. Hamburger\n2. Porc\n\n");
scanf("%d", &viande);
obese = viande == 1 && boisson == 2; // obese vaut 1 (est vrai) si viande est égal 1
(Hamburger) et si boisson est égal 2 (Soda)
printf("\nobese = %d", obese);

return 0;
}

C'est un peu compliqué mais avouez que c'est terriblement logique non ?
Si on a choisi le Soda (choix 2) et le Hamburger (choix 1) bien on est obèse, le booléen
obese vaut 1 (est vrai).
Que voulez-vous boire ?

1. Eau
2. Soda

Que voulez-vous manger ?

1. Hamburger
2. Porc

obese = 1

Je le reconnais, ce n'est pas une partie de plaisir, vous verrez dans le prochain chapitre que
tout cela a un sens incroyable (oui je vous jure).

Retenez juste les descriptions de ces opérateurs, notez qu'ils s'utilisent fréquemment avec
les opérateurs relationnels et ce sera suffisant pour le moment.

6. Les expressions et les instructions


a. Expressions
La formation des expressions est définie par récurrence :
Les constantes et les variables sont des expressions.
Les expressions peuvent être combinées entre elles par des opérateurs et former ainsi
des expressions plus complexes.
Les expressions peuvent contenir des appels de fonctions et elles peuvent apparaître
comme paramètres dans des appels de fonctions.

Exemples :
i=0

23
i++
X = pow(A,4)
printf(" Bonjour !\n")
a = (5*x+10*y)*2
(a+b) >= 100
position != limite

b. Instructions
Une expression comme I=0 ou I++ ou printf(...) devient une instruction, si elle est suivie
d'un point-virgule.
Exemples :
i=0;
i++;
X=pow(A,4);
printf(" Bonjour !\n");
a=(5*x+10*y)*2;

c. Evaluation et résultats
En C toutes les expressions sont évaluées et retournent une valeur comme résultat :
(3+2==5) retourne la valeur 1 (VRAI)
A=5+3 retourne la valeur 8
Comme les affectations sont aussi interprétées comme des expressions, il est possible de
profiter de la valeur rendue par l'affectation :
((A=sin(X)) == 0.5)

7. Les fonctions arithmétiques standard


Les fonctions suivantes sont prédéfinies dans la bibliothèque standard <math.h>. Pour
pouvoir les utiliser, le programme doit contenir la ligne :
#include <math.h>
Type de données
Les arguments et les résultats des fonctions arithmétiques sont du type double.
exp(X) fonction exponentielle
log(X) logarithme naturel ln(X)
log10(X) logarithme à base 10
pow(X,Y) X exposant Y
sqrt(X) racine carrée de X
fabs(X) valeur absolue de X
floor(X) arrondir en moins
ceil(X) arrondir en plus
fmod(X,Y) reste rationnel de X/Y (même signe que X)
sin(X) cos(X) tan(X) sinus, cosinus, tangente de X
asin(X) acos(X) atan(X) arcsin(X), arccos(X), arctan(X)
sinh(X) cosh(X) tanh(X) sinus, cosinus, tangente hyperboliques de X
Cette liste des fonctions ne cite que les fonctions les plus courantes.
Pour la liste complète et les constantes prédéfinies voir la définition de <math.h>.

8. Les conversions de type


La grande souplesse du langage C permet de mélanger des données de différents types
dans une expression.
Avant de pouvoir calculer, les données doivent être converties dans un même type.
La plupart de ces conversions se passent automatiquement, sans l'intervention du
programmeur, qui doit quand même prévoir leur effet.
Parfois il est nécessaire de convertir une donnée dans un type différent de celui que

24
choisirait la conversion automatique ; dans ce cas, nous devons forcer la conversion à l'aide
d'un opérateur spécial (cast).

a. Les conversions automatiques :


i. Calculs et affectations
Si un opérateur a des opérandes de différents types, les valeurs des opérandes sont
converties automatiquement dans un type commun.

Ces manipulations implicites convertissent en général des types plus "petits" en des types
plus "larges" ; de cette façon on ne perd pas en précision.

Lors d'une affectation, la donnée à droite du signe d'égalité est convertie dans le type à
gauche du signe d'égalité.

Dans ce cas, il peut y avoir perte de précision si le type de la destination est plus faible
que celui de la source.

ii. Appels de fonctions


Lors de l'appel d'une fonction, les paramètres sont automatiquement convertis dans les
types déclarés dans la définition de la fonction.

iii. Règles de conversion automatique


Conversions automatiques lors d'une opération avec...
1. deux entiers :
les types char et short sont convertis en int, ensuite, l'ordinateur choisit le plus large des
deux types dans l'échelle suivant e: int, unsigned int, long, unsigned long.
2. un entier et un rationnel :
Le type entier est converti dans le type du rationnel.
3. deux rationnels :
on choisit le plus large des deux types selon l'échelle suivante: float, double, long double
4. affectations et opérateurs d'affectations :
Lors d'une affectation, le résultat est toujours converti dans le type de la destination. Si ce
type est plus faible, il peut y avoir une perte de précision.

iv. Phénomènes imprévus


Le mélange de différents types numériques dans un calcul peut inciter à ne pas tenir
compte des phénomènes de conversion et conduit parfois à des résultats imprévus... A
éviter donc...

b. Les conversions forcées :


Il est possible de convertir explicitement une valeur en un type quelconque en forçant la
transformation à l'aide de la syntaxe: (<Type>) <Expression>
Exemple : VariableRationnelle = (float) VariableEntiere

9. Définition de constantes et de macros


On peut définir des constantes utiles lors du paramétrage du programme que l'on vient de
coder.

a. Définition d'une constante


#define Nom_Variable 12
main()
{

25
int n = Nom_Variable;
}

Le compilateur remplace limit par 12 partout dans le programme. Il n'est pas nécessaire
de mettre un ; à la fin de la définition d'une constante.

b. Les macros
Une macro est une fonction à paramètre qui renvoie le résultat de l'opération logique à
effectuer sur ces paramètres.
Les macros à paramètres sont surtout utiles dans C, car dans C++ on peut définir du code
"en ligne" qui joue presque le même rôle, mais est mieux testé par le compilateur.
Dans l'exemple ci-dessous, une macro est définie puis utilisée.
#define DoubleByte(a,b) ((a<<8) | (b&255))
int i = DoubleByte(12,200);

26
CHAPITRE
LES ENTRÉES/SORTIE
3
Introduction
La bibliothèque standard <stdio.h> contient un ensemble de fonctions qui assurent la
communication de la machine avec le monde extérieur.

Dans ce chapitre, nous allons en discuter les plus importantes :


printf() écriture formatée de données
scanf() lecture formatée de données
putchar() écriture d'un caractère
getchar() lecture d'un caractère

1. Ecriture formatée de données


printf()
La fonction printf est utilisée pour transférer du texte, des valeurs de variables ou des
résultats d'expressions vers le fichier de sortie standard stdout (par défaut l'écran).

Utilisation :
printf("<format>" , <Expression1> , <Expression2> ...)
La partie <format> peut contenir :
- du texte
- des séquences d'échappement
- des spécificateurs de format (indiquent la manière dont les valeurs des expressions sont
imprimées)

Remarques :
Il doit toujours y avoir un spécificateur de format pour chaque expression, il commence
toujours par % et se termine par un ou deux caractères qui indiquent le format d'impression.

Exemple :
int A = 1234;
int B = 567;
printf("%i fois %i est %li \n", A, B, (long) A*B);
On a alors à l'écran:
1234 fois 567 est 699678
Les différents spécificateurs de format pour printf
%d ou %i int entier relatif
%u int entier naturel (unsigned)
%o int entier exprimé en octal
%x int entier exprimé en hexadécimal
%c int caractère
%f double rationnel en notation décimale
%e double rationnel en notation scientifique
%s char* chaîne de caractères
%f float rationnel
%e float rationnel représenté par sa forme : +/- <Mantisee> * 10 ^ <Exposant>

Remarque : Pour pouvoir traiter correctement les arguments du type long, il faut utiliser
les spécificateurs %ld, %li, %lu, %lo, %lx, %lf, %le.

27
Largeur minimale pour les entiers
Pour les entiers, nous pouvons indiquer la largeur minimale de la valeur à afficher.
Dans le champ ainsi réservé, les nombres sont justifiés à droite.
Exemples : (_ représente un espace vide)

printf("%4d", 123);
==> _123
printf("%4d", 1234);
==> 1234
printf("%4d", 12345);
==> 12345
printf("%4u", 0);
==> ___0
printf("%4X", 123);
==> __7B
printf("%4x", 123);
==> __7b

Largeur minimale et précision pour les rationnels


Pour les rationnels, nous pouvons indiquer la largeur minimale de la valeur à afficher et la
précision du nombre à afficher.
La précision par défaut est fixée à six décimales.
Les positions décimales sont arrondies à la valeur la plus proche.

Exemples :
printf("%f", 100.123);
==> 100.123000
printf("%12f", 100.123);
==> __100.123000
printf("%.2f", 100.123);
==> 100.12
printf("%5.0f", 100.123);
==> __100
printf("%10.3f", 100.123);
==> ___100.123
printf("%.4f", 1.23456);
==> 1.2346

2. Lecture formatée de données


scanf()
La fonction scanf est la fonction symétrique à printf ; elle nous offre pratiquement les
mêmes conversions que printf, mais en sens inverse.
Cette fonction reçoit ses données à partir du fichier d'entrée standard stdin (par défaut le
clavier).
Utilisation :
scanf("<Format>", <AdresseVariable1>, <AdresseVariable2>...)

 -<Format> : format de lecture des données


 <AdresseVariable1>, <AdresseVariable2>...: adresses des variables auxquelles les
données seront attribuées
 L'adresse d'une variable est indiquée par le nom de la variable précédé du signe &.

28
Exemple :
int JOUR, MOIS, ANNEE;
scanf("%i %i %i", &JOUR, &MOIS, &ANNEE);
Les différents spécificateurs de format pour scanf
%d ou %i int entier relatif
%u int entier naturel (unsigned)
%o int entier exprimé en octal
%x int entier exprimé en hexadécimal
%c int caractère
%f double rationnel en notation décimale
%e double rationnel en notation scientifique
%s char* chaîne de caractères
%f float rationnel
%e float rationnel représenté par sa forme : +/- <Mantisee> * 10 ^ <Exposant>

Indication de la largeur maximale


Pour tous les spécificateurs, nous pouvons indiquer la largeur maximale du champ à
évaluer pour une donnée.
Les chiffres qui passent au-delà du champ défini sont attribués à la prochaine
variable qui sera lue !

Exemple :
int A,B;
scanf("%4d %2d", &A, &B);
Si nous entrons le nombre 1234567, nous obtiendrons les affectations suivantes:
A=1234
B=56
le chiffre 7 sera gardé pour la prochaine instruction de lecture.

Nombre de valeurs lues


Lors de l'évaluation des données, scanf s'arrête si la chaîne de format a été travaillée
jusqu'à la fin ou si une donnée ne correspond pas au format indiqué. scanf retourne comme
résultat le nombre d'arguments correctement reçus et affectés.

Exemple :
int JOUR, MOIS, ANNEE, RECU;
RECU = scanf("%i %i %i", &JOUR, &MOIS, &ANNEE);
réagit de la façon suivante ( / représente uen valeur indéfinie) :
Introduit RECU JOUR MOIS ANNEE
12 4 1980 3 12 4 1980
12/4/1980 1 12 / /
12.4 1980 1 12 / /
12 4 19.80 3 12 4 19

3. Écriture d'un caractère


putchar()
La commande, putchar("a"); transfère le caractère a vers le fichier standard de
sortie stdout. Les arguments de la fonction putchar sont ou bien des caractères (des
nombres entiers entre 0 et 255) ou bien le symbole EOF (End Of File).
EOF est une constante définie dans qui marque la fin d'un fichier. La
commande putchar(EOF); est utilisée dans le cas où stdout est dévié vers un fichier.

29
Exemple :
char A = 225;
char B = "\a";
int C = "\a";
putchar("x"); /* afficher la lettre x */
putchar("?"); /* afficher le symbole ? */
putchar("\n"); /* retour à la ligne */
putchar(65); /* afficher le symbole avec le code 65 (ASCII: "A") */
putchar(A); /* afficher la lettre avec le code 225 (ASCII: "ß") */
putchar(B); /* beep sonore */
putchar(C); /* beep sonore */
putchar(EOF); /* marquer la fin du fichier */

4. Lecture d'un caractère


Une fonction plus souvent utilisée que putchar est la fonction getchar, qui lit le prochain
caractère du fichier d'entrée standard stdin.

Type du résultat
Les valeurs retournées par getchar sont ou bien des caractères (0 - 255) ou bien le
symbole EOF.

Comme la valeur du symbole EOF sort du domaine des caractères, le type résultat
de getchar est int. En général, getchar est utilisé dans une affectation:
int C;
C = getchar();

30
LES STRUCTURES CHAPITRE
CONDITIONNELLES 4

1. Les structures alternatives


Les structures de contrôle définissent la suite dans laquelle les instructions sont effectuées.
Constatons déjà que la particularité la plus importante des instructions de contrôle en C est
le fait que les 'conditions' en C peuvent être des expressions quelconques qui fournissent
un résultat numérique.

La valeur zéro correspond à la valeur logique faux et toute valeur différente de zéro est
considérée comme vrai.

a. if – else
SYNTAXE :

if ( <expression> )
<bloc d'instructions 1>
else
<bloc d'instructions 2> ;

Si l'<expression> fournit une valeur différente de zéro, alors le <bloc d'instructions 1> est
exécuté

Si l'<expression> fournit la valeur zéro, alors le <bloc d'instructions 2> est exécuté
Exemple 1
if (a > b)
max = a;
else
max = b;

Exemple 2
if (A-B)
printf("A est différent de B\n");
else
printf("A est égal à B\n");

Application 1 :
Aficher du texte à l'écran en fonction de l'âge de l'utilisateur, par exemple, dites à l'utilisateur
qu'il est majeur si (if) il a plus de 18 ans et qu'il est mineur sinon (else).

Application 2 :
A partit de la saisie, des tailles respectives de deux enfants Jules et Jean, dite celui qui est
le plus grand.

31
Remarque
La partie else est facultative lorsqu’on n’a que 2 choix. On peut donc utiliser if de la façon
suivante:
if ( <expression> )
<bloc d'instructions> ;

b. if – else if – else if - …..


En combinant plusieurs structures if - else en une expression nous obtenons une structure
qui est très courante pour prendre des décisions entre plusieurs alternatives :
if ( <expr1> )
<bloc1>
else if (<expr2>)
<bloc2>
else if (<expr3>)
<bloc3>
else if (<exprN>)
<blocN>
else
<blocN+1>;
Exemple
#include <stdio.h> main() {
int A,B;
printf("Entrez deux nombres entiers :");
scanf("%i %i", &A, &B);
if (A > B)
printf("%i est plus grand que %i\n", A, B);
else if (A < B)
printf("%i est plus petit que %i\n", A, B);
else
printf("%i est égal à %i\n", A, B); return 0; }

Application 1 :
En fonction de la couleur du feu tricolore (Rouge, Orange, Vert), dites au Robot conducteur
l’action à exécuter (S’arrêter, Ralentir, Avancer).

Application 2 :
Ecrire un programme qui demande à l'utilisateur de faire le choix de son pays et lui affiche
sa nationalité. On s’inspirera du menu en console ci-dessous.

||| VOTRE PAYS |||

1. France
2. Canada
3. Belgique
4. Suisse

Choix : 1

Tu es francais.

32
2. Les structures de choix « switch »
Lorsque les choix à faire sont nombreux, switch est plus adapté.

Syntaxe :

switch (expression)
{
case valeur1 : instruction 1;
break;
case valeur2 : instruction 2;
break;
.
.
.
Case valeurn : instruction n;
}
Où expression et valeurx représentent des valeurs entières. Si expression est égal à valeur1
alors l’instruction1 est exécuté. Si expression est égal à valeur2 alors l’instruction2 est
exécuté, etc.

Le cas default correspond au cas où expression n’est égal à aucune des valeur valeur1,
valeur2,…, valeurn.

Un switch permet de tester des égalités et seulement des égalités ! C'est donc un mot clé
moins puissant qu'un if.

Il permet généralement de gérer un menu pour éviter d'avoir plein de else if de partout
comme précédemment.

Voici le même code que tout à l'heure en utilisant le switch, donc sans les else if :
switch(pays)
{
case 1 :
printf("\nTu es francais.");
break;
case 2 :
printf("\nTu es canadien.");
break;
case 3 :
printf("\nTu es belge.");
break;
case 4 :
printf("\nTu es suisse.");
break;
default :
printf("\nTu es un extraterrestre.");
break;
}

33
CHAPITRE
LES BOUCLES
5
1. while
La structure while correspond tout à fait à la structure tant que du langage algorithmique
while ( <expression> )
<bloc d'instructions> ;

 Tant que l'<expression> fournit une valeur différente de zéro, le <bloc d'instructions>
est exécuté.
 Si l'<expression> fournit la valeur zéro, l’exécution continue avec l'instruction qui
suit le bloc d'instructions.
 Le <bloc d'instructions> est exécuté zéro ou plusieurs fois.

Exemple /* Afficher les nombres de 0 à 9 */


int I = 0;
while (I<10)
{
printf("%i \n", I);
I++;
}

Application :
Ecrire un programme qui demande l’âge de l’utilisateur et lui affiche « Vous été mineur
chaque fois que l’âge saisi est <18.

2. do - while
La structure do - while est semblable à la structure while, avec la différence suivante :
 while évalue la condition avant d'exécuter le bloc d'instructions,
 do - while évalue la condition après avoir exécuté le bloc d'instructions. Ainsi le bloc
d'instructions est exécuté au moins une fois.

do
<bloc d'instructions>
while ( <expression> );

Le <bloc d'instructions> est exécuté au moins une fois et aussi longtemps que
l'<expression> fournit une valeur différente de zéro.

Exemple
float N;
do
{
printf("Introduisez un nombre entre 1 et 10 :");
scanf("%f", &N);
}
while (N<1 || N>10);

34
3. for
La structure for en Pascal et la structure pour en langage algorithmique sont utilisées pour
faciliter la programmation de boucles de comptage. La structure for en C est plus générale
et beaucoup plus puissante.
for ( <expr1> ; <expr2> ; <expr3> )
<bloc d'instructions> est équivalent à :
<expr1>; while ( <expr2> )
{
<bloc d'instructions>
<expr3>;
}
<expr1> est évaluée une fois avant le passage de la boucle. Elle est utilisée pour initialiser
les données de la boucle.
<expr2> est évaluée avant chaque passage de la boucle. Elle est utilisée pour décider si
la boucle est répétée ou non.
<expr3> est évaluée à la fin de chaque passage de la boucle. Elle est utilisée pour
réinitialiser les données de la boucle.

Le plus souvent, for est utilisé comme boucle de comptage :


for ( <init.> ; <cond. répétition> ; <compteur> )
<bloc d'instructions> ;
Exemple
int I;
for (I=0 ; I<=20 ; I++)
printf("Le carré de %d est %d \n", I, I*I);

Il y a 3 instructions condensées entre les parenthèses du for, à part ça, la boucle for s'utilise
comme la boucle while, il faut juste que je vous explique ces 3 instructions :
 i = 0; permet d'initialiser la variable compteur, i, pour ensuite commencer la boucle.
L'initialisation s'effectue une seule fois et non pas à chaque tour de boucle.
 i < 20; est la condition, rien à dire, c'est comme pour while.
 i++ est l'incrémentation qui est effectuée à la fin de chaque tour de boucle et non pas au
début.

Dans notre cas, c'est une incrémentation mais ça peut être d'autres opérations comme la
décrémentation (--).

En pratique, les parties <expr1> et <expr2> contiennent souvent plusieurs initialisations ou


réinitialisations, séparées par des virgules

35
CHAPITRE
LES TABLEAUX
6
Les tableaux sont certainement les variables structurées les plus populaires. Ils sont
disponibles dans tous les langages de programmation et servent à résoudre une multitude
de problèmes.

1. Les tableaux à une dimension


Un tableau (uni-dimensionnel) A est une variable structurée formée d'un nombre entier N
de variables simples du même type, qui sont appelées les composantes du tableau. Le
nombre de composantes N est alors la dimension du tableau.

En faisant le rapprochement avec les mathématiques, on dit encore que "A est un vecteur
de dimension N"
Exemple
La déclaration
int JOURS[12]={31,28,31,30,31,30,31,31,30,31,30,31};
Définit un tableau du type int de dimension 12. Les 12 composantes sont initialisées par les
valeurs respectives 31, 28, 31, ... , 31.
On peut accéder à la première composante du tableau par JOURS[0], à la deuxième
composante par JOURS[1], . . . , à la dernière composante par JOURS[11].

a. Déclaration et mémorisation

Déclaration de tableaux en C
<TypeSimple> <NomTableau>[<Dimension>];

Exemples int A[25]; float B[100]; char D[30];

En C, le nom d'un tableau est le représentant de l'adresse du premier élément du tableau.


Les adresses des autres composantes sont calculées (automatiquement) relativement à
cette adresse.
Exemple: short A[5] = {1200, 2300, 3400,

4500, 5600};

36
Si un tableau est formé de N composantes et si une composante a besoin de M octets en
mémoire, alors le tableau occupera de N*M octets.
b. Initialisation
Lors de la déclaration d'un tableau, on peut initialiser les composantes du tableau, en
indiquant la liste des valeurs respectives entre accolades. Exemple int A[5] = {10, 20,
30, 40, 50};

Il faut évidemment veiller à ce que le nombre de valeurs dans la liste corresponde à la


dimension du tableau. Si la liste ne contient pas assez de valeurs pour toutes les
composantes, les composantes restantes sont initialisées par zéro.

Réservation automatique
Si la dimension n'est pas indiquée explicitement lors de l'initialisation, alors l'ordinateur

réserve automatiquement le nombre d'octets nécessaires. Exemple : int A[] = {10, 20,

30, 40, 50};

==> réservation de 5*sizeof(int) octets (dans notre cas: 10 octets)

c. Accès aux composantes


En déclarant un tableau par:
int A[5]; nous avons défini un tableau A avec cinq composantes, auxquelles
on peut accéder par: A[0], A[1], ... , A[4]
Exemple

Attention !
Considérons un tableau T de dimension N:
En C,
- l'accès au premier élément du tableau se fait par T[0]
- l'accès au dernier élément du tableau se fait par T[N-1]
La structure for se prête particulièrement bien au travail avec les tableaux. La plupart des
applications se laissent implémenter par simple modification des exemples-types de
l'affichage et de l'affectation.

Exercice :
Ecrire un programme qui lit la dimension N d'un tableau T du type int (dimension maximale
: 50 composantes), remplit le tableau par des valeurs entrées au clavier et affiche le tableau.
Calculer et afficher ensuite la somme des éléments du tableau.
#include <stdio.h> main()
{
/* Déclarations */ int T[50]; /*
tableau donné */ int N; /*
dimension */ int I; /* indice
courant */

37
long SOM; /* somme des éléments - type long à cause */
/* de la grandeur prévisible du résultat. */
/* Saisie des données */
printf("Dimension du tableau (max.50) : ");
scanf("%d", &N );
for (I=0; I<N; I++)
{
printf("Elément %d : ", I);
scanf("%d", &T[I]);
}
/* Affichage du tableau */
printf("Tableau donné :\n"); for
(I=0; I<N; I++) printf("%d ", T[I]);
printf("\n");
/* Calcul de la somme */ for
(SOM=0, I=0; I<N; I++) SOM
+= T[I];
/* Edition du résultat */
printf("Somme de éléments : %ld\n", SOM);
return 0;
}

2. Les tableaux à deux dimensions


En C, un tableau à deux dimensions A est à interpréter comme un tableau (uni-
dimensionnel) de dimension L dont chaque composante est un tableau (uni-dimensionnel)
de dimension C.

On appelle L le nombre de lignes du tableau et C le nombre de colonnes du tableau. L


et C sont alors les deux dimensions du tableau. Un tableau à deux dimensions contient
donc L*C composantes.

On dit qu'un tableau à deux dimensions est carré, si L est égal à C.


En faisant le rapprochement avec les mathématiques, on peut dire que "A est un vecteur
de L vecteurs de dimension C", ou mieux:
"A est une matrice de dimensions L et C".

38
Exemple
Considérons un tableau NOTES à une dimension pour mémoriser les notes de 20
élèves d'une classe dans un devoir: int NOTE[20] = {45, 34, ... , 50, 48};

Pour mémoriser les notes des élèves dans les 10 devoirs d'un trimestre, nous pouvons
rassembler plusieurs de ces tableaux uni-dimensionnels dans un tableau NOTES à deux
dimensions :
int NOTE[10][20] = {{45, 34, ... , 50, 48},
{39, 24, ... , 49, 45},
... ... ...
{40, 40, ... , 54, 44}};

Dans une ligne nous retrouvons les notes de tous les élèves dans un devoir. Dans une
colonne, nous retrouvons toutes les notes d'un élève.

a. Déclaration et mémorisation
Déclaration de tableaux à deux dimensions en C
<TypeSimple> <NomTabl>[<DimLigne>][<DimCol>];
Exemples int A[10][10]; float B[2][20]; char D[15][40];
Mémorisation
Comme pour les tableaux à une dimension, le nom d'un tableau est le représentant de
l'adresse du premier élément du tableau (c.-à-d. l'adresse de la première ligne du
tableau). Les composantes d'un tableau à deux dimensions sont stockées ligne par ligne
dans la mémoire.

Exemple: Mémorisation d'un tableau à deux dimensions


short A[3][2] = {{1, 2 },
{10, 20 },
{100, 200}};

Un tableau de dimensions L et C, formé de composantes dont chacune a besoin de M


octets, occupera L*C*M octets en mémoire.

39
b. Initialisation
Lors de la déclaration d'un tableau, on peut initialiser les composantes du tableau, en
indiquant la liste des valeurs respectives entre accolades. A l'intérieur de la liste, les
composantes de chaque ligne du tableau sont encore une fois comprises entre accolades.
Pour améliorer la lisibilité des programmes, on peut indiquer les composantes dans
plusieurs lignes.

Exemples
int A[3][10] ={{ 0,10,20,30,40,50,60,70,80,90},
{10,11,12,13,14,15,16,17,18,19},
{ 1,12,23,34,45,56,67,78,89,90}};

float B[3][2] = {{-1.05, -1.10 },


{86e-5, 87e-5 },
{-12.5E4, -12.3E4}};

Lors de l'initialisation, les valeurs sont affectées ligne par ligne en passant de gauche à
droite. Nous ne devons pas nécessairement indiquer toutes les valeurs : Les valeurs
manquantes seront initialisées par zéro. Il est cependant défendu d'indiquer trop de valeurs
pour un tableau.

Si le nombre de lignes L n'est pas indiqué explicitement lors de l'initialisation, l'ordinateur


réserve automatiquement le nombre d'octets nécessaires.

int A[][10] = {{ 0,10,20,30,40,50,60,70,80,90},


{10,11,12,13,14,15,16,17,18,19},
{ 1,12,23,34,45,56,67,78,89,90}};

c. Accès aux composantes

Accès à un tableau à deux dimensions en C


<NomTableau>[<Ligne>][<Colonne>]
Les éléments d'un tableau de dimensions L et C se présentent de la façon suivante:
/ \
| A[0][0] A[0][1] A[0][2] . . . A[0][C-1] |
| A[1][0] A[1][1] A[1][2] . . . A[1][C-1] |
| A[2][0] A[2][1] A[2][2] . . . A[2][C-1] |
| ... ... ... ... ... |
| A[L-1][0] A[L-1][1] A[L-1][2] . . . A[L-1][C-1] |
\ /
Attention !
Considérons un tableau A de dimensions L et C.
En C,
- les indices du tableau varient de 0 à L-1, respectivement de 0 à C-1.
- la composante de la Nième ligne et Mième colonne est notée:
A[N-1][M-1]

Lors du travail avec les tableaux à deux dimensions, nous utiliserons deux indices (p.ex: I
et J), et la structure for, souvent imbriquée, pour parcourir les lignes et les colonnes des
tableaux.

40
Exercice :
Ecrire un programme qui lit les dimensions L et C d'un tableau T à deux dimensions du type
int (dimensions maximales : 50 lignes et 50 colonnes). Remplir le tableau par des valeurs
entrées au clavier et afficher le tableau ainsi que la somme de tous ses éléments.

#include <stdio.h> main()


{
/* Déclarations */
int T[50][50]; /* tableau donné */ int L,
C; /* dimensions */ int I, J; /*
indices courants */
long SOM; /* somme des éléments - type long à cause */
/* de la grandeur prévisible du résultat. */

/* Saisie des données */


printf("Nombre de lignes (max.50) : ");
scanf("%d", &L );
printf("Nombre de colonnes (max.50) : ");
scanf("%d", &C ); for (I=0; I<L; I++)
for (J=0; J<C; J++)
{
printf("Elément[%d][%d] : ",I,J);
scanf("%d", &T[I][J]);
}
/* Affichage du tableau */ printf("Tableau
donné :\n");
for (I=0; I<L; I++)
{
for (J=0; J<C; J++) printf("%7d",
T[I][J]);
printf("\n");
}
/* Calcul de la somme */ for
(SOM=0, I=0; I<L; I++) for
(J=0; J<C; J++) SOM +=
T[I][J];
/* Edition du résultat */ printf("Somme des
éléments : %ld\n", SOM); return 0;
}

41

Vous aimerez peut-être aussi