Vous êtes sur la page 1sur 37

Universit de Sfax

Ecole Nationale dIngnieurs de Sfax

Notes de cours

Programmation Structure
Langage C avanc

Assist par:
M Moncef Charfi
Moncef.charfi@ieee.org
Mme Boudour AMMAR CHERIF
boudour.ammar@ieee.org

Anne universitaire: 2012/2013

1 Enseignants: Moncef Charfi & Boudour Ammar


Plan du cours

Sommaire
Chapitre 1. Introduction .................................................................................................................................. 3
Environnement de travail .......................................................................................................................... 3
Chapitre 2. Rcursivit .................................................................................................................................... 5
Dfinition: .................................................................................................................................................. 5
Itrativit vs rcursivit: .............................................................................................................................. 5
Dnitions .................................................................................................................................................. 5
Itrativit vs rcursivit: exemple1, PGCD .................................................................................................. 5
Chapitre 3. Pointeurs..................................................................................................................................... 10
1. Rappel sur les tableaux ....................................................................................................................... 10
2. Dfinition des pointeurs ..................................................................................................................... 10
3. Proprits des pointeurs...................................................................................................................... 11
3.1 Pointeurs et tableaux : cas unidimensionnel ................................................................................. 12
3.2 Pointeurs et tableaux : cas multidimensionnel ................................................................................. 12
4. Arithmtique de pointeurs .................................................................................................................. 13
5. Allocation dynamique de mmoire : ................................................................................................... 14
6. Pointeurs sur des fonctions ................................................................................................................. 16
Chapitre 4. Fichiers ....................................................................................................................................... 18
1. Introduction........................................................................................................................................ 18
2. Les fichiers binaires ........................................................................................................................... 21
Chapitre 5. STRUCTURES ET LISTES CHANES ................................................................................. 23
1. Structures ........................................................................................................................................... 23
1.1 Oprations ....................................................................................................................................... 24
2. Listes Chanes .................................................................................................................................. 25
2.1. Listes simplement chanes ............................................................................................................ 26
2.2. Listes doublement chanes ............................................................................................................ 26
2.3 Allocation dynamique ..................................................................................................................... 26
2.4 Listes chanes : Piles ...................................................................................................................... 27
2.5 Listes chanes : Files ...................................................................................................................... 28
Chapitre 7. Compilation Spare .................................................................................................................. 30
1. Dfinition .............................................................................................................................................. 30
1. Motivations ........................................................................................................................................ 30
2. Directives du processeur .................................................................................................................... 31
3. Classes de variables ............................................................................................................................ 32
Chap8. Intraction avec lenvironnement ....................................................................................................... 34
extrieur ........................................................................................................................................................ 34
1. Motivations ........................................................................................................................................ 34
2. Arguments de la ligne de commande .................................................................................................. 34
Bibliographie ................................................................................................................................................ 37

2 Enseignants: Moncef Charfi & Boudour Ammar


Chapitre 1. Introduction

Le Langage C est un des langages de programmation les plus rpandus


Langage principal des sources du noyau UNIX et de tous ses descendants (LINUX, FreeBSD)
Syntaxe combinant la fois simplicit et forte expressivit
Objectif du cours du semestre 1 : introduire le langage et ses constructions de base (itrations,
conditions)
Objectif de ce cours : aborder les constructions avances du langage permettant de concevoir des
programmes complexes

Environnement de travail

Systme dexploitation : GNU/LINUX


Offre gratuitement tous les outils ncessaires pour mener bien le dveloppement dun
programme (diteur, compilateur, dbuggeur, chane de production)
Permet dillustrer plus clairement les diffrentes tapes de la conception dun programme (tout le
processus est contrl par le dveloppeur)
Compilateur: GNU Compiler Collection (GCC)
Compilateur moderne et maintenu trs activement
Supportant un grand nombre de langages de programmation (C, C++, Java, Ada, Fortran)
Libre (openIsource + gratuit)
Disponible sur plusieurs platesIformes (GNU/LINUX, MS Windows, MAC OS X)
Exemple: hello_world en C sous GNU/LINUX.
Fichier hello_world.c :
#include <stdio.h>
int main (void) {
printf ( Hello GNU/LINUX!\n );
return 0;
}
La fonction main doit avoir un retour de type entier
Les arguments de la fonction main sont optionnels
Le '\n' est ncessaire sous GNU/LINUX pour afficher les chanes de caractres
Une instruction return doit clore la fonction main
Compilation depuis un terminal est comme suit:
~% gcc -o hello hello_world.c
hello le nom de lexcutable
La compilation depuis l'diteur geany est:
Commande build/construire (et non pas compile/compiler)

3 Enseignants: Moncef Charfi & Boudour Ammar


