Vous êtes sur la page 1sur 123

2ème Année «Années Préparatoires

LE LANGAGE C Intégrés»
2018/2019
Dep. Génie Industriel
Pf. CHERGUIAdil
DÉFINITIONS
Qu’est-ce qu’un Programme?
On peut considérer un programme comme la Un programme est stocké dans un fichier (un
traduction d’un algorithme dans un langage de ensemble de données stockées sur un support
programmation, i.e. un langage formel persistant). On distingue deux types de fichiers,
compréhensible par un ordinateur. On dit alors correspondant à deux versions différentes d’un
que ce programme est l’implémentation de cet programme : fichier source et fichier exécutable. Le
algorithme. premier contient ce que l’on appelle le code source,
il s’agit d’un fichier texte, alors que le second
• Programme : séquence d’instructions
contient le code binaire, aussi appelé code machine
destinées à être exécutées par un ordinateur.
ou code objet.
• Instruction : action que l’ordinateur connait
• Code source : programme exprimé dans un
et peut réaliser.
langage de programmation compréhensible par
Un langage de programmation (y compris le C) un être humain, et ne pouvant pas être exécuté
est caractérisé par son jeu d’instructions : directement par l’ordinateur.
• Jeu d’instructions : ensemble des • Code binaire : programme exprimé en langage
instructions autorisées dans un langage de machine, pouvant être directement exécuté par
programmation. l’ordinateur.

PROGRAMMATION 2
EN LANGAGE C
DÉFINITIONS
Qu’est-ce que la compilation?
Le code binaire est obtenu à partir du code La procédure de compilation varie en fonction du
source, en réalisant un traitement appelé langage de programmation. On s’intéresse ici au cas
compilation. Ce traitement est réalisé par un du langage C.
programme spécial appelé le compilateur.
Un programme C prend généralement la forme de
• Compilation : action de transformer un code plusieurs fichiers source distincts, que l’on veut
source en code binaire, de manière à obtenir compiler de manière à obtenir un seul fichier
un fichier exécutable à partir d’un fichier exécutable. La décomposition d’un programme en
source. plusieurs fichiers séparés permet de le rendre
modulaire, ce qui facilite la maintenance, le
Le code binaire est spécifique au processeur qui
débogage et l’évolution du programme.
va exécuter le programme. Par contre, le code
source en est généralement indépendant. Cela
signifie qu’un même code source sera compilé
différemment en fonction du processeur (et/ou
du système d’exploitation) que l’on veut utiliser
pour exécuter le programme.

PROGRAMMATION 3
EN LANGAGE C
DÉFINITIONS
Les étapes de la compilation
La première étape (en rouge) consiste à précompiler La troisième étape (en orange) est appelée l’assemblage,
les fichiers source, en appliquant les directives de pré- et consiste à transformer chaque fichier assembleur en un
compilation indiquées dans le code source au moyen fichier binaire. Là encore, on obtient autant de fichiers
du caractère #. Ces directives seront décrites plus binaires que de fichiers source originaux. Ces fichiers
tard, mais on peut déjà dire que le travail de pré- prennent généralement l’extension .o.
compilation consiste à transformer et compléter le
code source. On obtient ainsi une version complétée La quatrième et dernière étape (en vert) est l’édition des
de chaque fichier source traité. Les fichiers obtenus liens. Elle consiste à rassembler dans un seul fichier binaire
contiennent toujours du code source. tout le code binaire nécessaire à l’exécution du
programme. Ceci inclut à la fois la totalité ou une partie
La deuxième étape (en bleu) est la compilation des fichiers objets de l’étape précédente, mais aussi
proprement dite. Cependant, elle ne produit pas éventuellement de bibliothèques statiques préexistantes.
directement du code binaire, mais un code source On obtient finalement un seul fichier que l’on peut
intermédiaire, utilisant le langage assembleur. Ce exécuter.
langage est qualifié de bas-niveau, car son jeu
d’instructions correspond aux actions les plus simples
qu’un processeur peut effectuer. Par conséquent, un
programme assembleur se traduit très facilement en
un programme binaire. À ce stade de la procédure, on
obtient autant de fichiers assembleur qu’on avait
initialement de fichiers source.
PROGRAMMATION 4
EN LANGAGE C
DÉFINITIONS
Le schéma de compilation

Remarque : par abus de langage, on appelle compilation l’ensemble de la procédure permettant


d’obtenir un fichier binaire à partir d’un ou plusieurs fichiers sources, alors qu’en réalité, la
compilation proprement dite n’est qu’une étape de cette procédure (ici, la deuxième étape).
PROGRAMMATION 5
EN LANGAGE C
DÉFINITIONS
Erreurs de compilation et
d’exécution
On distingue deux types de problèmes pouvant Dans ce cas-là, il n’est pas possible de créer le fichier
survenir lors de l’écriture d’un programme, en exécutable correspondant à votre programme. Il est donc
fonction du moment où elles sont détectées : inutile de tenter d’exécuter votre programme si la
compilation ou exécution. compilation a échoué. Ces erreurs-là sont indiquées en
rouge par l’IDE. À noter que des options du compilateur
Erreur de compilation : problème détecté lors du permettent de considérer certains problèmes soit comme IDE ou EDI
processus de compilation. des avertissements, soit comme de vraies erreurs. Environnement de
Cette erreur peut être détectée lors de l’étape de Développement Intégré,
Des messages d’information sont indiqués pour chaque ou IDE (Integrated
compilation proprement dite, mais elle peut aussi avertissement et erreur de compilation, afin d’aider le
apparaitre lors de la pré-compilation (auquel cas il y a Development
programmeur à résoudre le problème identifié. Cependant, Environment) doté
probablement un problème avec les directives, par il faut savoir que ces messages ne sont pas toujours très
exemple un ; placé incorrectement à la fin d’une ligne d'une interface utilisateur
explicites, et peuvent parfois aussi être trompeurs (cela graphique. C'est un outil
de directive) ou d’une autre étape du processus. dépend du compilateur). pour faciliter la tâche du
Le compilateur peut indiquer un simple Il est nécessaire d’avoir une certaine expérience du programmeur dans la
avertissement, auquel cas le problème détecté n’est compilateur utilisé pour être capable de les interpréter réalisation d'applications
que potentiel, et n’empêche pas la création d’un correctement. De plus, une erreur de compilation peut en ou l'écriture de scripts.
fichier binaire qui pourra ensuite être exécuté. provoquer d’autres. Pour cette raison, il faut absolument
Dans ce cours nous allons
utiliser Code Blocks
Le compilateur peut indiquer une erreur proprement commencer par corriger la toute première erreur détectée
dite, qui empêche de finaliser la compilation. par le compilateur, puisqu’elle est susceptible de causer les
erreurs ultérieures.
PROGRAMMATION 6
EN LANGAGE C
The American National
UN PEU D’HISTOIRE Standards
Institute (ANSI) is a
private non-profit
Le langage C organization that
Le langage C est un langage de programmation • La version originale s’est stabilisée en 1978 et est oversees the
développé à partir de 1972 dans les laboratoires appelée Kernighan & Ritchie ou C K&R ; development
Bell, dans le but d’écrire le système d’exploitation of voluntary consensus
• L’ANSI a défini sa propre version en 1989, basée standards for products,
Unix. Sa paternité est attribuée à Dennis Ritchie
sur le C K&R et appelée C89 ou C ANSI ; services, processes,
et Ken Thompson, tandis que Brian Kernighan
est intervenu plus tard dans son évolution. • L’ISO a défini sa version basée sur le C ANSI en systems, and personnel
1999, qui est appelée C99. in the United States
L’un des objectifs était de définir un langage
portable. Dans ce cours, nous nous concentrerons sur la
version ANSI C89, qui est d’après nous la plus ISO, the International
• Portabilité : un langage de programmation est répandue. Organization for
dit portable s’il peut être compilé sur des Standardization, is an
machines et de systèmes différents, sans avoir independent, non-
besoin d’être modifié. governmental
Cependant, on ne peut pas vraiment considérer organization, the
que cet objectif a été atteint, car différentes members of which are
versions du C sont apparues, qui ne sont pas the standards
complètement compatibles entre elles. Les organizations of the
principales sont les suivantes : 163 country

PROGRAMMATION 7
EN LANGAGE C
UN PEU D’HISTOIRE
Le langage C Classement en 2017
On qualifie parfois le C de langage bas niveau
car il est relativement proche de l’assembleur.
Toutefois, il est de plus haut niveau que ce
dernier. Il s’agit du langage le plus utilisé au
monde, ou du moins figure-t-il parmi les trois
premiers, en fonction des classements
considérés.
Sa syntaxe a fortement influencé d’autres
langages de plus haut niveau apparus plus tard,
tels que C++, Java, C#, JavaScript ou PHP. Un
grand nombre de systèmes d’exploitation et de
jeux vidéo sont encore (complètement ou
partiellement) écrits en C aujourd’hui.

PROGRAMMATION 8
EN LANGAGE C
LE IDE CODE BLOCKS
Code Blocks
Pour pouvoir créer une programme en C, vous
avez besoin d’un logiciel qui vous permettra de :
• un éditeur de texte pour écrire le code
source du programme. En théorie un logiciel
comme le Bloc-notes sous Windows. L'idéal,
c'est d'avoir un éditeur de texte intelligent
qui colore tout seul le code, ce qui vous
permet de vous y repérer bien plus
facilement.
Ces tâches sont groupées dans un seul logiciel. Il
• un compilateur pour transformer (« compiler
existe plusieurs environnements de
») votre source en binaire (programme
exécutable). développement. Un des IDE préférable pour
débuter en programmation est Code::Blocks. Il
• un débogueur pour vous aider à retrouver est gratuit et fonctionne sur la plupart des
facilement les erreurs dans votre systèmes d'exploitation
programme, afin que de les corrigées.
Il est librement téléchargeable à partir de
l’adresse suivante :
http://www.codeblocks.org/downloads/26
PROGRAMMATION 9
EN LANGAGE C
LE IDE CODE BLOCKS
Téléchargement de Code Blocks
Taper l’adresse : http://www.codeblocks.org/downloads/26
Suivez les liens de téléchargement pour télécharger le fichier
codeblocks-17.12mingw-setup.exe
Exécutez ce fichier et suivez les étapes d’installation normale.
… et ensuite suivez les étapes de création d’un projet en C.

PROGRAMMATION 10
EN LANGAGE C
LE IDE CODE BLOCKS
Création d’un nouveau projet
Une fois vous lancez code blocks le premier interface apparait
pour vous inviter à créer un nouveau projet.

PROGRAMMATION 11
EN LANGAGE C
LE IDE CODE BLOCKS
Les éléments de l’interface
On distingue 4 grandes sections dans la fenêtre de code
blocks, ils sont numérotées sur l'image : 1- la barre d'outils : elle comprend de nombreux boutons,
mais seuls quelques-uns nous seront régulièrement utiles.

2- la liste des fichiers du projet :


c'est à gauche que s'affiche la liste
de tous les fichiers source de votre
programme. Notez que sur cette
capture aucun projet n'a été créé, on
ne voit donc pas encore de fichiers à
l'intérieur de la liste. Les fichiers de
votre projet s’afficheront ici lorsque
vous créez votre projet.

3- la zone principale : c'est là que


vous pourrez écrire votre code en
langage C.

4- la zone de notification : c'est ici que vous verrez les erreurs de compilation
s'afficher si votre code comporte des erreurs. Le rapport des erreurs comporte
la raison et la nature des erreurs, ainsi que le numéro de la ligne ou elle se
trouve PROGRAMMATION 12
EN LANGAGE C
LES ÉLÉMENTS D’UN PROGRAMME EN C
Programme Hello world!
Lors de la création d’un projet en langage C avec
l’IDE Code blocks, un fichier source (main.c) est
créé automatiquement contenant une source
comme exemple du programme le plus simple
illustrant le commencement de l’apprentissage
de n’importe qu’elle langage de programmation :
le programme Hello world. Ce programme
consiste simplement à afficher un message Hello
world!! à l’écran. Nous examinons ici le syntaxe
d’un programme en C. les instructions du langage C sont obligatoirement
encapsulées dans des fonctions et il existe une
Remarquez que l’éditeur du code propose une
fonction privilégiée appelée main qui est le point
certaines colorations significatifs des parties de
de départ de tout programme (appelée aussi
code en fonction de leurs fonctionnalités. Par
programme principal)
exemple : les directives d’inclusion de
bibliothèques spéciales de fonctions sont en vert,
les mots clés sont en gras et en bleu foncé, les
messages à afficher en bleu clair, les délimiteurs
en rouge…

PROGRAMMATION 13
EN LANGAGE C
LES ÉLÉMENTS D’UN PROGRAMME EN C
Programme Hello world!
Lors de la création d’un projet en langage C avec

int main() Toutes instructions doit


{ obligatoirement être inclues
dans un programme principal

« int main() ». Il permet de
… définir le début (l’accolade
return 0: ouvrante « { ») et la fin de votre
} programme (l’accolade
fermante « } »). Une ou
plusieurs instructions sont alors
écrites à la place des « … »

# include <stdio.h> printf(’’Bonjour!’’); est un


La directive #include inclue le int main() exemple d’instruction qui permet
fichier stdio.h au programme d’afficher à l’écran une message
{
avant la compilation. On parle « Hello world! » , c’est une
printf(’’ Hello world!’’); fonction prédéfinies qui
alors de préprocesseur
return 0: appartient à une bibliothèques
} de fonctions d’entrées et de
sorties dont il faut l’inclure dans
votre programme afin qu’elle
soit reconnus, c’est le rôle de la
directives # include <stdio.h>