Excution dans un terminal :
~% ./hello
Hello GNU/LINUX!
Le prxe ./ (veut dire : excuter ( partir du rpertoire (courant) est recommand pour viter la
recherche dexcutables dans les chemins dexcution par dfaut
Ne jamais appeler un excutable test ou nimporte quel autre nom usuel => risque dtre masqu
par une commande systme dj existante
Ce qui se passe lors dun appel dune fonction modulaire
Lorsquune fonction C est appele, un nouvel espace de mmoire appel pile lui est automatiquement
allou. Il contient :
1. Les paramtres passs la fonction
2. Toutes les variables locales de la fonction (sauf les variables marques par le mot clef static)
3. Des informations permettant de revenir la fonction appelante
Lorsque lexcution dune fonction C est termine, la pile de cette fonction est dtruite automatiquement

Piles : Illustration
int main (void) { / T0 /

f (1, 2); / T1 /
/ T4 /
}
void f (int a, int b) {
int i;
int r;

g (i); / T2 /
/ T3 /
}
void g (int d) {
char c;

}

4 Enseignants: Moncef Charfi & Boudour Ammar


Chapitre 2. Rcursivit
Normalement, un sousprogramme appelle un autre sousprogramme pour lui demander un service.
Mais, peuton imaginer quun sousprogramme sappelle soit mme? Cest le cas des sous-
programmes dits rcursifs.
Dfinition:

Une fonction rcursive est une fonction qui contient, dans ses instructions, au moins un appel elle mme
Appel direct (f appelle f) ou indirect (f appelle g et g appelle f)
La notion de rcursivit existe aussi en mathmatiques. En effet, une formule rcurrente nest autre quune
formule rcursive. Uk = f(Uk1)
Avec une telle formule, on dfinit la valeur de Uk par une fonction Uk1
La rcursivit est un concept trs fort et elle permet de simplifier lcriture de nombreux algorithmes.
Elle nest pas disponible dans tous les langages de programmation. Dans le langage C, il est possible dcrire
des fonctions rcursives.
La rcursivit permet de rpter le mme traitement de la fonction sur un nouvel ensemble dentres
(paramtres, variables locales, chiers). Dans une fonction rcursive, il y a une nouvelle pile alloue pour
chaque nouvel appel de la fonction elle mme
Itrativit vs rcursivit:

Dnitions

Itrativit Rcursivit
Une action spcifie indpendamment de la Une action dont la dfinition dpend de la
fonction appelante est rpte un nombre de fonction appelante est contenue dans celle ci
fois Le nombre de rptitions est gnralement
Le nombre de rptitions est gnralement inconnu ou difficilement dductible des
connu lavance ou bien peut tre dduit paramtres de la fonction
facilement en fonction des paramtres de la Une clause de garde doit exister pour prvenir
fonction contre les appels infinis
Rptition ralise gnralement par Il faut que lalgorithme adopt garantisse
lintermdiaire des boucles (for, while) lutilisation de la clause de garde au bout dun
nombre fini de rcursions
Itrativit vs rcursivit: exemple1, PGCD

Itrativit Rcursivit

5 Enseignants: Moncef Charfi & Boudour Ammar


On suppose que a>=b
On suppose que a>=b Proprit issue de lalgorithme dEuclide:
Algorithme dEuclide: Si b=0 alors PGCD=a
r = a mod b Sinon, PGCD(a,b) = PGCD(b,amodb)
Si r=0 alors PGCD = b int PGCD (int a, int b) {
Sinon, lensemble des diviseurs de a et b est if (b <= 0) {
gal celui de b etr return a;
int PGCD (int a, int b) { }
int r = b; else {
while (r > 0) { return PGCD(b, a % b);
r = a % b; }
a = b; }
b = r; Le test (b <= 0) est la clause de garde. Il
} Permet de prvenir contre les rcursions innies
return a;
}
Laction rptitive consiste remplacer le
couple(a,b) par le couple (b,a modb)
jusqu obtenir lecouple (PGCD,0)

Exemple 2 : La factorielle
Version Itrative Version rcursive
n! = n (n 1) (n 2) 1 n! = n (n 1) (n 2) 1
long fact_iter (long n) { = n ((n 1)!)
long result = 1; long fact_rec (long n) {
long i; if (n <= 1) {
for (i = n; i > 1; i--) { / Clause de garde pour prvenir contre
/ Action rptitive / les rcusions infinies /
result = i; return 1;
} } else {
return result; / Appel rcursif la
} fonction fact
elle mme /
return n fact_rec (n - 1);

6 Enseignants: Moncef Charfi & Boudour Ammar


}

Exemple 3 : La suite de bonacci


F (0) = 0, F (1) = 1
F (n) = F (n 1) + F (n 2) pour tout n > 1
Rcursivit multiple
Version itrative Version rcursive
long fibo_iter (long n) { F (0) = 0, F (1) = 1
long f_n_2 = 0; F (n) = F (n 1) + F (n 2) pour tout n > 1
long f_n_1 = 1; long fibo_rec (long n) {
long temp = f_n_1; if (n == 0) {
long i; / 1re clause de garde /
if (n == 0) {return 0;} return 0;
for (i = 2; i <= n; i ++) { } else if (n == 1) {
temp = f_n_2 + f_n_1; / 2eme clause de garde /
f_n_2 = f_n_1; return 1;
f_n_1 = temp; } else {
} / 2 niveaux de rcursion /
return f_n_1; return fibo_rec (n - 1)
} + fibo_rec (n - 2);
}
}

Ajout dune fonction main et du mcanisme dentres sorties


#include <stdio.h>
/ Dfinitions des fonctions fibo_iter et fibo_rec /
int main (void) {
long n;
printf ("Donner un entier positif ou nul: ");
scanf ("%ld", &n); /* Lecture du type long * /
printf ("F (%ld) est gal %ld\n", n, fibo_iter (n));
printf ("F (%ld) est gal %ld\n", n, fibo_rec (n));
return 0;
}
Rcursivit mutuelle
7 Enseignants: Moncef Charfi & Boudour Ammar
Dnition: On parle de rcursivit mutuelle entre deux fonctions f et g lorsque f contient au moins un appel
g et g contient au moins un appel f
Cette dnition peut tre gnralise un ensemble de fonctions
f1, f2, , fn (f1 appelle f2, f2 appelle f3, et fn appelle f1)
Exemple classique : le test de parit
int pair (int n) { int impair (int n) {
if (n == 0) { if (n == 0) {
return 1; return 0;
} else { } else {
return impair (n - 1); return pair (n - 1);
} }
} }

Rcursivit mutuelle : mise en marche


Puisque les deux fonctions pair et impair sappellent mutuellement, on doit utiliser les dclarations de
fonctions C.
#include <stdio.h>
int pair (int ); / Dclaration /
int impair (int ); / Dclaration /
int main (void) {
int n;
printf ("Donner un entier positif ou nul : ");
scanf ("%d", &n);
printf ("%d pair : %d\n", n, pair (n));
printf ("%d impair : %d\n", n, impair (n));
return 0;
}
Rcursivit imbrique
Dnition: On parle de rcursivit imbrique dans une fonction f quand celle-ci contient au moins une
composition dappels elle mme
utiliser avec prcaution car lvolution de ce genre de fonctions est trs difficile contrler
Exemple classique: la fonction 91 de McCarthy
M(n) = 91 pour tout n 100
M(n) = n 10 pour n 101
int mc_91 (int n) {
if (n > 100) {
8 Enseignants: Moncef Charfi & Boudour Ammar
return n - 10;
} else {
return mc_91 (mc_91 (n + 11));
}
}
Rcursivit imbrique : mise en marche
#include <stdio.h>
int mc_91 (int n) {
if (n > 100) {
printf ("%d > 100, rsultat = %d\n", n, n - 10); /* Trace */
return n - 10;
} else {
printf ("%d <= 100, calcul de mc_91 (mc_91 (%d))\n", n, n + 11);
/* Trace */
return mc_91 (mc_91 (n + 11));
}
}
int main (void) {
int n;
printf ("Donner un entier positif ou nul : ");
scanf ("%d", &n);
printf ("McCathy_91 (%d) = %d\n", n, mc_91 (n));
return 0;
}
Exercice: Montrer que mc_91(n)=91 pour tout n<=100.

9 Enseignants: Moncef Charfi & Boudour Ammar


Chapitre 3. Pointeurs

1. Rappel sur les tableaux

Ds sa dclaration, la taille dun tableau est fige. Lexpression donne entre [] doit tre statique pour pouvoir
tre dduite la compilation.
Exemples de dclarations: lesquels sont interdites ?

int tab [3];

int tab2 [4 * 5];

#define TAILLE 3

int tab [TAILLE];

Exemples de dclarations interdites :


int i = 5;

int tab [i]; /* Interdit par le standard ANSI C */

Problme :
Cette manire de dclarer les tableaux les rend non flexibles et empche de changer leur taille
pendant lexcution du programme

Solutions: utilisation des pointeurs

2. Dfinition des pointeurs

Prliminaires
La mmoire dun ordinateur est divise en plusieurs parties appeles mots
Chacun de ces mots possde une adresse unique
Le mot estla plus petite entit adressable de la mmoire
Toutes les donnes et les instructions dun programme sont stockes dans
des mots
Dfinition:
"Un pointeur en C est une variable dont le contenu est ladresse du premier mot occup par une autre
variable"
La dclaration dun pointeur doit prciser le type point :
int *ptr_1; /* Loprateur * indique quil sagit dun pointeur */

char *ptr_2; /* Pointeur sur un caractre */

10 Enseignants: Moncef Charfi & Boudour Ammar


3. Proprits des pointeurs

Loprateur unaire & permet dobtenir les adresses des variables:


int a = 5; /* Dclaration dun entier */
int *ptr_a = &a; /* ptr_a contient ladresse de a */
int b = *ptr_a; /* Dclaration dun deuxime entier b et initialisation de b avec le contenu adress par ptr_a,
cest dire la valeur de a. Donc, b est gal 5 */

Un pointeur qui ne pointe sur aucune adresse est un pointeur nul:


ptr_a = NULL; /* ptr_a ne pointe nulle part */
NULL est une constante dclare dans <stdlib.h>
Loprateur unaire * constitue la rciproque de loprateur &.
Il permet daccder au contenu point par un pointeur (drfrencement)
& sapplique uniquement aux variables

* sapplique uniquement aux pointeurs


Les pointeurs sont des variables particulires => on peut connatre ladresse dun pointeur en utilisant
&.
&ptr dsigne ladresse de la variable pointeur ptr
int **ptr_ptr; /* Pointeur sur un pointeur sur un entier */
ptr_ptr = &ptr_a; /* Le contenu de ptr_ptr est ladresse du pointeur ptr_a */
**ptr_ptr = 6; /* Modification de la valeur de a */
printf ("a = %d\", a); /* Affiche "a = 6" */
Exemple1 :
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int a = 1, b = 2; /* Deux variables entires */
int *ptr; /* Un pointeur sur un entier */
int **ptr_ptr; /* Un pointeur sur un pointeur sur un entier */
printf ("01 : a = %d, b = %d, *ptr = %d\n", a, b, *ptr);
ptr = &a; /* ptr pointe vers ladresse mmoire de a */
printf ("02 : a = %d, b = %d, *ptr = %d\n", a, b, *ptr);
b = *ptr; /* b reoit le contenu point par ptr, cest dire la valeur de a */
printf ("03 : a = %d, b = %d, *ptr = %d\n", a, b, *ptr);
*ptr = 5; /* Le contenu point par ptr est modifi, la valeur de a est modifie */
printf ("04 : a = %d, b = %d, *ptr = %d\n", a, b, *ptr);
ptr = &b; /* ptr pointe vers ladresse mmoire de b */
printf ("05 : a = %d, b = %d, *ptr = %d\n", a, b, *ptr);
ptr_ptr = &ptr; /* ptr_ptr pointe vers ladresse de ptr */
11 Enseignants: Moncef Charfi & Boudour Ammar
**ptr_ptr = 6;
/* Le contenu point par le contenu point (2 invocations de loprateur *) par
ptr_ptr est modifi, b = 6 */
printf ("06 : a = %d, b = %d, *ptr = %d\n", a, b, *ptr);
return 0;
}

3.1 Pointeurs et tableaux : cas unidimensionnel


Les pointeurs et les tableaux une dimension sont troitement lis. Leurs reprsentations internes sont
identiques.

int tab [10]; En C, un tableau une dimension


est un pointeur vers son premier lment
int *ptr;
tab et &tab[0] dsignent
int i;
la mme chose: ladresse de
for (i = 0; i < 10; i++) la 1re case du tableau
{tab [i] = i + 100;} tab[0] et *tab dsignent la mme
chose: le contenu de la 1re
ptr = tab; case du tableau
/* Les trois lignes ci-dessous affichent le mme rsultat .
: le contenu de la premire case du tableau tab */
printf ("%d\n", *ptr);
printf ("%d\n", *tab);
printf ("%d\n", tab[0]);

3.2 Pointeurs et tableaux : cas multidimensionnel


Les tableaux multidimensionnels sont stocks en mmoire sous la forme dun tableau
unidimensionnel contenant les lignes lune la suite de lautre

int matrix [40][50]; En rouge


int *ptr;
int i, j;
for (i = 0; i < 40; i++)
{for (j = 0; j < 50; j++)
{matrix [i][j] = i + j + 100;}}
ptr = (int *) matrix; /* Casting */
/* Les 2 lignes ci-dessous affichent le mme rsultat : le
contenu de la 1re case de la 3me ligne de matrix */
Il est fortement dconseill de
12 Enseignants: Moncef Charfi & Boudour Ammar
printf ("%d\n", ptr[100]); manipuler les tableaux
multidimensionnels comme des
printf ("%d\n", matrix [2][0]);
pointeurs simples

4. Arithmtique de pointeurs

On peut ajouter ou retrancher des variables entires des pointeurs


La valeur ajoute ou retranche est multiplie par la taille du type point

Rsultat affich :
long tableau [5] = {13, 34, 67, 45, 98};
*ptr_long = 13
long *ptr_long = tableau;
*(ptr_long + 1) = 34
long *ptr_long2 = ptr_long + 3;
*(ptr_long + 3) = 45
printf ("*ptr_long = %ld\n", *ptr_long);
*tableau = 13
printf ("*(ptr_long + 1) = %ld\n", *(ptr_long + 1));
*(tableau + 1) = 34
printf ("*(ptr_long + 3) = %ld\n", *(ptr_long + 3));
*(tableau + 3) = 45
printf ("*tableau = %ld\n", *tableau);
*ptr_long2 = 45
printf ("*(tableau + 1) = %ld\n", *(tableau + 1));
*(ptr_long2 - 2) = 34
printf ("*(tableau + 3) = %ld\n", *(tableau + 3));
*(ptr_long2 + 1) = 98
printf ("*ptr_long2 = %ld\n", *ptr_long2);
printf ("*(ptr_long2 - 2) = %ld\n", *(ptr_long2 - 2));
printf ("*(ptr_long2 + 1) = %ld\n", *(ptr_long2 + 1));

Le type long est de taille 4 octets. Les ajouts et les soustractions des pointeurs sont donc multiplis par 4
En rouge

tableau [i] est quivalent *(tableau + i)

13 Enseignants: Moncef Charfi & Boudour Ammar


5. Allocation dynamique de mmoire :

Si on veut spcifier la taille des tableaux lexcution du programme, on doit les allouer dynamiquement

On utilise les pointeurs pour allouer dynamiquement les tableaux :


Une dimension => pointeurs simples
Deux dimensions => pointeurs sur pointeurs
Trois dimensions => pointeurs sur pointeurs sur pointeurs
Ainsi de suite

Les pointeurs sur pointeurs permettent de crer des tableaux imbriqus qui sont similaires aux tableaux
multidimensionnels
Deux fonctions clefs (dclares dans stdlib.h) :

malloc: prend en argument un entier reprsentant le nombre doctets


allouer, alloue dynamiquement lespace mmoire correspondant et retourne ladresse du dbut
de lespace allou.
En cas derreur (mmoire insuffisante par exemple), malloc retourne la constante NULL

free: prend en argument une adresse et libre lespace allou par malloc pralablement. La fonction
free ne fait que librer lespace mmoire. Elle ne modifie pas la valeur du pointeur donn en paramtre.

Un oprateur important, sizeof: qui permet de calculer la taille (en octets) dun type C
sizeof (long) vaut 4
sizeof (char) vaut 1
IMPORTANT : il faut toujours vrier que la valeur retourne par malloc est dirente de NULL
avant de poursuivre lexcution du programme
IMPORTANT : il faut toujours affecter NULL tout pointeur que lon vient de dsallouer avec free

Exemple 1 :
Construire un programme qui :
1. Demande lutilisateur de donner la taille dun tableau dentiers
2. Alloue dynamiquement le tableau
3. Demande lutilisateur de donner les lments du tableau et remplit ce dernier
4. Affiche le contenu du tableau
5. Libre lespace mmoire allou dynamiquement
Slt :
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int taille, i, *tab;
printf ("Donner la taille du tableau : ");

14 Enseignants: Moncef Charfi & Boudour Ammar


scanf ("%d", &taille);
tab = (int *) malloc (taille * sizeof (int));
if (tab == NULL)
printf ("Erreur lors de l'allocation\n");
printf ("Donner les lments :\n");
for (i = 0; i < taille; i++)
scanf ("%d", &tab [i]);
printf ("Contenu du tableau : ");
for (i = 0; i < taille; i++)
printf ("%d ", tab [i]);
printf ("\n");
free (tab);
tab = NULL;
return 0;
Exemple 2 :
Ecrire un programme qui:
1. Demande lutilisateur de donner les dimensions dune matrice de short
2. Alloue dynamiquement la matrice
3. Demande lutilisateur de donner les lments de la matrice et la remplit (une entre dutilisateur
par ligne)
4. Affiche le contenu de la matrice dune manire comprhensible
5. Libre tout lespace mmoire allou dynamiquement pour la matrice

Slt :
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int lignes, colonnes, i, j;
short **mat;
printf ("Donner les dimensions de la matrice : ");
scanf ("%d", &lignes);
scanf ("%d", &colonnes);
/* Allocation de la matrice */
mat = (short **) malloc (lignes * sizeof (short *));
if (mat == NULL)
printf ("Erreur lors de l'allocation\n");
/* Allocation des lignes */
for (i = 0; i < lignes; i++) {
mat [i] = (short *) malloc (colonnes * sizeof (short));
15 Enseignants: Moncef Charfi & Boudour Ammar
if (mat [i] == NULL)
printf ("Erreur lors de l'allocation de la ligne %d\n", i);
}
/* Remplissage de la matrice ligne par ligne */
printf ("Remplissage de la matrice :\n");
for (i = 0; i < lignes; i++) {
printf ("Donner les lments de la ligne %d :\n", i);
for (j = 0; j < colonnes; j++)
scanf ("%hd", &mat[i][j]); /* %hd => short */
}
/* Affichage du contenu de la matrice */
printf ("Contenu de la matrice :\n");
for (i = 0; i < lignes; i++) {
for (j = 0; j < colonnes; j++)
printf ("%hd\t", mat[i][j]);
printf ("\n");
}
/* Libration de la mmoire de chaque ligne */
for (i = 0; i < lignes; i++) {
free (mat [i]);
mat [i] = NULL;
}
/* Libration de la mmoire de la matrice */
free (mat);
mat = NULL;
return 0;
}
6. Pointeurs sur des fonctions

Une fonction nest pas une variable, mais il est possible davoir un pointeur sur une fonction
Utilit : construire des programmes gnriques qui peuvent tre paramtrs par plusieurs fonctions

Exemple : un programme de tri gnrique paramtr par une fonction daddition et une fonction de
multiplication

#include <stdio.h> int a, b, r;


#include <stdlib.h> char fonc [15];
int addition (int a, int b) printf ("Donner deux entier : ");
{return a + b;}

16 Enseignants: Moncef Charfi & Boudour Ammar


int multiplication (int a, int b) if (fonc [0] == 'a')
{return a * b;} pointeur_fonc = addition;
int main (void) { else
int (*pointeur_fonc) (int, int); pointeur_fonc = multiplication;
/* Pointeur sur une fonction */ r = (*pointeur_fonc) (a, b);
scanf ("%d %d", &a, &b); /* Appel travers le pointeur */
printf ("Que faire (a/m)? "); printf ("Rsultat = %d\n", r);
scanf ("%s", fonc); return 0;
}

17 Enseignants: Moncef Charfi & Boudour Ammar


Chapitre 4. Fichiers

1. Introduction

Dnition : "Un chier est une suite doctets stocks sur un support de mmoire. Il est caractris par un nom
(chane de caractres) attribu lors de sa cration"
Au niveau C, un chier est un pointeur sur la structure FILE dnie dans stdio.h. Cette structure
contient les informations ncessaires pour la manipulation du chier :
Descripteur du chier au niveau systme (gnralement un entier)
Mode douverture du chier (lecture, criture, ajout)
Position courante dans le chier
Etc

Deux fonctions principales (dnies dans stdio.h) pour ouvrir et fermer un chier :
FILE *fopen(const char *nom, const char *mode);

int fclose(FILE *);

Modes possibles d'ouverture :


"r" pour lecture seule
"r+" pour lecture puis criture
"w" pour criture seule (crase le contenu)
"w+" pour criture puis lecture (crase le contenu)
"a" pour ajout (rallongement)
"a+" pour rallongement puis lecture

int fgetc (FILE *pf)


Lit un caractre depuis un chier puis passe lindex du fichier la position suivante
Retourne la constante EOFsi la fin du fichier est rencontre
Possde un alias, getc
char *fgets (char *buffer, int nbr, FILE *pf)
Lit au maximum nbr caractres depuis le chier pf
Sarrte quand un '\n'est rencontr
Les caractres lus sont placs dans bufferet la valeur de ce mme bufferest retourne par la fonction
Retourne NULLdans le cas dune n de chier
int fscanf (FILE*,char *,liste darguments)
quivalent de scanf, mais rcupre son entre depuis un chier
int fputc(int c,FILE *pf)
crit un caractre dans la position courante dun chier
Possde un alias, putc

18 Enseignants: Moncef Charfi & Boudour Ammar


int fputs(const char *buffer,FILE *pf)
crit la chane de caractres bufferdans le chier pf
Ne copie pas le caractre '\0'de n de chane
int fprintf (FILE *, char *,liste darguments)
quivalent de printf, mais crit dans un chier

Exemple :

int main (void) {FILE *le_fichier; char buffer [101]; int i;

le_fichier = fopen ("exemple.fich", "w"); /* criture seule */


fprintf (le_fichier, "Premire ligne : commentaire\n");
fprintf (le_fichier, "%d\n", 2);
fputc ('Y', le_fichier); fputc ('\n', le_fichier); fclose
(le_fichier);

le_fichier = fopen ("exemple.fich", "r"); /* Lecture seule */


fgets (buffer, 100, le_fichier); printf ("Ligne lue : %s", buffer);
fscanf (le_fichier, "%d", &i); printf ("Entier lu : %d\n", i);
i = fgetc (le_fichier); /* '\n' */
i = fgetc (le_fichier);
printf ("Caractre lu : '%c'\n", i);
fclose (le_fichier);

return 0;
}

Exercice2 : Saisie de notes

Construire un programme qui :


Demande le nombre total d'lves
demande la saisie des noms et des notes dun nombre dlves
Stocke dans un chier les noms et les notes, sous la forme dun nombre rel deux chi res
aprs la virgule
Lit nouveau le chier et affiche son contenu sous une forme comprhensible

Le format du chier de stockage est le suivant

Ligne 1 : commentaire ignorer Ligne 2 : nombre dlves (entier) Nom de llve 1


Note de llve 1 (rel)
Nom de llve 2
Note de llve 2 (rel)

Nom de llve n
Note de llve n (rel)

Exemple :
19 Enseignants: Moncef Charfi & Boudour Ammar
Exemple de fiche de notes :
3
Ali
10.50
Ahmed
20.00
Amel
13.00

typedef struct { char nom [20]; float


note;
} EleveNote;

void afficher (EleveNote en) {


printf ("\tNom : %s\n" "\tNote : %5.2f\n", en.nom,
en.note);}
/* Affiche la note dun lve */

void remplir_fichier
(int n, /* Nombre dlves */ EleveNote *liste, /*
Tableau */ FILE *fic);
/* Remplit le fichier fic avec n couples (nom, note)
extraits du tableau liste */

int lire_fichier
(int n, EleveNote *liste, FILE *fic);
/* Remplit le tableau liste avec le contenu du fichier fic
et retourne le nombre de couples insrs */

int main (void) {

int n_eleves, i;
EleveNote en, *listeEleves, *autreListe; char
nomFichier [] = "resultat.fich"; FILE *fic;

/* Rcupration du nombre d'lves */


printf ("Nombre d'lves : ");
scanf ("%d", &n_eleves);

listeEleves = /* */
/* Remplissage du tableau */
for (i = 0; i < n_eleves; i++) {/* */}

20 Enseignants: Moncef Charfi & Boudour Ammar


/* Remplissage du fichier */
fic = fopen (nomFichier, "w");
/* */
fclose (fic);

/* Lecture du fichier nouveau + aff */


fic = fopen (nomFichier, "r");
/* */
fclose (fic);
return 0;
}
2. Les fichiers binaires

Contrairement aux fonctions dj vues (fscanf, fprintf) les deux fonctions ci-- dessous permettent de
lire et dcrire nimporte quel type de donne sans format et sous la forme avec la quelle il est
prsent en mmoire :
size_t fread(void *ptr, size_t t, size_t n,FILE *pf)
Lit, depuis le chier pf, au plus nlments de taille t
Stocke les lments lus dans le tableau ptr(doit tre dj allou)
Retourne le nombre dlments effectivement lus ou bien 0 si la n de
chier est rencontre
size_t fwrite(const void *ptr, size_t t, size_t n, FILE *pf)
crit, dans le chier pf, n lments de taille t issus du tableau ptr
Retourne le nombre dlments effectivement crits
La manipulation de fichiers binaires permet souvent (mais pas toujours) davoir des tailles plus
petites.
Mais elle ne garantit pas la portabilit des fichiers entre les diffrentes plates--formes (systmes
dexploitation, matriel)
utiliser avec prcaution

Exercice: fichier binaire

Ecrire deux fonctions remplir_fichier_b et lire_fichier_bqui effectuent le mme travail que


rempir_fichieret lire_fichieren utilisant les chiers binaires
Les deux fonctions doivent grer les cas derreur dcriture ou de lecture
Tester le fonctionnement de remplir_fichier_bet de lire_fichier_bdans le programme
principal de saisie de notes
Comparer la taille du fichier texte et du fichier binaire et essayer de trouver une
justification
La commande UNIX 'du -b fichier_1 fichier_2 ' permet de donner, en octets, les
tailles des fichiers passs en paramtre

21 Enseignants: Moncef Charfi & Boudour Ammar


Il existe des fonctions qui permettent daccder, en lecture ou en criture, la position du curseur
dans un chier :

int fseek (FILE *pf, long decalage, int a_partir_de)


xe lindicateur de position du chier pf "O+ decalage"

Si a_partir_de vaut SEEK_SET, SEEK_CUR ou SEEK_END, Ovaut

respectivement, le dbut, la position courante ou la n du chier pf


long ftell(FILE *pf)
Indique la position courante dans le chier pf
void rewind(FILE *pf)
Place lindicateur de position au tout dbut du chier pf
int fgetpos (FILE *pf, fpos_t *pos)

Enregistre, dans lendroit point par pos, la valeur de lindicateur de

position du chier pf
int fsetpos (FILE *pf, pos_t *pos)

Fixe la valeur de lindicateur de position du chier pf la valeur pointe par

pos.
int feof (FILE* pf)

Retourne une valeur non nulle si lindicateur de position a aaeint la n du

chier, et 0sinon.

22 Enseignants: Moncef Charfi & Boudour Ammar


Chapitre 5. STRUCTURES ET LISTES
CHANES
1. Structures

Dfinition : Une structure est un type compos de plusieurs lments (membres) de diffrents types
(entiers, tableaux, pointeurs, autre structure).
La structure possde un nom
Chacun des membres possde un nom et un type

Syntaxe : dfinition dune structure

struct nom_du_type { type_1 membre_1; type_2 membre_2;


type_n membre_n;

};
Exemple :
struct point3D {
float x; float y; float z;
};
Syntaxe : dclaration dune variable structure

struct nom_du_type nom_de_la_variable;


Exemple :
struct point3D unPoint = {0.0, 1.5, 3.0};

Les membres dune structure peuvent avoir nimporte quel type C, pourvu que sa taille puisse
tre calcule la compilation :
Types simples (int, char)
Tableaux (int [10], char [10000][5000])
Autres structures
Pointeurs
Un membre dune structure ne peut pas tre :
De type void(mais peut tre de type void*)
Du mme type de la structure elle mme (mais peut tre un pointeur sur la structure elle mme)
Une fonction (mais peut tre un pointeur sur une fonction)
Exercice

Une personne est caractrise par les informations suivantes :


nom : pour des raisons de simplicit nous allons nous restreindre au prnom de la
personne.
sexe : masculin ou fminin
date de naissance : une structure de 3 entiers

23 Enseignants: Moncef Charfi & Boudour Ammar


tat civil : clibataire, mari
conjoint dans le cas o elle est marie
descendants dans le cas o elle en a.

struct date { short jour; short mois; int annee;};

enum civilite {celibataire, marie, veuf, divorce};

struct personne {
char nom [10];
char gendre; /* M ou F */ struct date naissance; enum civilite etat_civil;
struct personne *conjoint;

struct personne **descendants;


/* Tableau de pointeurs sur personne */
};

1.1 Oprations
Les seuls oprateurs que lon peut appliquer sur les structures sont :
-= pour affecter une constante ou copier le contenu dune autre structure

-& pour obtenir ladresse mmoire dune structure

-sizeof pour obtenir la taille dune structure

Exemples :
Struct date d1 = {1, 1, 2009}, d2, *ptr_d;
Long i, j;
ptr_d = &d;
d2 = d1;
i = sizeof (struct date) ;
j = sizeof (struct d2) ;

Il est interdit de comparer des structures


if (s1 != s2)est un test illgal.
Tout comme pour les autres types en C, on peut utiliser des pointeurs sur des structures.
La syntaxe est exactement la mme.
On peut allouer dynamiquement des structures en utilisant mallocet sizeof.

Exemple :
Struct personne *ptr_p;
ptr_p = (struct personne*) malloc (sizeof (struct personne));

On peut allouer des tableaux de structures ou des tableaux de pointeurs sur des structures.
Exemple :
Struct personne *tab_personne;
Struct personne **tab_pointeurs_personne;
tab_personne = (struct personne*) malloc (10 * sizeof (struct personne));
24 Enseignants: Moncef Charfi & Boudour Ammar
tab_pointeurs_personne = (struct personne**) malloc (15 * sizeof (struct personne*));

Pour accder aux membres dune structure, on utilise les oprateurs :


. si la variable est de type structure

-> si la variable est de type pointeur sur une structure

Exemples

struct personne epoux, epouse; epoux.nom = Ali; epoux.naissance.jour = 24;


epouse.nom = Lilia; epouse.naissance.jour = 15; epoux.conjoint = &epouse;
(epoux.conjoint) -> conjoint = &epoux;
printf (Nom de lpoux : %s\n, epoux.nom);
Printf (Nom de lpouse : %s\n, (epoux.conjoint) -> nom); /* ou bien */
Printf (Nom de lpouse : %s\n, (*epoux.conjoint).nom); /* ou bien */
Printf (Nom de lpouse : %s\n, epouse.nom);

structure.membreest quivalent (&structure)->membre.


pointeur_sur_structure->membreest quivalent (*pointeur_sur_structure).membre.

Exercice1
Ecrire un programme en C qui cre larbre familial suivant :
Epoux : Ali, n le 23-09-1955

Epouse : Lilia, ne le 12-07-1960

Fils an : Ahmad, n le 01--02--1982 (clibataire)

Deux jumeaux cadets : Mohamed et Sonia, ns le 30-05-1985 (clibataires)

Ecrire une fonction void afficher_infos (struct personne) qui affiche sous une forme lisible les

informations suivantes sur la personne donne en paramtre :


Nom
Date de naissance
Etat civil
Nom du conjoint (seulement le nom)
Noms des descendants (seulement les noms)
Tester la fonction afficher_infossur les personnes cres.

2. Listes Chanes

Les listes : structures de donnes trs populaires en informatique (stockage dinformation, files
dattentes, compilation)
Ensemble dlments de mme type (les nuds de la liste)
Ensemble doprations lmentaires : ajout, suppression, lecture, modification, destruction
Listes simplement chanes : chacun des nuds de la liste contient un lien vers le nud qui le
25 Enseignants: Moncef Charfi & Boudour Ammar
suit.

Listes doublement chanes : chacun des nuds de la liste contient un lien vers le nud suivant et
un lien vers le nud prcdent

2.1. Listes simplement chanes


Exemple : listes de points 2D formant une courbe mise jour continuellement
Typedef struct point2d{
float x;
float y;
struct point2d *suivant;
} Point2D;

typedef struct { Point2D *debut; Point2D *fin;

} Courbe2D;

2.2. Listes doublement chanes


Exemple : listes de commandes robotiques.
typedef struct requete {
char *nom;
struct requete
*suivant;
struct requete
*precedent;
} Requete;

typedef struct { Requete *premiere; Requete *derniere;


} Requetes;

2.3 Allocation dynamique


Pour construire une liste chaine, on utilise lallocation dynamique de mmoire

Exercice : crire un programme qui :


1. Construit une courbe chane de 10 coordonnes alatoires (fonctions creer_pointet
inserer_point)
2. Ache son contenu dune manire lisible (fonctions afficher_pointet afficher_courbe)
3. La vide de son contenu (fonction vider_courbe)

Point2D* creer_point (float x, float y) { Point2D *result = (Point2D *) malloc


(sizeof (Point2D)));
26 Enseignants: Moncef Charfi & Boudour Ammar
if (result == NULL)
printf ("Erreur d'allocation mmoire\n");
result->x = x;
result->y = y;
result->suivant = NULL;
return result;
}
void inserer_point (Point2D *p, Courbe2D *c) { Point2D *dernier;
if (c->fin == NULL)
c->debut = p;
else
c->fin->suivant = p;
dernier = p;
while (dernier != NULL) {
c->fin = dernier;
dernier = dernier->suivant;}
}

2.4 Listes chanes : Piles

Dnition : la pile est une liste chane dans laquelle tout ajout ou suppression dlments
seffectue au niveau dune seule extrmit appel le dessus ou la tte de la pile.

Modle LIFO (Last In First Out) ou encore dernier arriv, premier servi
Exemple dutilisation : valuation des expressions mathmatiques
Oprations :
Empiler : ajouter un nouvel lment la tte de la pile
Dpiler : retirer le dernier lment ajout la tte de la pile
Consulter : lire le dernier lment ajout la tte de la pile sans le retirer.
Exercice : construire un programme implantant une pile dentiers et permettant dillustrer les oprations
dempilage et de dpilage.

typedef struct pileentiers {


int donnee;
struct pileentiers *suivant;
} PileEntiers;

PileEntiers *empiler (int a, PileEntiers* p)


{}
PileEntiers *depiler (PileEntiers *p)
{ }
int consulter (PileEntiers *p)
{ }
void desallouer (PileEntiers *p)
{}
void afficher_contenu (PileEntiers *p)
{}

int main (void) { int donnee; PileEntiers *pile; char c [2];


pile = NULL; /* IMPORTANT */
27 Enseignants: Moncef Charfi & Boudour Ammar
/* Remplissage de la pile */
printf ("Remplissage de la pile :\n");
do {
/* */
printf ("Ajouter d'autres entiers?(o/n) ");
scanf ("%s", c);
} while (c [0] != 'n');

/* Affichage du contenu de la pile */


afficher_contenu (pile);

/* Suppression de quelques lments */


printf ("Suppression :\n");
while ((printf ("Dpiler un lement? (o/n) ")
&& scanf ("%s", c)) && c [0] != 'n') {
/* */
}

/* Affichage du contenu de la pile */


afficher_contenu (pile);
/* Libration de la mmoire */ desallouer (pile); pile = NULL;
affichage_contenu (pile);
return 0;
}