PROGRAMMATION 14
EN LANGAGE C
LES ÉLÉMENTS D’UN PROGRAMME EN C
Programme Hello world!
Pour examiner le résultat que donne ce
programme, il faut compiler se projet à travers le
bouton build . La compilation une
fois réussie (sans erreurs de compilation) génère
une fichier exécutable que nous pouvons
exécuter à partir du compilateur en appuyant sur
le bouton run . Nous pouvons aussi
faire ces deux tâche simultanément en appuyant
sur le bouton build & run , dans les
deux cas une fenêtre d’exécution (que nous Cette console représente la manière dont
appelons console) s’affiche à l’écran. communique le programme avec son utilisateur.
C’est la raison pour laquelle le type du projet
Dans la console apparait le message Hello world!
que nous avons créé est du type console
qui représente le résultat de ce programme.
application.
Le message qui suit :
Process returned 0 (0x0) execution time : 0.031 s
Press any key to continue.

est un message générer par le compilateur qui


donne l’état d’exécution du programme : la
valeur retournée et le temps qu’a pris son
exécution. PROGRAMMATION 15
EN LANGAGE C
LES ÉLÉMENTS D’UN PROGRAMME EN C
Algorithme ► Programme en C
Prenons l’exemple de l’algorithme qui permet
d’échanger les valeurs de deux variables entiers
que nous allons traduire en langage C.
Par la suite nous allons expliqué chaque élément
de cette traduction.
ALGORITHME : echange
A,B,C : ENTIER
DEBUT
/*ce programme échange
les valeurs de deux variables*/
AFFICHER("donner A et B")
LIRE(A,B)
/*avant échange*/
AFFICHER("A =",A," et B=",B)
C ← A
A ← B
B ←
C
/*avant échange*/
AFFICHER("A =",A," et B=",B)
FIN
PROGRAMMATION 16
EN LANGAGE C
LES ÉLÉMENTS D’UN PROGRAMME EN C
Algorithme ► Programme en C
Prenons l’exemple de l’algorithme qui permet
d’échanger les valeurs de deux variables entiers
que nous allons traduire en langage C.
Par la suite nous allons expliqué chaque élément
de cette traduction.
ALGORITHME : echange
A,B,C : ENTIER
DEBUT
/*ce programme échange
les valeurs de deux variables*/
AFFICHER("donner A et B")
LIRE(A,B)
/*avant échange*/
AFFICHER("A =",A," et B=",B)
C ← A
A ← B
B ←
C
/*avant échange*/
AFFICHER("A =",A," et B=",B)
FIN
PROGRAMMATION 17
EN LANGAGE C
LES VARIABLES EN C
Les types de variables
Les types de base du langage C se répartissent en
3 grande catégories en fonction de la nature des
informations qu’ils permettent de représenter:
• Nombres entiers (int)
peuvent être signés ou non signés : signed
ou unsigned (unsigned int x;)
• Nombres réels à virgules flottantes (float ou
double)
• Caractère (char): apparaît en C comme un
cas particulier de int.

PROGRAMMATION 18
EN LANGAGE C
LES VARIABLES EN C
Le type entier
• short int ou short (entier sur 16 bits : -
32 768 à 32 767)
Exemple: unsigned short x;
• int (entier sur 32 bits : - 2 147 483 648 à 2 x peut aller de 0 à 65 535
147 483 647) pas de bit réservé pour le signe
• long int ou long (entier sur 32 bits ou - C accepte les constantes entière en
64 bits, selon les machines) notation décimale, hexadécimale ou
octale.
Chacun des 3 peut être nuancé par l’utilisation
du qualificatif unsigned pour ne représenter
que des nombres positifs. Par conséquence, le
nombre maximal qui peut être stocké augmente
tout en utilisant la même capacité :

PROGRAMMATION 19
EN LANGAGE C
LES VARIABLES EN C
Le type réel (float)
float: codé sur 4 octets avec 1 bit de signe, 23
bits de mantisse et 8 bits d'exposant. Exemple
C accepte les constantes flottante en
double : codé sur 8 octets avec 1 bit de signe, notation décimale ou scientifique
52 bits de mantisse et 11 bits d'exposant. 3.5e+3 3500 2.43 -0.38 -.38
4. .27
long double : codé sur 10 octets avec 1 bit de
signe, 64 bits de mantisse et 15 bits
d'exposant.
3.4*10-38 à
float Flottant (réel) 4
3.4*1038
1.7*10-308 à
double Flottant double 8
1.7*10308
long Flottant double 3.4*10-4932 à
10
double long 3.4*104932
PROGRAMMATION 20
EN LANGAGE C
LES VARIABLES EN C
Le type char
En C, un caractère est un entier signé codé sur 1 NOTATION RESULTAT
octet.
\a cloche ou bip (alert ou audible bell)
Notation des constantes caractères : ‘a’ , ‘$’ ..
\b Retour arrière (Backspace)
\f Saut de page (Form Feed)
Important: ‘a’ ≠ ‘’a’’ \n Saut de Ligne (Line Feed)
\r Retour chariot (Carriage Return)
\t Tabulation horizontaLe (HorizontaL Tab)
Il existe des caractères non imprimables, tel que
le changement de ligne, de tabulation, … en voici \v Tabutation verticale (VerticaL Tab)
un tableau récapitulatif \\ \
\' ‘
\ '' ‘’
\? ?

PROGRAMMATION 21
EN LANGAGE C
LES VARIABLES EN C
La table code ASCII

PROGRAMMATION 22
EN LANGAGE C
LES VARIABLES EN C
A propos du type Booléen
Nous avons vu en algorithmique le type de
variable particulier dans lequel il est possible de
stocker seulement des valeurs logiques (vrai,
faux). Le type booléen n’existe pas en C alors
qu’il existe dans d’autres langages de
programmation.
Le type booléen est représenté par un entier. Il se
comporte comme la valeur booléenne : vraie si
cette valeur entière est non nulle.
Dans un contexte qui exige une valeur booléenne
(comme les tests, par exemple), un entier non
nul équivaut à vrai et la valeur zéro équivaut à
faux.

PROGRAMMATION 23
EN LANGAGE C
LES VARIABLES EN C
La déclaration de variables
Char
Unsigned Short Exemples :
Signed int x, y=0, z;
Int
identificateur
float a,b;
long = expression
unsigned short n=1000;
Float
Double
Long double

Les mots suivants sont réservés. Leur fonction est prévue par la syntaxe de C et ils ne peuvent pas être utilisés dans un autre
but :
auto break case char const continue default do

double else enum extern float for goto if

int long register return short signed sizeof static

struct switch typedef union unsigned void volatile while PROGRAMMATION 24


EN LANGAGE C
LES OPERATEURS EN C
Opérateurs arithmétiques en C
C dispose d'un important éventail d'opérateurs Les opérateurs binaires ne sont à priori définis que
originaux d'affectation et d'incrémentation. pour deux opérandes ayant le même type parmi: int,
• Comme tous les langages, C dispose long int, float, double, long double et ils fournissent
d'opérateurs classiques "binaires" , à savoir un résultat de même type que leurs opérandes.
l'addition (+), la soustraction (-), la
multiplication (*), la division (/), et le Modulo
(%) ainsi que d'un opérateur "unaire"
correspondant à l'opposé noté - (comme dans
-n ou -x+y).
• Remarque: le quotient de deux entiers fournit
un entier. Ainsi 5/2 vaut 2; en revanche, le
quotient de deux flottants (noté, lui aussi, /)
est bien un flottant (5.0/2.0 vaut bien
approximativement 2.5).

PROGRAMMATION 25
EN LANGAGE C
LES OPERATEURS EN C
Opérateurs arithmétiques en C
Conversions implicites :
On peut écrire des expressions mixtes dans lesquelles interviennent des opérandes de types différents:
Int n,p; float x;
n*x + p (int * float) + int On parle de
Conversion implicite: int  float ( float*float) + int conversion d’ajustement de type:
intlongfloatdoublelong double
float + int
Même mécanisme : float + float  float
Les opérateurs numériques ne sont pas définis pour le types char et short :
C prévoit que toute valeur char ou short soit d’abord convertie en int.
char n,p; float x; n*x + p
(char* float) + short
Conversion systématique: ( int * float) + int
Conversion implicite : float * float + int
PROGRAMMATION
float + float  float EN LANGAGE C
26
LES OPERATEURS EN C
Les opérations relationnelles

Notation Notation en Sens


en pseudocode Langage C
a<b a<b a inférieur strictement à b
a>b a>b a supérieur strictement à b
a<=b a<=b a inférieur ou égale à b
a>=b a>=b a supérieur ou égale t à b
a=b a==b a égale à b
a!=b a!=b a différent de b
• L’opérateur = est un opérateur d’affectation en langage C.

PROGRAMMATION 27
EN LANGAGE C
LES OPERATEURS EN C
Opérateur d’affectation Opérateurs d’affectation élargie:
Opérateur d’affectation ordinaire Il existe aussi une équivalence en écritures de
• i = 5 est une expression qui réalisait une certaines opérations particulières d’affectations :
action : l'affectation de la valeur 5 à i. Cet
opérateur d'affectation (=) peut faire i=i+k  i+=k
intervenir d'autres expressions comme
a=a*b  a*=b
dans : c=b + 3
• Cet opérateur possède une associativité i=i-k  i-=k
de droite à gauche : i = j = 5
a=a/b  a/=b

PROGRAMMATION 28
EN LANGAGE C
LES OPERATEURS EN C
Opérateurs d’incrémentation et de décrémentation ( ++ - - )

• ++ i : expression qui incrémente de 1 la valeur


de i, et sa valeur est celle de i après Priorité:
incrémentation 3 * i++ * j-- + k++ équivaut à 3 * (i++) * (j--) + (k++)
• si la valeur de i est 5, l'expression : n = ++i - 5
affectera à i la valeur 6 et à n la valeur 1.
La priorité élevée de ces opérateurs unaires permet d’écrire
• n = i++ - 5 (n==0 , i++ vaut 5, i vaut 6)
des expression assez compliquées sans qu’il soit nécessaire d’employer
des ( )
• On dit que ++ est:
-un opérateur de pré incrémentation
lorsqu'il est placé à gauche
-un opérateur de post incrémentation
lorsqu'il est placé à droite

PROGRAMMATION 29
EN LANGAGE C
LES OPERATEURS EN C
Opérateur de CAST Opérateur conditionnel
L’operateur CAST permet d’obliger une
(seul opérateur ternaire en C)
conversion vers un type particulier.
syntaxe : condition ? Valeur si vrai : valeur si faux
Exemple: z = (x==y) ? a : b ; on utilise la valeur de l’expression

n=10, p=3; a>b ? i++ : i-- ; la valeur de l’expression n’est pas utilisée

(double) (n/p) aura comme valeur 3

(double) n/p aura comme valeur 3.33333…

PROGRAMMATION 30
EN LANGAGE C
LES OPERATEURS EN C
Opérateurs bit à bit Exemple :
Le langage C définit six opérateurs permettant de
#include <stdio.h>
manipuler les bits d’une variable:
int main(void)
• l’opérateur « et »: &. {
int a = 99; /* 99 == 0110 0011 */
• l’opérateur « ou inclusif »: |.
int b = 42; /* 42 == 0010 1010 */
• l’opérateur « ou exclusif »: ^. int c = 37; /* 37 == 0010 0101 */
/* 0110 0011 & 0010 1010 == 0010 0010 == 34 */
• l’opérateur de négation ou de complément: ~. printf("%d\n", a & b);
/* 0110 0011 | 0010 1010 == 0110 1011 == 107 */
• l’opérateur de décalage à droite: >>.
printf("%d\n", a | b);
• l’opérateur de décalage à gauche: <<. /* 0110 0011 ^ 0010 1010 == 0100 1001 == 73 */

Notez que tous ces opérateurs travaillent printf("%d\n", a ^ b);

uniquement sur des entiers. printf("%d\n",~c);/*~c == 1101 1010 */


printf("%d\n",c<<2);/*c<<2 == 1001 0100 == 158 */
printf("%d\n",c>>2);/*c>>2 == 0000 1001 == 9*/
return 0;
}
PROGRAMMATION 31
EN LANGAGE C
LES PRIORITÉS DES OPERATEURS EN C
Priorité Opérateurs Description Associativité
15 () [ ] -> . opérateurs d'adressage ->
++ -- incrément/décrément
~ complément à un (bit à bit)
! Le NON logique unaire
14 <-
&* adresse et valeur (pointeurs)
(type) conversion de type (cast)
+- plus/moins unaire (signe)
13 */% opérations arithmétiques ->
12 +- opérations arithmétiques ->
11 << >> décalage bit à bit ->
10 < <= > >= opérateurs relationnels ->
9 == != opérateurs relationnels ->
8 & ET bit à bit ->
7 ^ OU exclusif bit à bit ->
6 | OU bit à bit ->
5 && le ET logique ->
4 || le OU logique ->
3 ?: conditionnel <-
= += -= *= /= %=
2 assignations <-
>>= <<= &= ^= |=
1 , séparateur -> PROGRAMMATION
EN LANGAGE C
Informations complémentaires : Les priorités des
opérateurs
Certains symboles d’opérateurs sont utilisés avec La notion d’associativité dans le tableau de priorité, le sens
plusieurs significations, et donc, avec des priorités de l’évaluation d’une expression contenant des opérateurs
différentes. qui ont la même priorité :
Tel que le symbole &, se symbole signifie l’adresse • -> du gauche vers la droite
d’une variable lorsqu’il employé comme • <- de la droite vers la gauche
opération unaire(par exemple &Var) (à voir dans Dans certains cas, l’évaluation d’une expression dans une
les chapitres ultérieurs) . direction ou son inverse, donne le même résultat. Mais
Lorsque il est employé comme opération binaire dans d’autres cas non, comme exemple la division (/) :
(par exemple a&b), il signifie dans ce cas le ET en d=a/b/c; les deux sens d’évaluation donnent des résultats
opérations bit à bit. différents. Pour cela il faut tenir compte de l’associativité.
Donc, il faut bien prendre en compte le contexte Nous pouvons présenter un concept qui peut aider à s’en
d’utilisation du symbole comme opérateur : souvenir :
unaire ou binaire, pour différencier son L’opérateur ternaire (?: :), les opérateurs unaires (la classe
fonctionnement. (La même chose pour les 14) et les opérateurs d’assignations (classe 2), sont tous
symboles + et -) de la droite vers la gauche. Les autres sont du gauche vers
la droite.
LES OPERATEURS EN C
Exercices