2.5 Listes chanes : Files


Dnition : la le est une liste chane o les lments sont insrs la n (queue) et supprims au
dbut (tte).
Modle FIFO (First In First Out) ou encore premier arriv, premier servi
Exemple dutilisation : rception des messages depuis le rseau (le dattente)
Oprations :

Enler : ajouter un nouvel lment la queue de la le


Dler : retirer un lment de la tte de la le (llment le plus ancien)
Consulter : lire llment la tte de la le sans le retirer.

Exercice : construire un programme implantant une le dentiers et permettant dillustrer les oprations
dajout et de suppression.
typedef struct noeud {
int donnee;
struct noeud *suivant;
} Noeud;

Typedef struct fileentiers {


Nud *debut;
Nud *fin;
} FileEntiers;

28 Enseignants: Moncef Charfi & Boudour Ammar


void enfiler (int a, FileEntiers *f) { }
void defiler (FileEntiers *f) {
} int consulter (FileEntiers
*f) { } void desallouer
(FileEntiers *f) { }
void afficher_contenu (FileEntiers *f) { }
int main (void) {
int donnee; FileEntiers *file; char c[2];
file = (FileEntiers *) malloc (sizeof (FileEntiers));
file->debut = NULL; /* IMPORTANT */
file->fin = NULL; /* IMPORTANT */

/* Remplissage de la file */
printf ("Remplissage de la file :\n");
do {
/* complter */
printf ("Ajouter d'autres entiers? (o/n) "); scanf ("%s", c);
} while (c [0] != 'n');

/* Affichage du contenu de la file. complter */

/* Suppression de quelques lments */


printf ("Suppression de quelques lments de la file :\n");
while ((printf ("Dfiler un lement? (o/n) ") && scanf ("%s", c)) && c [0] != 'n') {
/* complter */
}

/* Affichage du contenu de la file. complter */


/* Dsallocation. complter */
return 0;
}

29 Enseignants: Moncef Charfi & Boudour Ammar


Chapitre 7. Compilation Spare

1. Dfinition

La compilation spare consiste diviser le code source dun programme sur plusieurs
fichiers

Les dclarations des sous--programmes, des variables globales et les dnitions


des types partags sont crites dans les fichiers dentte (fichiers .h).
Les dfinitions des sous--programmes sont crites dans les fichiers .c.

La diffrentiation entre les fichiers .c et les fichiers .h est une pure convention.
1. Motivations

Un programme est plus lisible si son code est divis sur plusieurs chiers
On peut rassembler certaines fonctions dans des bibliothques logicielles
et les rutiliser dans des programmes dirents

Un programme se prte mieux au dveloppent en quipe si chacun des membres travaille


sur un ensemble indpendant de fichiers
Une premire phase danalyse permet disoler les diffrents modules dun
programme.
Chaque module est form par un couple de fichiers

nom_du_module.h: contient toutes les entits du module qui doivent tre


visibles par au moins un autre module du programme
nom_du_module.c: contient les dfinitions des entits dclares dans
nom_du_module.hainsi que les dclarations et les dfinitions des entits internes au
module lui-mme

Si un module A a besoin de fonctionnalits implantes dans un autre module B, le fichier


A.cdoit contenir une directive
#include "B.h"pour lui permettre de voir les entits de B.
N.B : Noter la prsence de ' "" 'au lieu de '<>'dans la directive