PROGRAMMATION 34
EN LANGAGE C
ÉCRITURE FORMATÉE DE DONNÉES
Les possibilités de la fonction printf
La fonction printf est utilisée pour transférer Exemple:
du texte, des valeurs de variables ou des
résultats d'expressions vers le fichier de printf("leur somme est : %d",n1+n2);
sortie standard stdout (par défaut l'écran).
La fonction printf a comme 1er argument une
chaîne de caractères qui spécifie:

• Des caractères à afficher tels quels;

• Des code de format repérés par %. Un


code de conversion (c, d, f..) précise le
type de l’information à afficher.

Un code de format peut contenir des


informations complémentaires agissant sur le
cadrage, le gabarit ou la précision.
PROGRAMMATION 35
EN LANGAGE C
ÉCRITURE FORMATÉE DE DONNÉES
Les principaux codes de conversion

• c : char: caractère affiché ''en clair" • f : double ou float écrit en notation "décimale" avec six
(convient aussi à short ou à int compte chiffres après le point
tenu des conversions systématiques)
• e : double ou float écrit en notation ‘'exponentielle''
• d : int (convient aussi à char, compte tenu (mantisse entre 1 et 9) avec six chiffres après le point
des conversions systématiques) décimal, sous la forme x.xxxxxxe+yyy ou x.xxxxxxe-yyy
• u : unsigned int (convient aussi à unsigned pour les nombres positifs et -x.xxxxxxe+yyy ou -
char ou à unsigned short, compte tenu x.xxxxxxe-yyy pour les nombres négatifs
des conversions systématiques) • s : chaîne de caractères dont on fournit l'adresse (notion
• ld : long qui sera étudiée ultérieurement)
• lu : unsigned long

PROGRAMMATION 36
EN LANGAGE C
ÉCRITURE FORMATÉE DE DONNÉES
Action sur le gabarit d’affichage
Les entiers sont affichés par défaut sans printf("%f" , x );
espaces avant ou après. Les flottants avec six x = 1.2345 1.234500
chiffres après le point. x = 12.3456789 12.345678
Pour agir sur l’affichage  un nombre est printf("%10f" , x );
placé après % et précise le nombre de
caractère minimum à utiliser. x = 1.2345 ^^1.234500

Exemples x = 1.2345E5 123450.000000


printf("%e" , x );
printf("%3d" , n );
x = 1.2345 1.234500e+000
n = 20 ^20
x = 123.45 1.234500e+002
n=3 ^^3
n = 2358 2358
n = -5200 -5200
PROGRAMMATION 37
EN LANGAGE C
ÉCRITURE FORMATÉE DE DONNÉES
Actions sur la précision
pour les flottants, on peut préciser un nombre - Le caractère * figurants à la place d’un gabarit ou une
de chiffres après le point décimal précision signifie que la valeur effective est fournie dans la
liste des arguments de printf:
Exemples:
printf("%8.*f" , n, x );
printf("%10.3f" , x );
n=1; x=1.2345  ^^^^^1.2
x = 1.2345 ^^^^^1.235
- La fonction printf fournit une valeur de retour (nombre de
x = 1.2345E3 ^^1234.500
caractère affichés)
x = 1.2345E7 12345000.000

Remarques:
Cadrage de l’affichage à gauche 
printf("%-10.3f" , x );
x = 1.2345  1.235^^^^^

PROGRAMMATION 38
EN LANGAGE C
ÉCRITURE FORMATÉE DE DONNÉES
Les erreurs d’affichage
Erreur 1 : Code de format en désaccord avec le Conséquence 2 : s’il y a trop de code de format, printf
type de l’expression à afficher: cherchera à afficher n’importe quoi :
Conséquence : mauvaise interprétation si printf("%d %d" , n );
même taille (int en %u), sinon, conséquences n=8  8 2
plus désastreuses.
Erreur 2: Nombre de code de format différents
du nombre d’expressions de la liste
Conséquence 1 : si des expressions de la liste
n’ont pas de format, elles ne seront pas
affichées :
printf("%d" , n, p );
// valeur de p ne sera pas
affiché

PROGRAMMATION 39
EN LANGAGE C
LECTURE FORMATÉE DE DONNÉES
Les principaux codes de conversion Premières notion de tampon et de
séparateurs
• c : char Lorsque scanf attend des données, l’information
frappée au clavier est rangée temporairement dans
• d : int
l’emplacement mémoire nommé « tampon ». Ce
• u : unsigned int dernier est exploré caractère par caractère au fur et
à mesure des besoins. Certains caractères jouent un
• hd : short int
rôle particulier: les séparateurs (l’espace et la fin de
• hu : unsigned short ligne \n)
• ld : long
• lu : unsigned long
• f ou e : float écrit en notation "décimale"
ou ‘'exponentielle''
• Lf ou le : double écrit en notation
"décimale" ou ‘'exponentielle''
• s : chaîne de caractères dont on fournit
l'adresse (notion qui sera étudiée
ultérieurement) PROGRAMMATION 40
EN LANGAGE C
LECTURE FORMATÉE DE DONNÉES
Les premières règles utilisées Premières notion de tampon et de
par scanf séparateurs
• Les codes de format correspondant à un Exemples : (n et p sont de type int, c char, @
nombre entraînent l’avancement du désigne une fin de ligne)
pointeur jusqu’au 1er caractère différent scanf("%d%d" , &n, &p );
d’un séparateur, puis scanf prend en
compte tous les caractères suivants jusqu’à 12^25@ n = 12 p=25
la rencontre d’un séparateur. ^12^^25^^@ n = 12 p=25
• Quand au code de format %c, il entraîne la 123@
prise en compte du caractère désigné par le
pointeur (même un séparateur) et il est @
avancé sur le caractère suivant. ^25 n = 12 p=25
scanf("%d%c" , &n, &c );
12^a@ n = 12 c=‘ ‘

PROGRAMMATION 41
EN LANGAGE C
LECTURE FORMATÉE DE DONNÉES
On peut imposer un gabarit
Rôle d’un espace dans le format
maximal
Le traitement d’un code de format Un espace entre deux codes de format demande à
s’interrompe soit à la rencontre d’un scanf de faire avancer le pointeur au prochain
séparateur, soit lorsque le nombre de caractère caractère différent d’un séparateur !!
indiqué a été atteint !!
Exemples : (n et p sont de type int, @ désigne Exemples : (n et p sont de type int, c char, @
une fin de ligne) désigne une fin de ligne)

scanf("%3d%3d" , &n, &p ); scanf("%d %c" , &n, &c );


12^25@ n = 12 p=25 12^a@ n = 12 c=‘a‘
^^^^^12345@ n = 123 p=45 12^^^@
12@ a@ n = 12 c=‘a‘
25@ n = 12 p=25

PROGRAMMATION 42
EN LANGAGE C
LECTURE FORMATÉE DE DONNÉES
Arrêt prématuré de scanf
Compte = scanf("%d %d %c" , &n, &p, &c );
12^25^b@ n = 12 p = 25 c=‘b‘ compte = 3
12b@ n = 12 p inchangé c inchangé compte = 1
b@ n indéfini p inchangé c inchangé compte = 0
Un arrêt prématuré de scanf a lieu dans le cas où scanf n’est pas en mesure de fabriquer une valeur adéquate !!

Erreurs de programmation
1- Code de format en désaccord avec le type de l’expression:
Si même taille  introduction d’une mauvaise valeur
Si la variable a une taille inférieur  écrasement d’un emplacement mémoire consécutif à cette variable
2- Nombre de codes de format différent du nombre d’éléments de la liste:
Scanf("%d",&n, &p);  seule la valeur de n est lue
Scanf("%d%d",&n);  on affecte une valeur à un emplacement aléatoire de la mémoire
PROGRAMMATION 43
EN LANGAGE C
LES INSTRUCTIONS DE CONTRÔLE
Structures conditionnelles (if)

Il n’y a que deux formes possibles pour un test ;


 if ([condition])
{ Les instructions qui sont dans ce
[bloc d’instructions] bloc
ne seront exécutées que si la condition
}
et Vrai
 if ([condition])
{
[bloc d’instructions 1] Si la condition est vrai
} Le bloc 1 d’instructions est exécuté
else Si la condition est fausse
Le bloc 2 est exécuté
{
[bloc d’instructions 2]
}

PROGRAMMATION 44
EN LANGAGE C
LES INSTRUCTIONS DE CONTRÔLE
Structures conditionnelles (if)

Exemple

char Let;
printf("donner une lettre en Minuscule\n");
Les lettres minuscules ont une valeur
scanf("%c", &Let);
comprise entre 97 (a) et 122 (z).
if (Let <96)
Regarder la table des codes ASCII
{
Let=Let+32;
printf("vous avez tapez une lettre en Majuscule\n"); Ces instructions (entre
printf("Mais ne vous inquiete pas \n"); accolades) s’exécutent si la
printf("nous l’avons rendu Minuscule\n"); condition et vrai
}
printf("ce message s’affiche a l’exterieur de la structure de
test"); Le programme
continue son exécution

PROGRAMMATION 45
EN LANGAGE C
LES INSTRUCTIONS DE CONTRÔLE
Structures conditionnelles (if)

Exemple

int n,m; Si la condition n’agit que sur une seul
printf("donner un nombre entier\n"); instruction, il n’est pas nécessaire de
scanf("%d", &n); mettre les accolades
if (n % 2 == 0)
printf("le nombre %d est paire\n", n);
else
printf("le nombre %d est impaire\n",n);
m = n + 6;
printf("le nombre m =%d\n", m); Ces instructions n’appartiennent pas
… ni au bloc de if ni celui de else
Ici le programme continu ces
instructions

PROGRAMMATION 46
EN LANGAGE C
LES INSTRUCTIONS DE CONTRÔLE
L’instruction de choix multiple (switch) Exemple :
#include <stdio.h>
int main()
Syntaxe : {
switch(choix) int i,j,k;
printf("entrez deux nombres entiers \n");
{
scanf("%d %d",&i,&j);
case [valeur1] : printf("entrez 0 pour avoir un quotient entier\n");
[bloc d’instructions 1] printf("ou 1 pour avoir un quotient
break; fractionnaire\n");
case [valeur2] : scanf("%d",&k);
[bloc d’instructions 2] switch(k)
break; {
case 0 :
….
printf("%d\n",i/j);
case [valeur n] : break;
[bloc d’instructions n] case 1 :
break; printf("%f\n",(float)i/j);
default : break;
[bloc d’instructions a exécuté lorsque la default :
valeur de choix ne correspond a aucun cas ] printf("il faut entrer 0 ou 1\n");
printf("relancez l'execution\n");
break;
}
} return 0;
} PROGRAMMATION 47
EN LANGAGE C
LES INSTRUCTIONS DE CONTRÔLE
L’instruction de répétition (la boucle for) Syntaxe :

L'instruction for permet d'exécuter plusieurs fois la for ([initialisation du compteur]; [condition];
même série d'instructions (Bloc d’instructions): [modification du compteur])
{
c'est une boucle !
[Bloc d’instructions];
Dans sa syntaxe, il suffit de préciser le nom de la }
variable qui sert de compteur (et éventuellement sa
valeur de départ, la condition sur la variable pour Exemple :
laquelle la boucle s'arrête (basiquement une for (i=1; i<6; i++)
condition qui teste si la valeur du compteur dépasse {
printf("%d", i);
une limite) et enfin une instruction qui incrémente }
(ou décrémente) le compteur.

PROGRAMMATION 48
EN LANGAGE C
LES INSTRUCTIONS DE CONTRÔLE
L’instruction de répétition (while) Syntaxe :
L'instruction while représente un autre moyen
while ([condition])
d'exécuter plusieurs fois la même série
d'instructions. {
[Bloc d’instructions];
Avec cette structure de contrôle, tant qu'une
}
condition est vraie, les instructions lui
correspondant sont exécutées.
Exemple :
x=1;
while (x<=10)
{
a = 1/(x-20);
printf("%f", a);
x=x+1;
}

PROGRAMMATION 49
EN LANGAGE C
LES INSTRUCTIONS DE CONTRÔLE
L’instruction de répétition (do…while) Syntaxe :
C’est une seconde version de la boucle while que
do
l’on appelle do…while. La différence réside dans
l’ordre d’évaluation de la condition, ici le bloc {
d’instructions est exécuté premièrement puis la [Bloc d’instructions];
} while ([condition]);
condition est évaluée.

Exemple :
x=1;
do
{
a = 1/(x-20);
printf("%f", a);
x=x+1;
} while (x<=10);

PROGRAMMATION 50
EN LANGAGE C
LES INSTRUCTIONS DE CONTRÔLE
Exemple break :
Les instructions de branchement int main()
inconditionnel : break, continue {
int i;
for ( i=1 ; i<=5 ; i++ )
{ printf ("iteration %d\n", i);
printf ("bonjour\n");
Les instructions break et continue fournissent if ( i==3 )
une plus grande maîtrise de l’exécution d’une break;
boucle dans un code en C. Chaque fois que printf ("fin tour %d\n", i);
}
l’instruction break est rencontrée, le contrôle printf ("après la boucle");
d’exécution saute immédiatement à la première return 0;
instruction après la boucle. Pour passer le contrôle }
à l’itération suivante sans sortir de la boucle, nous
utilisons l’instruction continue. Les deux
instructions continue et break peuvent être
utilisées dans les boucles tant que et pour.

PROGRAMMATION 51
EN LANGAGE C
LES INSTRUCTIONS DE CONTRÔLE
Exemple continue:
Les instructions de branchement int main()
inconditionnel : break, continue {
int i ;
for ( i=1 ; i<=5 ; i++ )
{
Les instructions break et continue fournissent printf ("début tour %d\n", i) ;
une plus grande maîtrise de l’exécution d’une if (i<4) continue ;
boucle dans un code en C. Chaque fois que printf ("bonjour\n") ;
}
l’instruction break est rencontrée, le contrôle
return 0;
d’exécution saute immédiatement à la première }
instruction après la boucle. Pour passer le contrôle
à l’itération suivante sans sortir de la boucle, nous
utilisons l’instruction continue. Les deux
instructions continue et break peuvent être
utilisées dans les boucles tant que et pour.

PROGRAMMATION 52
EN LANGAGE C
LES FONCTIONS
Qu'est-ce qu'une fonction ? Définir et utiliser une fonction
Le concept de fonction ne vous est pas inconnu : Pour définir une fonction, nous allons devoir donner quatre
printf(), scanf(), et main() sont des informations sur celle-ci :
fonctions que vous avez surement utilisé. • son nom : les règles sont les mêmes que pour les variables ;
Une fonction est : • son corps (son contenu) : le bloc d’instructions à exécuter ;
 une suite d’instructions. • son type de retour : le type du résultat de la fonction ;
• d’éventuels paramètres : des valeurs reçues par la fonction
 marquée à l’aide d’un nom (comme une
lors de l’appel.
variable finalement).
La syntaxe est la suivante:
 qui a vocation à être exécutée à plusieurs type nom(paramètres)
reprises. {
 qui rassemble des instructions qui permettent /* Corps de la fonction */
d’effectuer une tâche précise (comme afficher }
du texte à l’écran, calculer la racine carrée d’un
nombre, etc).

PROGRAMMATION 53
EN LANGAGE C
LES FONCTIONS
Définir et utiliser une fonction Le type de retour
Prenons un exemple en créant une fonction qui Le type de retour permet d’indiquer deux choses :
affiche « bonjour ! » à l’écran. si la fonction retourne une valeur et le type de
#include <stdio.h> cette valeur. Comme dans l’exemple suivant :
void bonjour(void)
{ #include <stdio.h>
printf("Bonjour !\n"); int deux(void)
} {
return 2;
int main(void)
}
{ int main(void)
bonjour(); {
return 0; printf("Retour : %d\n", deux());
} return 0;
}
Comme vous le voyez, la fonction se nomme «
bonjour ». Son corps est composée d’un appel à
printf(). Dans le cas du type de retour void, il
spécifie que la fonction ne retourne rien. Dans le
cas des paramètres, il spécifie que la fonction
n’en reçoit aucun (cela se manifeste lors de
PROGRAMMATION
l’appel : il n’y a rien entre les parenthèses). EN LANGAGE C
54
LES FONCTIONS
Le retour de la fonction Exemple
Dans l’exemple ci-contre, la fonction deux() est
définie comme retournant une valeur de type int.
#include <stdio.h>
Vous retrouvez que la valeur retournée se trouve
int deux(void)
à droite de l’instruction return. Ce return arrête {
l’exécution de la fonction courante et provoque return 2;
un retour (techniquement, un saut) vers l’appel à }
int main(void)
cette fonction qui se voit alors attribuer la valeur {
de retour (s’il y en a une). Autrement dit, dans printf("Retour : %d\n", deux());
notre exemple, l’instruction return 2 provoque return 0;
}
l’arrêt l’exécution de la fonction deux() et ramène
l’exécution du programme à l’appel qui vaut
désormais 2, ce qui donne finalement
printf("Retour : %d\n", 2)
Autre remarque importante, une fonction ne peut
retourner qu’une seul variable au maximum.

PROGRAMMATION 55
EN LANGAGE C
LES FONCTIONS
Fonction qui ne retourne rien - void Exemple
Certaines fonctions peuvent ne retourner aucune
valeurs, leurs exécutions consiste plutôt à faire
certaines tâches particulières, par exemple
afficher, trier, modifier…
Observons l’exemple de programme qui contient
une fonction de ce type :

L’exécution donne le résultat suivant :

PROGRAMMATION 56
EN LANGAGE C
LES FONCTIONS
Les paramètres Exemple
Un paramètre sert à fournir des informations à la #include <stdio.h>
int ppcd(int a, int b)
fonction lors de son exécution.
{
La fonction printf() par exemple récupère ce int min = (a < b) ? a : b;
qu’elle doit afficher dans la console à l’aide de int i;
for (i = 2; i <= min; ++i)
paramètres. Ceux-ci sont définis de la même if (a % i == 0 && b % i == 0)
manière que les variables si ce n’est que les return i;
définitions sont séparées par des virgules. return 0;
}
Maintenant, nous pouvons réaliser une fonction int main(void)
qui calcul le plus petit commun diviseur entre {
deux nombres. int a;
int b;
C’est plus simple et plus lisible qu’une version int resultat;
sans fonction, non ? printf("Entrez deux nombres : ");
scanf("%d %d", &a, &b);
resultat = ppcd(a, b);
if (resultat != 0)
printf("Le plus petit diviseur de %d et %d est
%d\n", a, b, resultat);
return 0;
} PROGRAMMATION 57
EN LANGAGE C
LES FONCTIONS
• Ces valeurs sont recopiées dans les paramètres
Le passage des paramètres
correspondants de la fonction : l’ordre de recopie est celui
Nous allons étudier, dans cette partie, le dans lequel les entrées ou paramètres de la fonction sont
mécanisme de passage des paramètres, qui est écrits dans l’en-tête de la fonction : l’argument 1 dans le
un point fondamental concernant les fonctions. paramètre 1, et ainsi de suite ;
Nous allons voir en détail la manière dont se fait • La fonction est exécutée et réalise ses calculs et instructions ;
la communication entre les arguments fournis • L’instruction return est exécutée : l’expression contrôlée par
par la fonction appelante et les paramètres (ou cette instruction est évaluée et retournée au surprogramme
entrées) reçus par la fonction appelée. Ce qui a appelé cette fonction en tant que sous-programme.
passage de paramètre est effectué à chaque
appel d’une fonction Intégrité des variables locales
Le mécanisme de recopie En effet, il ne faut pas confondre les arguments d’une fonction
appelée et les variables du programme qui appelle cette
Les actions effectuées par l’ordinateur lors du
fonction. Un argument n’est pas nécessairement une variable,
passage des paramètres (transmission de la
et même si c’est le cas, c’est la valeur de l’argument qui est
valeur des arguments au moment d’un appel de
transmis à la fonction et non la variable elle-même. On peut
fonction) sont les suivantes :
donc en conclure qu’une variable utilisée comme argument
 Les valeurs des arguments sont calculées (ou d’un appel de fonction ne sera pas modifiée par l’appel, car c’est
évaluées) ; simplement sa valeur qui est recopiée. PROGRAMMATION 58
EN LANGAGE C
LES FONCTIONS
Les arguments et les paramètres Exemple
À ce stade, il est important de préciser qu’un #include <stdio.h>
paramètre est propre à une fonction, il n’est pas
utilisable (reconnu) en dehors de celle-ci. void fonction(int nombre)
Par exemple, la variable a de la fonction ppcd() {
++nombre;
n’a aucun rapport avec la variable a de la printf("Variable nombre dans fonction : %d\n", nombre);
fonction main(). Nous parlons ici de la portée des }
variables que nous allons traiter ultérieurement. int main(void)
{
int nombre = 5;
Voici un autre exemple plus explicite à ce sujet,
fonction(nombre);
et remarquez le résultat afficher à l’exécution. printf("Variable nombre dans main : %d\n", nombre);
return 0;
}

PROGRAMMATION 59
EN LANGAGE C
Informations complémentaires : Les fonctions

A quelle place nous devons mettre la fonction?


La réponse à cette question ne sera clair que si on comprend un certain principe: une fonction ne peut être utilisée
que ci elle est déclarée avant son appel (il y’a une différence entre la déclaration et la définition d’une fonction).
C-à-d que :
cette version marche : celle-là est par convention incorrecte cette version est la plus correcte

La troisième cas présente une version ou nous avons définit la fonction après son appel, mais sa déclaration s’est
faite à l’intérieur du programme principal avant son appel.
Informations complémentaires : Les fonctions

La déclaration
La déclaration d'une fonction n'est nécessaire que lorsque son utilisation précède sa définition. En effet, une fois
définie, la fonction est entièrement connue et donc n'a plus besoin d'être déclarée. Il est cependant toujours
conseillé de ne définir une fonction qu'après son utilisation (ce qui requiert donc une déclaration) ne serait-ce que
pour la lisibilité du programme (en effet c'est le programme principal qu'on veut voir à première vue, pas les petits
détails).
Dans une déclaration
On peut : Mettre le nom des arguments de la fonction (bon uniquement pour la déco et rien d'autre).
Par exemple :
int Surface(int Longueur, int largeur);
int Surface(int, int);
Dans une définition:
• On peut ne pas préciser le type de retour d'une fonction (déconseillé). Dans ce cas celle-ci est supposée retourner
un int.
• Ne pas préciser les arguments de la fonction (déconseillé). Dans ce cas, il faut aller à la définition de la fonction
pour connaître les arguments qu'elle requiert. Attention ! Ne pas préciser les arguments d’une fonction n'est pas la
même chose que déclarer une fonction qui ne requiert aucun argument.
Informations complémentaires : Les fonctions

Les précautions
Une fonction peut fournir comme résultat :
• - un type primitif,
• - une structure (définie par struct - traité ultérieurement dans ce cours),
• - une réunion (définie par union - traité ultérieurement dans ce cours),
• - un pointeur (traité ultérieurement dans ce cours),
• - void (vide).
Une fonction ne peut pas fournir comme résultat des tableaux, des chaînes de caractères ou des fonctions.
(Attention : Il est cependant possible de renvoyer un pointeur sur le premier élément d'un tableau ou d'une chaîne
de caractères.)
• Si une fonction ne fournit pas de résultat, il faut indiquer void (vide) comme type du résultat.
• Si une fonction n'a pas de paramètres, on peut déclarer la liste des paramètres comme (void) ou simplement
comme () .
• Le type par défaut est int; autrement dit : si le type du retour d'une fonction n'est pas déclaré explicitement, elle
est automatiquement du type int.
• Il est interdit de définir des fonctions à l'intérieur d'une autre fonction (comme en Pascal).
• En principe, l'ordre des définitions dans le texte du programme ne joue pas de rôle, mais chaque fonction doit être
déclarée ou définie avant d'être appelée
LES FONCTIONS : EXEMPLE 1
Affichage d’un rectangle d’étoile Le programme principale
Écrire un programme qui permet d'afficher à le programme principale serait de cette forme, l’affichage du
l'écran un rectangle de longueur L et de hauteur rectangle se fera à travers l’appel de la fonction RECTANGLE qui nous
H formé d'astérisques ‘*’ (L et H introduit par devons définir après :
l’utilisateur). Le résultat à l’écran doit produire #include <stdio.h>
#include <stdlib.h>
l’affichage suivant :
int main()
{
/* Prototypes des fonctions appelées par main */
void RECTANGLE(int L, int H);
/* Déclaration des variables locales de main */
int L, H;
/* Traitements */
printf("Entrer la longueur (>= 1): ");
scanf("%d", &L);
printf("Entrer la hauteur (>= 1): ");
scanf("%d", &H);
/* Afficher un rectangle d'étoiles */
RECTANGLE(L,H);
return (0);
}
PROGRAMMATION 63
EN LANGAGE C
LES FONCTIONS : EXEMPLE 1
Définition de la fonction Définition de la fonction LIGNE
RECTANGLE
La fonction RECTANGLE telle que nous l’avons La fonction ligne admet un seul paramètre : le nombre d’astérisques
appelé admet deux paramètres L et H, et puis par ligne. La fonction ne retourne rien, dont voici la définition
cette fonction ne retourne rien puisque sa tâche
consiste à faire seulement un affichage : void LIGNE(int L)
void RECTANGLE(int L, int H) {
/* Affiche à l'écran une ligne avec L étoiles */
{
/* Déclaration des variables locales */
/* Prototypes des fonctions appelées */ int I;
void LIGNE(int L); /* Traitements */
/* Déclaration des variables locales */ for (I=0; I<L; I++)
int I; printf("*");
printf("\n");
/* Traitements */
}
/* Afficher H lignes avec L étoiles */
for (I=0; I<H; I++)
LIGNE(L);
}
Remarquer que même dans cette fonction nous
avons déclaré et appelé une fonction LIGNE qui
affiche chaque fois qu’elle est appelé une ligne
composée de L astérisques PROGRAMMATION 64
EN LANGAGE C
LES FONCTIONS : EXEMPLE 1
Schéma des appels et de définitions des fonctions

PROGRAMMATION 65
EN LANGAGE C
LES FONCTIONS : EXEMPLE 1
Code complet

PROGRAMMATION 66
EN LANGAGE C
LES FONCTIONS : EXEMPLE 2
Calcul de valeurs de polynôme Exécution
Dans cet exemple on se propose de calculer la En voila un exemple d’exécution qui donne une
valeur d’un polynôme dans le degré et les idée sur le déroulement du programme :
coefficients du polynôme sont introduits par
l’utilisateurs. Le programme récupère le degré du
polynôme (un entier n), ensuite il demande à
l’utilisateur les coefficients (des réels) pour les
stockés dans un tableau.
Le programme demande ensuite à l’utilisateur
d’introduire une valeur réel de x pour qu’il puisse
calculer la valeur du polynôme (P(x)) .
Avec :
𝑛

𝑃 𝑥 = 𝐶 𝑖 ∗ 𝑥𝑛
𝑖=0

PROGRAMMATION 67
EN LANGAGE C
LES FONCTIONS : EXEMPLE 2
Calcul de valeurs de polynôme Programme principal
Nous allons élaborer un programme dans lequel #include <stdio.h>
#include <stdlib.h>
nous allons utiliser et définir une fonction qui #define NMAX 100
calcule la puissance de x. int main()
{
Le programme principal aura la forme ci-contre. int n,i;
float x,P,C[NMAX];
Vous remarquez la déclaration et l’appel de la float Puissance(float y, int m);
fonction Puissance que nous devons définir juste printf("Donner le degre du polynome\n");
scanf("%d",&n);
après. printf("Introduire les coeficiens\n");
for(i=0;i<=n;i++)
{
printf("C %d =",i);
scanf("%f",&C[i]);
}
printf("Donner la valeur de x\n");
scanf("%f",&x);
P=0;
for(i=0;i<=n;i++)
{
P+=C[i]*Puissance(x,i);
}
printf("la valeur du polynome P(%f)=%f",x,P);
return 0;
}
PROGRAMMATION 68
EN LANGAGE C
LES FONCTIONS : EXEMPLE 2
Calcul de valeurs de polynôme Fonction puissance
La fonction puissance admet deux paramètres y : float Puissance(float y, int m)
{
réel et m: entier. La fonction calcul y à la
float F;
puissance m et donc doit retourner cette valeur int i;
dont le type et réel (float) F=1;
if(m==0)
return 1;
else
{
for(i=1;i<=m;i++)
{
F*=y;
}
return F;
}
}

PROGRAMMATION 69
EN LANGAGE C
LES FONCTIONS : EXEMPLE 2
Code complet

PROGRAMMATION 70
EN LANGAGE C
LES FONCTIONS : EXEMPLE 3
Calcul des valeurs d’un fonction
Le programme suivant permet de calculer plusieurs valeurs de la fonction numérique :
𝐹 𝑥 = 𝑋 3 − 2𝑋 + 1
On désire construire un tableau de valeurs de cette fonction. Le nombre N de valeurs ainsi que les
valeurs de X sont entrés au clavier par l’utilisateur. L’exécution de ce programme doit produire
d’affichage suivant :

Le programme doit être modulaire (utilisation de fonctions)

PROGRAMMATION 71
EN LANGAGE C
LES FONCTIONS : EXEMPLE 3
Calcul des valeurs d’un fonction Forme du programme principal
En modularisant ce problème, nous obtenons un #include <stdio.h>
#include <stdlib.h>
programme principal très court et bien 'lisible'. La
fonction main joue le rôle du programme int main()
principal aura comme forme ci-contre : {
/* Prototypes des fonctions appelées par main */
Pour que la machine puisse exécuter ce void ACQUERIR(int *N);
programme, il faut encore implémenter les void LIRE_VECTEUR(float T[], int N);
fonction suivante : void CALCULER_VALEURS(float X[], float V[], int N);
void AFFICHER_TABLE(float X[], float V[], int N);
ACQUERIR /* Déclaration des variables locales de main */
LIRE_VECTEUR float X[100]; /* valeurs de X */
float V[100]; /* valeurs de F(X) */
CALCULER_VALEURS int N;
AFFICHER_TABLE. /* Traitements */
ACQUERIR(&N); /* 1 <= N <= 100 */
LIRE_VECTEUR(X, N);
CALCULER_VALEURS(X, V, N);
AFFICHER_TABLE(X, V, N);
return 0;
}

PROGRAMMATION 72
EN LANGAGE C
LES FONCTIONS : EXEMPLE 3
Fonction ACQUERIR Sa définition
 ACQUERIR void ACQUERIR(int *N)
La fonction ACQUERIR permettra de récupérer {
do
une valeur valide de N (1 ≤ 𝑁 ≤ 100), donc la
{
vérification doit être prise en compte. printf("Entrez un entier entre 1 et 100 : ");
Cette fonction prendra en argument l’adresse (et scanf("%d", N);
pas la valeur) de N, cela permet à la fonction de }
modifier la valeur de N à l’intérieur de cette while ((*N<1) || (*N>100));
fonction. C’est pour cela que lors de son appel }
nous avons utilisé l’adresse de N :
ACQUERIR(&N);
Dans la définition nous utilisons *N pour signifier
que les instructions agissent sur le contenu de la
variable.
La fonction d’après son utilisation ne retourne
aucune valeur.

PROGRAMMATION 73
EN LANGAGE C
LES FONCTIONS : EXEMPLE 3
Fonction LIRE_VECTEUR Sa définition
 LIRE_VECTEUR void LIRE_VECTEUR(float T[], int N)
La fonction LIRE_VECTEUR permettra de remplir {
/* Remplit un tableau T d'ordre N avec des
un tableau T de N valeur, nous devons fournir T et
nombres réels entrés au clavier */
N dans les paramètres de cette fonction. /* Déclaration des variables locales */
Il faut noter que la manière de passé un tableau int i;
dans les arguments de la fonction se fait avec /* Remplir le tableau */
l’entête suivant : printf("Entrez %d nombres reels :\n", N);
void LIRE_VECTEUR(float T[], int N) for (i=0; i<N; i++)
scanf("%f", &T[i]);
L’appel de cet de cette fonction est de la manière }
suivante :
LIRE_VECTEUR(X, N);
c’est-à-dire nous donnons seulement le nom du
tableau à remplir.
La fonction d’après son utilisation ne retourne
aucune valeur.

PROGRAMMATION 74
EN LANGAGE C
LES FONCTIONS : EXEMPLE 3
Fonction CALCULER_VALEURS Sa définition
 CALCULER_VALEURS void CALCULER_VALEURS(float X[], float V[], int N)
La fonction CALCULER_VALEURS permettra de {
/* Remplit le tableau V avec les valeurs de */
calculer un tableau V à partir des N éléments du
/* F(X[I]) pour les N premières composantes */
tableau X, pour cela nous avons utilisé aussi une /* X[I] du tableau X */
autre fonction (F) qui va être utilisé uniquement /* Prototype de la fonction F */
dans la fonction CALCULER_VALEURS. float F(float X);
/* Déclaration des variables locales */
int I;
/* Calculer les N valeurs */
for (i=0; i<N; i++)
V[i] = F(X[i]);
}

PROGRAMMATION 75
EN LANGAGE C
LES FONCTIONS : EXEMPLE 3
Fonction F Sa définition
F float F(float X)
La fonction F permettra de calculer la valeur de {
/* Retourne la valeur numérique du polynôme
de la fonction mathématique ∶ défini par F(X) = X^3-2X+1 */
𝐹 𝑥 = 𝑋 3 − 2𝑋 + 1 return (X*X*X - 2*X + 1);
Pour ensuite retourner une valeur cette fonction. }

PROGRAMMATION 76
EN LANGAGE C
LES FONCTIONS : EXEMPLE 3
Fonction AFFICHER_TABLE. Sa définition
 AFFICHER_TABLE. void AFFICHER_TABLE(float X[], float V[], int N)
La fonction AFFICHER_TABLE affichera les N {
/* Affiche une table de N valeurs :
valeurs stockées dans le tableau X et les valeurs
X contient les valeurs données et
qui correspondes dans le tableau V∶ V contient les valeurs calculées. */
/* Déclaration des variables locales */
int i;
/* Afficher le tableau */
printf("\n X : ");
for (i=0; i<N; i++)
printf("%6.1f", X[i]);
printf("\n F(X): ");
for (i=0; i<N; i++)
printf("%6.1f", V[i]);
printf("\n");
}

PROGRAMMATION 77
EN LANGAGE C
LES FONCTIONS : EXEMPLE 3
Schéma des appels et de définitions des fonctions
Nous avons construit un programme
entièrement modulaire, nous avons
devisé les tâches sous forme de 5
fonctions. La conséquence est bien
visible : le programme principal est plus
lisible, et la réflexion devient plus facile
par la résolution du problème par des
modules indépendants au niveau de la
nature des tâches.

PROGRAMMATION 78
EN LANGAGE C
LES FONCTIONS : EXEMPLE 3
Le code complet

PROGRAMMATION 79
EN LANGAGE C
LES FONCTIONS RÉCURSIVES
Définition
il s'agit de programmes ou de fonctions d'un  Récursivité croisée (ou indirecte): l’appel d’une
programme qui ont la faculté de s'appeler eux- fonction entraine celui d’une autre fonction qui,
mêmes (on entend également le terme d'auto- à son tour, appelle la fonction initiale(le
appel ce qui est logique). La récursivité est une « cycle » pouvant d’ailleurs faire intervenir plus
manière simple et élégante de résoudre certains de deux fonctions).
problèmes algorithmiques, notamment en
mathématique.
En C, toute fonction peut appeler toute fonction
dont elle connaît le nom. En particulier, elle peut
s’appeler elle-même. Il est donc possible d’écrire
des fonctions récursives.
Le langage C autorise la récursivité des appels de
fonctions. Celle-ci peut prendre deux aspects :
 Récursivité directe : une fonction comporte,
dans sa définition, au moins un appel à elle-
même
PROGRAMMATION 80
EN LANGAGE C
LES FONCTIONS RÉCURSIVES
Exemple de Récursivité directe Exemple de Récursivité croisée
Voici un exemple fort classique (d’ailleurs Pour illustrer cette notion partons d’un exercice
inefficace sur le plan de temps d’exécution) On définit deux suites u et v par
d’une fonction calculant une factorielle de 𝑢0 = 1; 𝑣0 = 12 et pour tout entier naturel n :
manière récursive : 1
𝑢𝑛+1 = (𝑢𝑛 + 2𝑣𝑛 )
3
int fac(int n) 1
{ 𝑣𝑛+1 = (𝑢𝑛 + 3𝑣𝑛 )
4
if (n == 0)
return 1 ;
Il s’agit ici de définir deux fonctions récursives
else dépendant l’une de l’autre.
return n*fac(n-1) ;
}

PROGRAMMATION 81
EN LANGAGE C
LES FONCTIONS RÉCURSIVES
Exemple de Récursivité croisée Code
L’écriture de ces algorithmes ne pose pas de
difficultés, elle apparait même beaucoup plus
intuitive qu’une écriture itérative.

PROGRAMMATION 82
EN LANGAGE C
LES FONCTIONS RÉCURSIVES
Efficacité
On peut par contre s’attendre à retrouver des
problèmes d’efficacité. Cela est confirmé par
l’exécution du programme pour n=60 par
exemple.

PROGRAMMATION 83
EN LANGAGE C
LES TABLEAUX
Déclaration
On déclare un tableau (statique) par : Dans une telle déclaration, le nombre
typeElements nomTableau[NOMBRE_ELEMENTS]; d’éléments du tableau est obligatoirement une
où typeElements est le type des éléments du constante.
tableau, nomTableau est le nom du tableau, et Nous verrons dans le chapitre sur l’allocation
NOMBRE_ELEMENTS est une constante indiquant dynamique comment créer des tableaux dont
le nombre d’éléments du tableau. le nombre d’emplacements mémoire est
Par exemple, pour déclarer un tableau de 100 donné par une variable.
entiers appelé tab :
 int tab[100]; L’exemple suivant nous permet de voir cette
déclaration et manipulation d’un tableau.
Pour déclarer un tableau de 150 caractères
appelé chaine ;
 char chaine[150];

PROGRAMMATION 84
EN LANGAGE C
LES TABLEAUX
Déclaration

Le nombre d’éléments du tableau peut être défini comment


une constante dans une directive #define ce qui
augmente la souplesse du programme (on peut alors
changer le nombre d’éléments en changeant au niveau du
#define).
Le programme ci-contre, permet de mémoriser différentes
valeurs saisies au clavier et d’afficher la moyenne. Le
nombre de valeurs, ou nombre d’éléments du tableau, est
fixé à 100.
le nombre d’éléments n (ce que nous appellerons taille
utile) doit toutefois rester inférieur à la valeur maximale de
constante fixée. L’idée est de n’utiliser qu’une partie du
tableau. On réserve des emplacements mémoires pour
Taille_Max éléments dans le tableau, mais il n’est pas
indispensable d’utiliser toutes les cases du tableau. Par
contre, le nombre de cases utilisées doit rester inférieur ou
égal à Taille_Max. PROGRAMMATION 85
EN LANGAGE C
Informations complémentaires : Les constantes

Les constantes sont proches des variables, à un


point près : Elles ne peuvent pas changer de #include <stdio.h>
#include <stdlib.h>
valeur au cours du programme. /* Les constantes symboliques définies par l'utilisateur */
Les constantes symboliques #define MAX 100
#define PI 3.14
Les constantes symboliques sont définies par le #define LANGAGE "C-AINSI"
programmeur (ou pour lui dans des fichiers inclus int main()
par exemple stdio.h). {
const float g=9.8;
• Variable déclarée avec le modificateur const /* Ce code affichera les noms des 3 constantes déclarées
Ce sont des variables dont la valeur n’est pas avec define et leur valeurs */
printf("MAX = %d, PI = %e, LANGAGE= \"%s\"\n",MAX, PI,
modifiable, sauf au niveau de leurs déclarations.
LANGAGE);
Pour déclarer une constante, il faut ajouter le mot /* Ce code affichera le nom de la constante g déclarée avec
réservé const avant son type. const et sa valeur */
printf("g=%f\n",g);
• Constantes préprocesseur /* Ce code essayera de changer les valeurs des constantes
Avec le commande #define, il est possible de ce qui provoquera des erreurs*/
donner un nom symbolique à une constante MAX=120;
g=10.0
littérale définies dans les fichiers d'entête ou dans return 0;
le texte du programme (de préférence au début). }
LES TABLEAUX
Initialisation
On peut initialiser un tableau à l'aide des
accolades. Par exemple : On peut également initialiser un tableau à plusieurs
int t[10] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90}; dimensions. Par exemple :
Bien évidemment, on n'est pas obligé d'initialiser • int t[3][4] = { {0, 1, 2, 3},{4, 5, 6, 7},{8, 9, 10, 11} };
tous les éléments, on aurait donc pu par exemple
nous arrêter après le 5ème élément, et dans ce
cas les autres éléments du tableau seront
automatiquement non initialisés et contiennent
« n'importe quoi », pas 0 !
Lorsqu'on déclare un tableau avec initialisation,
on peut ne pas spécifier le nombre d'éléments
car le compilateur le calculera automatiquement.
Ainsi, la déclaration :
 int t[] = {0, 10, 20, 30};
est strictement identique à :
 int t[4] = {0, 10, 20, 30};
PROGRAMMATION 87
EN LANGAGE C
NOTION DE POINTEURS
introduction Comprendre la notion d'adresse
Un pointeur est une variable contenant l'adresse d'une Lorsque l'on exécute un programme, celui-ci est stocké
autre variable d'un type donné. en mémoire, cela signifie que d'une part le code à
La notion de pointeur fait souvent peur car il s'agit exécuter est stocké, mais aussi que chaque variable que
d'une technique de programmation très puissante, l'on a défini a une zone de mémoire qui lui est
permettant de définir des structures dynamiques, c'est- réservée, et la taille de cette zone correspond au type
à-dire qui évoluent au cours du temps (par opposition de variable que l'on a déclaré.
aux tableaux par exemple qui sont des structures de
données statiques, dont la taille est figée à la En réalité la mémoire est constituée de plein de petites
définition). cases de 8 bits (un octet). Une variable, selon son type
Principalement nous avons 3 utilisations des pointeurs (donc sa taille), va ainsi occuper une ou plusieurs de ces
pour résoudre certains problèmes rencontrés: cases (une variable de type char occupera une seule
 Pour un parcourt efficace de listes d’éléments (à la case, tandis qu'une variable de type long occupera 4
place du parcourt à l’aide d’indices). cases consécutives).
 Pour le passage par adresse (à la place de passage
par valeurs qui utilise la copie de valeurs) lors
d’appels de fonctions.
 Pour l’allocation dynamique de la mémoire (à la place
de l’allocation statique)
PROGRAMMATION 88
EN LANGAGE C
NOTION DE POINTEURS
Introduction
Nous avons déjà été amené à utiliser l’opérateur & L’instruction :
pour désigné l’adresse d’une variable dans la fonction ad=&n;
scanf. D’une manière générale, le langage C permet
Affecte à la variable ad la valeur de l’expression &n.
de manipuler les adresses par l’intermédiaire de L’operateur & est un opérateur unaire qui fournie
variables spéciales nommées « pointeurs ». comme résultat l‘adresse de n. Ainsi, cette instruction
En guise d’introduction à cette nouvelle notion, place dans la variable ad l ’adresse de la variable n.
considérons les instructions : L’instruction suivante :
int *ad;
*ad = 30;
int n;
n=20; Signifie : affecter à la variable sur laquelle pointe ad la
ad=&n;
valeur 30. Or ad pointe sur n, et donc n se verra
attribuer la valeur 30. Bien entendu, ici, c’est équivalent
*ad=30;
à cette affectation:
La première instruction réserve une variables nommée
n=30;
ad comme étant un « pointeur » sur des entiers. Nous
verrons que * est un opérateur qui désigne le contenus
de l’adresse qui le suit. Ainsi, on peut dire que cette
déclaration signifie que *ad, c-à-d l’objet d’adresse ad,
est de type int ; ce qui signifie bien que ad est
l’adresse d’un entier.
PROGRAMMATION 89
EN LANGAGE C
NOTION DE POINTEURS
Exemple
Prenant l’exemple suivant :

Mémoire organisée
Code source de déclaration en C Adresse
en mot de 32bits

PROGRAMMATION 90
EN LANGAGE C
NOTION DE POINTEURS
Priorité de * et & Exemple
En travaillant avec des pointeurs, nous devons observer Exemple
les règles suivantes: Après l'instruction :
P = &X;
 Les opérateurs * et & ont la même priorité que les Les expressions suivantes, sont équivalentes:
autres opérateurs unaires (la négation !,
l'incrémentation ++, la décrémentation --). Dans une
Y = *P+1 ↔ Y = X+1
même expression, les opérateurs unaires *, &, !, ++, -
- sont évalués de droite à gauche.
*P = *P+10 ↔ X = X+10
 Si un pointeur P pointe sur une variable X, alors *P
peut être utilisé partout où on peut écrire X. *P += 2 ↔ X += 2

++*P ↔ ++X

(*P)++ ↔ X++

PROGRAMMATION 91
91 EN LANGAGE C
NOTION DE POINTEURS
Résumons
Après les instructions: Les pointeurs et les noms de variables ont le même
rôle: Ils donnent accès à un emplacement dans la
int A; mémoire interne de l'ordinateur. Il faut quand même
bien faire la différence:
int *P;
P = &A;
Attention!
A désigne le contenu de A
 Un pointeur est une variable qui peut 'pointer' sur
&A désigne l'adresse de A différentes adresses.

P désigne l'adresse de A  Le nom d'une variable reste toujours lié à la même


*P désigne le contenu de A adresse.
En outre:

&P désigne l'adresse du pointeur P


*A est illégal (puisque A n'est pas un pointeur)
 X.

PROGRAMMATION 92
92 EN LANGAGE C
NOTION DE POINTEURS
Pointeurs et tableaux
En C, il existe une relation très étroite entre tableaux et En déclarant un tableau A de type int et un pointeur P
pointeurs. Ainsi, chaque opération avec des indices de sur int,
tableaux peut aussi être exprimée à l'aide de pointeurs. int A[10];
En général, les versions formulées avec des pointeurs int *P;
sont plus compactes et plus efficientes, surtout à
l'intérieur de fonctions. Mais, du moins pour des l'instruction:
débutants, le 'formalisme pointeur' est un peu P = A; est équivalente à P = &A[0];
inhabituel. Si P pointe sur une composante quelconque d'un
En effet, le nom d'un tableau représente l'adresse de tableau, alors P+1 pointe sur la composante suivante.
son premier élément. En d'autre termes: Plus généralement,
&tableau[0] et tableau P+i pointe sur la i-ième composante derrière P et
P-i pointe sur la i-ième composante devant P.
sont une seule et même adresse. Ainsi, après l'instruction,
En simplifiant, nous pouvons retenir que le nom d'un P = A;
tableau est un pointeur constant sur le premier le pointeur P pointe sur A[0], et *(P+1) désigne le
élément du tableau. contenu de A[1]
*(P+2) désigne le contenu de A[2]
...
PROGRAMMATION 93
*(P+i) désigne le contenu de A[i] 93 EN LANGAGE C
NOTION DE POINTEURS
Pointeurs et tableaux : opérations Exemple
Addition et soustraction d'un nombre entier Exemples
Si P pointe sur l'élément A[i] d'un tableau, alors int A[10];
 P+n pointe sur A[i+n] int *P;
 P-n pointe sur A[i-n] P = A+9;
Incrémentation et décrémentation d'un pointeur /* dernier élément + 1 -> légal */
Si P pointe sur l'élément A[i] d'un tableau, alors après P = A+11;
l'instruction /* dernier élément + 2 -> illégal */
 P++; P pointe sur A[i+1] P = A-1;
 P+=n; P pointe sur A[i+n] /* premier élément - 1 -> illégal */
 P--; P pointe sur A[i-1]
 P-=n; P pointe sur A[i-n]
Domaine des opérations
L'addition, la soustraction, l'incrémentation et la
décrémentation sur les pointeurs sont seulement
définies à l'intérieur d'un tableau. Si l'adresse formée
par le pointeur et l'indice sort du domaine du tableau,
alors le résultat n'est pas défini.
PROGRAMMATION 94
94 EN LANGAGE C
NOTION DE POINTEURS
Pointeurs et tableaux : opérations Exemple
Soustraction de deux pointeurs Comparaison de deux pointeurs
Soient P1 et P2 deux pointeurs qui pointent dans le On peut comparer deux pointeurs par <, >, <=, >=, ==,
même tableau: !=.
P1-P2 fournit le nombre de composantes comprises La comparaison de deux pointeurs qui pointent dans le
entre P1 et P2. même tableau est équivalente à la comparaison des
Le résultat de la soustraction P1-P2 est indices correspondants. (Si les pointeurs ne pointent
- négatif, si P1 précède P2 pas dans le même tableau, alors le résultat est donné
par leurs positions relatives dans la mémoire).
- zéro, si P1 = P2
- positif, si P2 précède P1
- indéfini, si P1 et P2 ne pointent pas dans le même
tableau
Plus généralement, la soustraction de deux pointeurs
qui pointent dans le même tableau est équivalente à la
soustraction des indices correspondants.

PROGRAMMATION 95
95 EN LANGAGE C
NOTION DE POINTEURS
Pointeurs et tableaux Attention
Résumons Il existe toujours une différence essentielle entre un
Soit un tableau A d'un type quelconque et i un indice pointeur et le nom d'un tableau:
pour les composantes de A, alors - Un pointeur est une variable,
A désigne l'adresse de A[0] donc des opérations comme P = A ou P++ sont
A+i désigne l'adresse de A[i] permises.
*(A+i) désigne le contenu de A[i] - Le nom d'un tableau est une constante,
donc des opérations comme A = P ou A++ sont
Si P = A, alors impossibles.
P pointe sur l'élément A[0]
P+i pointe sur l'élément A[i]
*(P+i) désigne le contenu de A[i]

PROGRAMMATION 96
96 EN LANGAGE C
NOTION DE POINTEURS
Formalisme tableau
Les deux programmes suivants copient les éléments Nous pouvons remplacer systématiquement la notation
positifs d'un tableau T dans un deuxième tableau POS. tableau[I] par *(tableau + I), ce qui conduit à ce
int main() programme:
{ int main()
int T[10] = {-3, 4, 0, -7, 3, 8, 0, -1, 4, {
-9}; int T[10] = {-3, 4, 0, -7, 3, 8, 0, -1, 4,
int POS[10]; -9};
int I,J; /* indices courants dans T et int POS[10];
POS */ int I,J; /* indices courants dans T et
for (J=0,I=0 ; I<10 ; I++) POS */
if (T[I]>0) for (J=0,I=0 ; I<10 ; I++)
{ if (*(T+I)>0)
POS[J] = T[I]; {
J++; *(POS+J) = *(T+I);
} J++;
return 0; }
} return 0;
}

PROGRAMMATION 97
97 EN LANGAGE C
NOTION DE POINTEURS
Passage par valeur et passage par adresse
Passage des paramètres par valeur Passage des paramètres par adresse
En C, le passage des paramètres se fait toujours par la Pour changer la valeur d'une variable de la fonction
valeur, c.-à-d. les fonctions n'obtiennent que les valeurs appelante, nous allons procéder comme suit:
de leurs paramètres et n'ont pas d'accès aux variables
elles-mêmes.  la fonction appelante doit fournir l'adresse de la
Les paramètres d'une fonction sont à considérer variable et
comme des variables locales qui sont initialisées  la fonction appelée doit déclarer le paramètre
automatiquement par les valeurs indiquées lors d'un comme pointeur.
appel.
A l'intérieur de la fonction, nous pouvons donc changer
On peut alors atteindre la variable à l'aide du pointeur.
les valeurs des paramètres sans influencer les valeurs
originales dans les fonctions appelantes.

PROGRAMMATION 98
98 EN LANGAGE C
NOTION DE POINTEURS
Passage par valeur et passage par adresse
Exemple de passage par valeur Explication: Lors de l'appel, les valeurs de X et de Y sont
Nous voulons écrire une fonction PERMUTER qui copiées dans les paramètres A et B. PERMUTER
échange le contenu de deux variables du type int. En échange bien contenu des variables locales A et B, mais
première approche, nous écrivons la fonction suivante: les valeurs de X et Y restent les mêmes.
Mauvaise solution
void PERMUTER (int A, int B)
{
int AIDE;
AIDE = A;
A = B;
B = AIDE;
}
Nous appelons la fonction pour deux variables X et Y
par:
PERMUTER(X, Y);
Résultat: X et Y restent inchangés !.

PROGRAMMATION 99
99 EN LANGAGE C
NOTION DE POINTEURS
Passage par valeur et passage par adresse
Exemple de passage par adresse Explication: Lors de l'appel, les adresses de X et de Y
Pour pouvoir modifier le contenu de X et de Y, la sont copiées dans les pointeurs A et B. PERMUTER
fonction PERMUTER a besoin des adresses de X et Y. En échange ensuite le contenu des adresses indiquées par
utilisant des pointeurs, nous écrivons une deuxième les pointeurs A et B.
fonction:
void PERMUTER (int *A, int *B)
{
int AIDE;
AIDE = *A;
*A = *B;
*B = AIDE;
}
Nous appelons la fonction par:
PERMUTER(&X, &Y);
Résultat: Le contenu des variables X et Y est échangé !

PROGRAMMATION 100
100 EN LANGAGE C
NOTION DE POINTEURS
Passage par valeur et passage par adresse
Passage de l'adresse d'un tableau à une void LIRE_TAB(int N, int *PTAB)
dimension {
printf("Entrez %d valeurs : \n", N);
 Méthode
while(N)
Comme il est impossible de passer 'la valeur' de tout un
{
tableau à une fonction, on fournit l'adresse d'un
scanf("%d", PTAB++);
élément du tableau.
N--
En général, on fournit l'adresse du premier élément du }
tableau, qui est donnée par le nom du tableau.
}
Pour qu'une fonction puisse travailler correctement
Nous obtenons alors les grilles suivantes:
avec un tableau qui n'est pas du type char, il faut aussi
fournir la dimension du tableau ou le nombre
d'éléments à traiter comme paramètre, sinon la
fonction risque de sortir du domaine du tableau.
Exemple
La fonction LIRETAB lit N données pour un tableau
(unidimensionnel) du type int et les mémorise à partir
de l'adresse indiquée par le pointeur PTAB. PTAB et N
sont fournis comme paramètres.
PROGRAMMATION 101
101 EN LANGAGE C
NOTION DE POINTEURS
Allocation dynamique de mémoire
Déclaration statique de données Nous avons vu que l'utilisation de pointeurs nous
Chaque variable dans un programme a besoin d'un permet de mémoriser économiquement des données
certain nombre d'octets en mémoire. Jusqu'ici, la de différentes grandeurs. Si nous générons ces données
réservation de la mémoire s'est déroulée pendant l'exécution du programme, il nous faut des
automatiquement par l'emploi des déclarations des moyens pour réserver et libérer de la mémoire au fur
données. Dans tous ces cas, le nombre d'octets à et à mesure que nous en avons besoin. Nous parlons
réserver était déjà connu pendant la compilation. Nous alors de l'allocation dynamique de la mémoire.
parlons alors de la déclaration statique des variables.

Problème
Souvent, nous devons travailler avec des données dont
nous ne pouvons pas prévoir le nombre et la grandeur
lors de la programmation. Ce serait alors un gaspillage
de réserver toujours l'espace maximal prévisible. Il
nous faut donc un moyen de gérer la mémoire lors de
l'exécution du programme. PROGRAMMATION 102
102 EN LANGAGE C
NOTION DE POINTEURS
Allocation dynamique de mémoire
La fonction malloc et l'opérateur sizeof Exemple :
La fonction malloc de la bibliothèque <stdlib> nous
int *p; // pointeur sur un entier
aide à localiser et à réserver de la mémoire au cours int *T; // pointeur sur un entier
d'un programme. Elle nous donne accès au tas (heap); // allocation dynamique d’un entier
c.-à-d. à l'espace en mémoire laissé libre une fois mis p = (int *)malloc(sizeof(int)); // alloue 4 octets (= int) en mémoire
en place le DOS, les gestionnaires, les programmes *p = 1; // ecrit 1 dans la zone mémoire allouée
résidents, le programme lui-même et la pile (stack). // allocation dynamique d’un tableau de 10 int
L’operateur sizeof T = (int *)malloc(sizeof(int) * 10); /* alloue 4 * 10 octets en mémoire
// initialise le tableau avec des 0 (cf. la fonction memset)
Nous introduisons la fonction « sizeof » pour illustrer for(int i=0;i<10;i++)
les notions de taille des données. « sizeof » attend {
comme argument un type et il renvoie le nombre *(T+i) = 0; // les 2 écritures sont possibles
d'octets nécessaire pour le coder dans la mémoire. T[i] = 0; // identique à la ligne précédente
}
// la libération de la mémoire allouée
free(p);
free(T);

PROGRAMMATION 103
103 EN LANGAGE C
NOTION DE POINTEURS
Allocation dynamique de mémoire
Revenons un peu sur l'allocation de notre tableau, Exemple :
comme nous l'avons vu précédemment, nous pouvons int **matrice , i;
utiliser une autre fonction pour allouer de la mémoire : matrice =(int **) malloc( 3 * sizeof(int*));
calloc(). Voici sa signature : if( matrice == NULL )
{
void * calloc (size_t n, size_t t) fprintf(stderr,"Allocation impossible");
La fonction alloue n blocs de taille t. elle est donc exit(EXIT_FAILURE);
presque équivalente à l'appel suivant : }
for( i = 0 ; i < 3 ; i++ )
malloc( n * t ); {
La seule différence réside dans le contenu des cases qui matrice[i] = (int *)calloc (3, sizeof(int));
sont allouée. En effet, avec malloc(), le contenu est
totalement aléatoire tandis qu'avec calloc, les cases if( matrice[i] == NULL )
{
contiennent des valeurs nulles (tous les bits du bloc
fprintf(stderr,"Allocation impossible");
alloué sont mis à 0). Ceci est très utile pour initialiser
exit(EXIT_FAILURE);
rapidement un tableau de nombre. Si ce n'est ce point }
de détail, il n'y a aucune autre différence, et nous }
pourrons donc écrire un exemple d’allocation de la /* remplissage */
façon suivante : for( i = 0 ; i<3 ; i++ )
matrice[i][i] = 1;
PROGRAMMATION 104
104 EN LANGAGE C
LES CHAINES DE CARACTÈRES
Déclaration Mémorisation
Déclaration de chaînes de caractères en C Mémorisation
char <NomVariable> [<Longueur>]; Le nom d'une chaîne est le représentant de l'adresse du
Exemples premier caractère de la chaîne. Pour mémoriser une
char NOM [20]; variable qui doit être capable de contenir un texte de N
char PRENOM [20]; caractères, nous avons besoin de N+1 octets en mémoire:
char PHRASE [300]; Exemple: Mémorisation d'un tableau
Espace à réserver char TXT[10] = "BONJOUR !";
Lors de la déclaration, nous devons indiquer l'espace à
réserver en mémoire pour le stockage de la chaîne.
La représentation interne d'une chaîne de caractères Observation
est terminée par le symbole '\0' (NUL). Ainsi, pour un Pour la mémorisation de la chaîne de caractères "Hello",
texte de n caractères, nous devons prévoir n+1 octets. nous avons besoin de six (!!) octets.
Malheureusement, le compilateur C ne contrôle pas si 'x' est un caractère constant, qui a une valeur numérique:
nous avons réservé un octet pour le symbole de fin de
P.ex: 'x' a la valeur 120 dans le code ASCII.
chaîne; l'erreur se fera seulement remarquer lors de
l'exécution du programme ... "x" est un tableau de caractères qui contient deux
caractères: la lettre 'x' et le caractère NUL: '\0'
'x' est codé dans un octet
"x" est codé dans deux octets PROGRAMMATION 105
105 EN LANGAGE C
LES CHAINES DE CARACTÈRES
Accès aux éléments d'une chaîne Affichage de chaînes de caractères
L'accès à un élément d'une chaîne de caractères peut printf avec le spécificateur de format %s permet
se faire de la même façon que l'accès à un élément d'intégrer une chaîne de caractères dans une phrase.
d'un tableau. En déclarant une chaîne par: En plus, le spécificateur %s permet l'indication de la
char A[6]; largeur minimale du champ d'affichage. Dans ce champ,
nous avons défini un tableau A avec six éléments, les données sont justifiées à droite. Si on indique une
auxquels on peut accéder par: largeur minimale négative, la chaîne sera justifiée à
A[0], A[1], ... , A[5] gauche. Un nombre suivant un point indique la largeur
maximale pour l'affichage.
Exemple
Exemples
char NOM[] = "hello, world";
printf(":%s:", NOM); -> :hello, world:
printf(":%5s:", NOM); -> :hello, world:
printf(":%15s:", NOM); -> : hello, world:
printf(":%-15s:", NOM); -> :hello, world :
printf(":%.5s:", NOM); -> :hello:

PROGRAMMATION 106
106 EN LANGAGE C
LES CHAINES DE CARACTÈRES
Lecture de chaînes de caractères Lecture avec gets
scanf avec le spécificateur %s permet de lire un mot isolé à - La fonction scanf avec plusieurs arguments présuppose
l'intérieur d'une suite de données du même ou d'un autre que l'utilisateur connaisse exactement le nombre et l'ordre
type. des données à introduire! Ainsi, l'utilisation de scanf pour
Effet: scanf avec le spécificateur %s lit un mot du fichier la lecture de chaînes de caractères est seulement
d'entrée standard stdin et le mémorise à l'adresse qui est conseillée si on est forcé de lire un nombre fixé de mots en
associée à %s. une fois.
Exemple gets est idéal pour lire une ou plusieurs lignes de texte (p.ex.
char LIEU[25]; des phrases) terminées par un retour à la ligne.
int JOUR, MOIS, ANNEE; Syntaxe:
printf("Entrez lieu et date de naissance : \n");
gets( <Chaîne> )
scanf("%s %d %d %d", LIEU, &JOUR, &MOIS, &ANNEE);
Remarques importantes Effet:
- La fonction scanf a besoin des adresses de ses arguments: gets lit une ligne de de caractères de stdin et la copie à
l'adresse indiquée par <Chaîne>. Le retour à la ligne final est
* Les noms des variables numériques (int, char, long, float, remplacé par le symbole de fin de chaîne '\0'.
...) doivent être marqués par le symbole '&’.
Exemple
* Comme le nom d'une chaîne de caractères est le
int MAXI = 1000;
représentant de l'adresse du premier caractère de la
char LIGNE[MAXI];
chaîne, il ne doit pas être précédé de l'opérateur adresse '&'
gets(LIGNE);
! PROGRAMMATION 107
107 EN LANGAGE C
LES CHAINES DE CARACTÈRES
La bibliothèque <string> Quelques fonctions
La bibliothèque <string> fournit une multitude de Fonctions pour le traitement de chaînes de caractères
fonctions pratiques pour le traitement de chaînes de strlen(<s>)
caractères. Voici une brève description des fonctions fournit la longueur de la chaîne sans compter le '\0' final
les plus fréquemment utilisées. strcpy(<s>, <t>)
Dans les prototypes de fonctions ci-contre, <n> copie <t> vers <s>
représente un nombre du type int. Les symboles <s> et strcat(<s>, <t>)
<t> peuvent être remplacés par :
ajoute <t> à la fin de <s>
 une chaîne de caractères constante strcmp(<s>, <t>)
 le nom d'une variable déclarée comme tableau de compare <s> et <t> lexicographiquement et fournit un
char résultat:
 un pointeur sur char
 négatif si <s> précède <t>
 zéro si <s> est égal à <t>
 positif si <s> suit <t>
strncpy(<s>, <t>, <n>)
copie au plus <n> caractères de <t> vers <s>
strncat(<s>, <t>, <n>)
ajoute au plus <n> caractères de <t> à la fin de <s>
PROGRAMMATION 108
108 EN LANGAGE C
LES STRUCTURES EN LANGAGE C
Introduction Définir une structure
Les types utilisés dans le langage C sont : Une définition de structure commence par le mot-clé
 les types standards existant : int, float, double,… struct, suivi du nom de votre structure. Ensuite entre
 les types utilisateurs accolade nous mettons les champs de cette structure (les
variables composantes) qui peuvent être de différents types.
 définis par le développeur
Exemple:
 utilisés comme des types standards
struct NomDeVotreStructure
Le langage C vous permet de créer vos propres types {
de variables. Des « types de variables personnalisés » à int variable1;
travers les structures. int variable2;
Une structure est un assemblage de variables qui int autreVariable;
peuvent avoir différents types. Contrairement aux double nombreDecimal;
tableaux qui vous obligent à utiliser le même type dans };
tout le tableau, vous pouvez créer une structure
comportant des variables de types long, char, int et
double sous leurs différents aspects à la fois (simple
variable, tableau, pointeur).

PROGRAMMATION 109
109 EN LANGAGE C
LES STRUCTURES EN LANGAGE C
Définition d'une variable structurée Exemple
C’est une opération qui consiste à créer une variable Soit la structure Personne :
ayant comme type celui d'une structure que l'on a struct Personne{
précédemment déclarée, c'est-à-dire la nommer et lui int Age;
réserver un emplacement en mémoire.
char Sexe;
La définition d'une variable structurée se fait comme
};
suit :
struct Nom_Structure Nom_Variable_Structuree;
Nom_Structure représente le nom d'une structure que Attention : le point-virgule est nécessaire après
l'on aura préalablement déclarée. l'accolade fermante de la déclaration de la structure.
Nom_Variable_Structuree est le nom que l'on donne à
la variable structurée. On peut définir plusieurs variables structurées :
Il va de soi que, comme dans le cas des variables on struct Personne Meriem, Karim, John;
peut définir plusieurs variables structurées en les
séparant avec des virgules :
struct Nom_Structure Nom1, Nom2, Nom3, ...;

PROGRAMMATION 110
110 EN LANGAGE C
LES STRUCTURES EN LANGAGE C
Accès aux champs d'une variable Tableaux de structures
structurée
Chaque variable de type structure possède des champs Etant donné qu'une structure est composée d'éléments
repérés avec des noms uniques. Toutefois le nom des de taille fixe, il est possible de créer un tableau ne
champs ne suffit pas pour y accéder étant donné qu'ils contenant que des éléments du type d'une structure
n'ont de contexte qu'au sein de la variable structurée... donnée. Il suffit de créer un tableau dont le type est
Pour accéder aux champs d'une structure on utilise celui de la structure et de le repérer par un nom de
l'opérateur de champ (un simple point) placé entre le variable :
nom de la variable structurée que l'on a défini et le struct Nom_Structure
nom du champ : Nom_Tableau[Nb_Elements];
Chaque élément du tableau représente alors une
Nom_Variable.Nom_Champ; structure du type que l'on a défini...
Ainsi, pour affecter des valeurs à la variable Karim Le tableau suivant (nommé Repertoire) pourra par
(variable de type struct Personne définie exemple contenir 8 variables structurées de type struct
précédemment), on pourra écrire : Personne :
struct Personne Repertoire[8];

Karim.Age = 24; De la même façon, il est possible de manipuler des


Karim.Sexe = 'M';
structures dans les fonctions.

PROGRAMMATION 111
111 EN LANGAGE C
Informations complémentaires : Les structures

Déclaration de variable de type structure :


Il existe trois manières de déclarer des variables de type structure en C :

De ces trois méthodes c'est la première qui est recommandée, car elle permet de bien séparer la définition du type
structure de ses utilisations.

112
LES STRUCTURES EN LANGAGE C
Exercice d’application
Enoncé Le programme doit gérer en boucle le menu de choix
Ecrire un programme permettant de : suivant:
Constituer un tableau de 20 Enseignants max(NE_max).
La structure est la suivante : 1- Construction Saisie et affichage
2- et affichage
typedef struct E 3- Modifier et affichage
{ 4- Tri et affichage
char nom_pren[40]; // nom+pren 5- Quitter
char nom[20];
char pren[20];
int NH[NM_max] ;/*NM_max=3 : nbre
d’heures pr NM_max matières*/
}enseignant;

PROGRAMMATION 113
113 EN LANGAGE C
LES FICHIERS
Qu’est ce que c’est qu’un fichier? Fichier séquentiel
les entrées-sorties conversationnelles entre un Dans des fichiers séquentiels, les enregistrements
programme et son utilisateurs ne se limitent pas aux sont mémorisés consécutivement dans l'ordre de
communications entre périphérique habituels : clavier leur entrée et peuvent seulement être lus dans cet
↔ écran. Nous verrons toutefois qu’en C, comme ordre. Si on a besoin d'un enregistrement précis
d’ailleurs dans d’autres langages, tous les dans un fichier séquentiel, il faut lire tous les
périphériques, qu’ils soient d’archivage (disque dur, enregistrements qui le précèdent, en commençant
Usb,….) ou de communication (clavier, écran, par le premier.
imprimante,…), peuvent être considérés comme des Les fichiers séquentiels que nous allons considérer
fichiers. Ainsi, en définitive, les entrées-sorties dans ce cours auront les propriétés suivantes:
conversationnelles apparaîtrons comme un cas  Les fichiers se trouvent ou bien en état d'écriture
particulier de la gestion de fichiers. ou bien en état de lecture; nous ne pouvons pas
On se propose ici d’étudier les fonctions permettant simultanément lire et écrire dans le même fichier.
au programme d’échanger des informations avec des  A un moment donné, on peut uniquement
« fichiers ». Le terme de fichier désigne plutôt un accéder à un seul enregistrement; celui qui se
ensemble d’informations situé sur une « mémoire de trouve en face de la tête de lecture/écriture.
masse » telle que le disque dur.
 Après chaque accès, la tête de lecture/écriture
est déplacée derrière la donnée lue en dernier
lieu.
PROGRAMMATION 114
114 EN LANGAGE C
LES FICHIERS
Accès aux fichiers séquentiels Le type FILE
Les problèmes traitant des fichiers ont généralement la Pour pouvoir travailler avec un fichier, un
forme suivante: un fichier donné par son nom (et en programme a besoin d'un certain nombre
cas de besoin le chemin d'accès sur le médium de d'informations au sujet du fichier:
stockage) doit être créé, lu ou modifié. La question qui  adresse de la mémoire tampon,
se pose est alors:  position actuelle de la tête de lecture/écriture,
Comment pouvons-nous relier le nom d'un fichier sur  type d'accès au fichier: écriture, lecture, ...
un support externe avec les instructions qui donnent
accès au contenu du fichier ?  état d'erreur,
En résumé, la méthode employée sera la suivante:  ...
Avant de lire ou d'écrire un fichier, l'accès est notifié
par la commande fopen. fopen accepte le nom du Ces informations (dont nous n'aurons pas à nous
fichier (p.ex: "A:\ADRESSES.DAT"), négocie avec le occuper), sont rassemblées dans une structure du
système d'exploitation et fournit un pointeur spécial type spécial FILE. Lorsque nous ouvrons un fichier
qui sera utilisé ensuite lors de l'écriture ou la lecture du avec la commande fopen, le système génère
fichier. Après les traitements, il faut annuler la liaison automatiquement un bloc du type FILE et nous
entre le nom du fichier et le pointeur à l'aide de la fournit son adresse.
commande fclose.
On peut dire aussi qu'entre les événements fopen() et
fclose() le fichier est ouvert. PROGRAMMATION 115
115 EN LANGAGE C
LES FICHIERS
Bibliothèque de gestion Ouvrir et fermer des fichiers
Elle est assurée par la librairie standard <stdio.h> via un Les fichiers sont ouverts avec la fonction fopen.
ensemble de fonctions commençant par ‘f’. Ils sont fermés avec la fonction fclose.
 Avant de manipuler un fichier, il faut lui associer un Exemple
descripteur (pointeur vers la structure fichier) #include <stdio.h>
 Il y a 3 descripteurs automatiquement ouvert par void main(void)
tout programme C, stdin, stdout et stderr {
 stdin (standard input) est connecté au clavier. On FILE* in;
FILE* out;
peut y lire
FILE* append;
 stdout (standard output) et stderr (standard error) in = fopen("autoexec.bat", "r");
sont reliés au moniteur. On peut y écrire. out = fopen("autoexec.bak", "w");
append = fopen("config.sys", "a");
FILE *f; /* … */
fclose(in);
/*déclare un descripteur f de fichier*/
fclose(out);
fclose(append);
}

PROGRAMMATION 116
116 EN LANGAGE C
LES FICHIERS
Les modes d’ouverture

modes d'ouverture description

"r" lecture seule

"w" écriture seule

"a" mode d'ajout.

"r+" lecture et écriture.

"w+" lecture et écriture, avec


suppression du contenu au
préalable.

PROGRAMMATION 117
117 EN LANGAGE C
LES FICHIERS
Lecture et écriture sur fichier
Les fonctions de lecture:
int fscanf(FILE* stream, const char* format, ...);
int fgetc(FILE* stream);
char* fgets(char* buffer, int size, FILE* stream);

Les fonctions d’écriture:


int fprintf(FILE* stream, const char* format, ...);
int fputc(int ch, FILE* stream);
int fputs(const char* buffer, FILE* stream);

Fonction qui permet de savoir si nous avons atteint la fin d’un fichier :
int feof(FILE *f);
/*renvoie une valeur non nulle si fin de fichier*/

PROGRAMMATION 118
118 EN LANGAGE C
LES FICHIERS
Exemple d’écriture sur fichier Exemple de lecture d’un fichier
#include <stdio.h> #include <stdio.h>
void sauvegarde( char titre[], int n, void main(void)
float x[], int ind [] ) {
{ char titre[81];
int i=0; float x[10];
FILE *f; int ind[10], i=0;
f = fopen(“monfichier.dat”,”w”); FILE *f;
if (f !=NULL){ f = fopen(“monfichier.dat”,”r”);
fprintf(f,”%s\n”,titre); if (f!= NULL) {
for (i=0; i < n; i++ ) { fgets(titre,80,f);
fprintf(f,”%f %d\n”, x[i],ind[i]); while(!feof(f)) {
} fscanf(f,”%f %d”,&x[i],&ind[i]);
} i++;
fclose(f); }
} Mon titre }
fclose(f);
3.0 1 }

4.5 2
7.3 3
PROGRAMMATION 119
119 EN LANGAGE C
LES FICHIERS
Exemple d’illustration
#include <stdio.h>
int main() /* Deuxième partie :
{ Lire et afficher le contenu du fichier */
FILE *P_FICHIER; /* pointeur sur FILE */ P_FICHIER = fopen(NOM_FICHIER, "r"); /* read */
char NOM_FICHIER[30], NOM_PERS[30]; C = 0;
int C,NB_ENREG; while (!feof(P_FICHIER))
/* Première partie : {
Créer et remplir le fichier */ fscanf(P_FICHIER, "%s\n", NOM_PERS);
printf("Entrez le nom du fichier à créer : "); printf("NOM : %s\n", NOM_PERS);
scanf("%s", NOM_FICHIER); C++;
P_FICHIER = fopen(NOM_FICHIER, "w"); /* write }
*/ fclose(P_FICHIER);
printf("Nombre d'enregistrements à créer : "); return 0;
scanf("%d", &NB_ENREG); }
C = 0;
while (C<NB_ENREG)
{
printf("Entrez le nom de la personne : ");
scanf("%s", NOM_PERS);
fprintf(P_FICHIER, "%s\n", NOM_PERS);
C++;
}
fclose(P_FICHIER);
PROGRAMMATION 120
120 EN LANGAGE C
COMPLEXITÉ D’ALGORITHME
La théorie de complexité
La théorie de la complexité algorithmique s’intéresse à Dans les années 1960 et au début des années 1970, on a
l’estimation de l’efficacité des algorithmes. commencé à découvrir des algorithmes fondamentaux . . .
• Elle s’attache à connaître la difficulté d’une réponse • Absence de moyens fiables pour mesurer l’efficacité de
par algorithme à un problème posé de façon ces algorithmes . . .
mathématique. • Par exemple, on se contentait de dire :
Question de base Cet algorithme se déroule en 6 secondes avec un tableau
Entre différents algorithmes réalisant une même de 50 000 entiers choisis au hasard en entrée, sur un
tâche, quel est le plus rapide et dans quelles ordinateur IBM 360/91. Le langage de programmation C
conditions ? a été utilisé avec les optimisations standards.
La théorie de la complexité vise à savoir si la réponse à Une telle démarche rendait difficile la comparaison des
un problème peut être donnée très efficacement, algorithmes entre eux.
efficacement ou au contraire être inatteignable en Une telle mesure est dépendante du :
pratique.  processeur utilisé ;
Elle se fonde sur une estimation théorique des temps  les temps d’accès à la mémoire vive et de masse ;
de calcul et des besoins en mémoire informatique.
 le langage de programmation ;
 le compilateur utilisé ;
 etc.
PROGRAMMATION 121
121 EN LANGAGE C
COMPLEXITÉ D’ALGORITHME
Définition Formalisation mathématique
La complexité d’un algorithme est la mesure du On évalue la complexité d’un algorithme T(n) (le nombre
nombre d’opérations fondamentales qu’il effectue sur de ces opérations élémentaires) en fonction de la taille de
un jeu de données. La complexité est exprimée comme la donnée d’entrée n.
une fonction de la taille du jeu de données. – Si n est la taille de la donnée d’entrée,
• La complexité algorithmique est un moyen – on évalue la complexité de l’algorithme en calculant une
d’évaluation du coût d’un algorithme. fonction T(n).
• Cette complexité mesure le nombre d’opérations
élémentaires et le coût mémoire. Notions
• Cela permet de connaître le type de croissance en Dn l’ensemble des données de taille n ;
fonction de la taille des données.
T(n) le coût de l’algorithme sur la données de taille n.

PROGRAMMATION 122
122 EN LANGAGE C
COMPLEXITÉ D’ALGORITHME
Mesure de complexité
Comment mesurer la complexité (temps d’exécution et
place mémoire) ?
– On suppose que chaque opération de l’algorithme
prend un temps unitaire, on calcule le temps global
pour exécuter l’algorithme, en meilleur cas, en cas
moyen, en pire cas
• La complexité ne nous permet pas de prévoir un
temps d’exécution exact, mais ce qui nous intéresse
c’est l’ordre de grandeur de l’évolution du temps
d’exécution (ou encombrement mémoire) en fonction
d’éléments caractéristiques de l’algorithme (e.g. A compléter …
nombre d’éléments à trier dans un tableau)

PROGRAMMATION 123
123 EN LANGAGE C

Vous aimerez peut-être aussi