#include pour indiquer linclusion de fichiers non standards.


Il est possible de rassembler les dfinitions de types de donnes dans un chier types .h par
exemple.
Il est aussi possible de crer un chier de conguration qui permet de saffranchir des particularits
du systme dexploitation ainsi que de larchitecture matrielle et de rendre le reste du code portable
(config.h par exemple).

30 Enseignants: Moncef Charfi & Boudour Ammar


Un fichier principal contenant la fonction maindevrait aussi tre cr.
Compilation avec GCC
Chacun des chiers .cdoit tre compil sparment (do le nom de la technique) :
gcc -c nom_du_module.c
Loption c indique que lon veut uniquement produire un chier objet partir du chier .c
(pas d'excutable).
Rsultat sil ny a pas derreur : un chier nom_du_module.o (que lon appelle chier objet)

Lexcutable est construit en rassemblant tous les chiers objets (tape appele dition des
liens) :

gcc -o nom_du_programme fichier_1.o fichier_2.o


Loption -opermet de choisir le nom de lexcutable (sinon, lexcutable sappellera
a.out).

Rsultat sil ny a pas derreur : un chier excutable appel nom_du_programme.

Exemple : Arbre familial

2. Directives du processeur

Avant de compiler un chier source avec GCC (transformer un .cen un .o)


Un prprocesseur est un programme qui procde des transformations sur un code source, avant l'tape
de traduction proprement dite (compilation ou interprtation).

Un prprocesseur analyse les directives #quelquechoseet cre un chier source temporaire qui sera le
vrai fichier tre transform en un .o.
Chaque directive #include <f.h>sera remplace par le contenu du chier .hcorrespondant.

31 Enseignants: Moncef Charfi & Boudour Ammar


Chaque directive #define NOM VALEUR aura leffet de :
1. Marquer la variable Nomcomme dfinie

2. Remplacer toutes les occurrences de NOM dans le fichier source par VALEUR. L ajout dun
paramtre VALEUR est optionnel.
Dans certains cas, on peut se trouver dans la situation o un chier a.h veut voir les entits
dclares dans un autre fichier b.h et que b.h veut, lui aussi, voir les entits de a.h. Il sagit
dinclusion mutuelle.

Problme : ceci va causer une erreur dans le prprocesseur car il va essayer dinclure indfiniment
le contenu des fichiers dentte.
Solution : marquer chaque fichier inclus par une directive de compilation conditionnelle afin
dviter les inclusions multiples.

3. Classes de variables

Dans le chier affichage.h la dclaration de la fonction afficher_info a t prcde par le mot


clef extern. Ceci indique au compilateur que cette fonction existe dans un autre module et
quelle sera trouve lors de ldition des liens.
Il existe plusieurs classes de dclaration :
extern : indique quune fonction ou une variable existe dans un autre module. Une
dclaration prcde de extern ne cause pas la rservation despace mmoire pour
lentit dclare.
static : indique que la dure de vie dune variable est gale celle du programme
mme si cette variable est dclare dans une fonction appele plusieurs fois. Les
variables statiques dclares lintrieur des fonctions sont permanentes mais elles ne
sont visibles que depuis les fonctions o elle sont dclares.
register : indique quune variable locale une fonc4on doit tre place dans
un registre du microprocesseur (tant que cela est possible).
volatile : indique quune variable peut tre modie par un autre programme en arrire
plan. Le compilateur va donc viter toutes les optimisations qui pourraient compromettre
la cohrence de ces modications.
auto : cest la classe de variables par dfaut. Prxer une dclaration de variable par
auto est quivalent une dclaration ordinaire de cette variable. Elle sera alloue dans la
pile de la fonction contenant la dclaration.
Exercice: Piles

32 Enseignants: Moncef Charfi & Boudour Ammar


Rcrire le programme dillustration des piles pour utiliser la compilation spare.
1. Un fichier dentte pour les types de donnes
2. Un module pour les fonctions empiler, depiler, consulter et desallouer
3. Un module pour la fonction afficher_contenu
4. Un module principal pour la fonction main

33 Enseignants: Moncef Charfi & Boudour Ammar


Chap8. Intraction avec lenvironnement
extrieur
1. Motivations

Interaction avec lenvironnement extrieur : rcupration des donnes qui constituent lentre du
programme et/ou production des sorties (donnes, messages, signaux, chiers) qui en
constituent le rsultat.
Un programme qui ninteragit pas avec son environnement extrieur est un programme
inutile.

Dans cette partie du cours, on sintresse aux entres.


Jusque l, les seuls moyens vus pour communiquer les entres un programme
sont :
Les coder en dur dans le code source (valeur dune variable, nom dun chier)

Les demander lutilisateur lors de lexcution des programmes (printf/scanf)


But : pour avoir des programmes plus flexibles et plus conviviaux, il serait bien de pouvoir :

Ne pas intgrer en dur les entres


Trouver un moyen rapide de passer les entres au programme lors de lexcution
Solution :
Le passage des arguments la ligne de commande
2. Arguments de la ligne de commande

Dans la plupart des systmes dexploitation (UNIX, Windows, Mac OS X), il est possible dinvoquer
un excutable avec une liste darguments :
~% executable arg1 arg2 argn
Dans le langage C, il est possible de rcuprer tous les lments de la ligne de commande en
modiant la signature de la fonction main:
int main (int argc, char *argv[])
argcest un entier. Il reprsente le nombre dlments de la ligne de commande en comptant le
nom de lexcutable lui mme.
argvest un tableau de chanes de caractres contenant tous les lements de la ligne de
commande.
Les valeurs de argc et de argvsont spcies par
linterprteur de commandes qui excute le programme.

Exemple : programme listant ses paramtres

int main (int argc, char *argv[]) {


int i;

34 Enseignants: Moncef Charfi & Boudour Ammar


printf ("Nombre d'arguments : %d\n", argc);

for (i = 0; i < argc; i++) {


printf ("Argument N%d = '%s'\n", i, argv[i]);
}
return 0;
}

Exemple dexcution :
~% ./test_ligne_cmd arg1 -3 test dernier
Nombre d'arguments : 5
Argument N0 = './test_ligne_cmd'
Argument N1 = 'arg1'
Argument N2 = '-3'
Argument N3 = 'test'
Argument N4 = 'dernier'

Exercice
Ecrire un programme qui rcupre, sur la ligne de commande, deux chanes de caractre
suivies dun entier strictement positif et qui eectue le traitement suivant :
Interprte la premire chane comme un nom de chier dentre et louvre en lecture.
Interprte la deuxime chane de caractre comme un chier de sortie et louvre en
criture.
Copie le contenu du premier chier dans le second chier autant de fois que le troisime
argument le prcise.
On suppose que :
La longueur maximale des lignes du premier chier est gale 80 caractres
Le programme doit pouvoir signaler les erreurs suivantes :
Nombre incorrect de paramtres de la ligne de commande
Fichier en entre inexistant
Paramtres de type erron (entier ngatif par exemple)

NB: La fonction atoide la bibliothque standard permet de convertir les chanes de caractres en
entiers.

Exercice
Ecrire un programme qui rcupre, sur la ligne de commande, deux chanes de caractre
suivies dun entier strictement positif et qui effectue le traitement suivant :
Interprte la premire chane comme un nom de fichier dentre et louvre en lecture.
Interprte la deuxime chane de caractre comme un fichier de sortie et louvre en
criture.
Copie le contenu du premier fichier dans le second fichier autant de fois que le troisime

35 Enseignants: Moncef Charfi & Boudour Ammar


argument le prcise.
On suppose que :
La longueur maximale des lignes du premier fichier est gale 80 caractres
Le programme doit pouvoir signaler les erreurs suivantes :
Nombre incorrect de paramtres de la ligne de commande
Fichier en entre inexistant
Paramtres de type erron (entier ngatif par exemple)

NB: La fonction atoide la bibliothque standard permet de convertir les chanes de caractres en
entiers.

36 Enseignants: Moncef Charfi & Boudour Ammar


Bibliographie
[1] Bechir Zalila, Programmation structure C avanc , ENIS 2010
[2] Kamel Hamrouni, Algorithmique et Structures de Donnes , ENIT 2011
[3] Kamel Hamrouni, Algorithmes avancs , ESPRIT 2011
[4] Jean-Claude GEORGES, "Algorithmique Pointeurs, listes et arbres", ESIEE IN4A11 2008

37 Enseignants: Moncef Charfi & Boudour Ammar