Cours - Langage C (Suite)
Cours - Langage C (Suite)
Cours - Langage C (Suite)
Objectifs : Proposer une solution logicielle conforme à un cahier des charges simple
Compétences visées :
Contenu :
1- Présentation du langage C
1-1 Historique
Langage de programmation développé en 1970 par Dennie RITCHIE aux laboratoires Bell d’AT&T.
Il fut limité à l’usage interne de Bell jusqu’en 1978 date à laquelle Brian KEKERNIGAN et Dennie
RITCHIE publièrent les spécialisations du langage : « The C programming Language »
De nombreux compilateurs ont été écrits, mais comportant quelques incompatibilités portant
atteinte à l’objectif de portabilité.
1
1-2 Intérêts du langage
- Langage structuré
- Langage évolué qui permet néanmoins d’effectuer des opérations de bas niveau
- Portabilité due à l’emploi de bibliothèques dans lesquelles sont reléguées les fonctionnalités
liées à la machine
-Clarté
-Simplicité
-Modularité
-Extensibilité
-Chiffres 0 à 9
- Caractères spéciaux :
! * + \ ‘’ <
# ( = | { >
% ) ~ ; ] /
^ - [ : , ?
& - } ‘ . (espace)
- backspace (\b)
Identificateur :
Nom donné aux diverses composantes d’un programme ; variables, tableaux, fonctions.
- Formé de lettres et de chiffres ainsi que du caractère_ permettant une grande lisibilité.
2
Le 1er caractère doit obligatoirement être une lettre ou bien le caractère_
- Peut contenir jusqu’à 31 caractères minuscules et majuscules.
- Il est d’usage de réserver les identificateurs entièrement en majuscules aux variables du
préprocesseur.
Exemples :
- Identificateurs valides :
x y12 somme_1 _temperature fin_de_fichier
- Identificateurs invalides :
4eme commence par un chiffre
x #y caractère non autorisé (#)
taux change caractère non autorisé (espace)
const if typedef
do register void
enum signed
Void main ()
3
#include <stdio.h> //inclusion de la bibliothèque standard
Remarques :
La compilation de ce fichier s’effectue à l’aide de la commande cc. Sans autre spécification, cette
commande enchaîne 3 étapes :
- Appel au pré-processeur
- Appel au compilateur
- Appel à l’éditeur de liens
3- Les types de données
Un caractère est considéré comme un entier qu’on pourra donc utiliser dans une expression
arithmétique
4
Remarque :
char x,y,t ;
Constantes symboliques
Exemples :
Utilisation : enum bool v ; /* v est une constante énumérée de type bool qui peut prendre deux
valeurs : false ou true */
5-Les opérateurs
addition -> +
division -> /
multiplication -> *
soustraction -> -
5
modulo (reste de la division entière ) -> %
Différent de -> !=
Egal à -> ==
5-4-L’opérateur d’affectation
Affectation en C -> =
Exemples :
Int x ;
%d -> entier
6
%e -> écriture exponentielle d’un réel
%c -> caractère
Exemples :
int a ;float ;
Application 1 :
#include <stdio.h>
#include<conio.h>
Void main ()
Int L = 10, l = 5 , s;
S= L*l;
Application 2 :
#include<stdio.h>
#include<conio.h>
Void main()
float x,y;
7
printf(‘’Entrer le premier reel:\n’’) ;
scanf(‘’%f’’,&x) ;
scanf(‘’%f’’,&y) ;
getch() ;
Application 3 :
Ecrire un programme qui calcule et affiche la surface d’un cercle de rayon quelconque
#include<stdio.h>
#include<conio.h>
#define pi 3.14
Void main()
clrscr();
float r;
scanf(‘’%f’’,&r) ;
getch() ;
La clause : if (si)
Syntaxe : if(condition)
Instruction ;
8
- Chaque bloc d’instruction doit être délimité par { }
Application :
#include<stdio.h>
#include<conio.h>
Void main()
clrscr();
float a ;
scanf(‘’%f’’,&a) ;
If(a !=0)
If(a==0)
getch() ;
Syntaxe : if(condition)
Instruction 1 ;
Else instruction 2 ;
Application 1
#include<stdio.h>
#include<conio.h>
9
Void main()
clrscr();
float a, b, x;
scanf(‘’%f%f’’,&a,&b) ;
If(a !=0)
x=-b/a;
else //a = 0
If(b!=0)
printf(‘’pas de solution’’);
getch();
Application 2
Ecrire un programme qui lit un entier au clavier et qui teste si cet entier est positif ou négative
#include<stdio.h>
#include<conio.h>
Void main()
clrscr();
10
int n;
Printf(‘’Entrer un entier:’’);
Scanf(‘’%d’’,&n) ;
If(n>=0)
{ test = true;
else
{ test = false ;
getch() ;
Syntaxe : if(cond 1)
Instruction 1 ;
else if (cond 2)
Instruction 2;
else if (cond 3)
Instruction 3;
else if (cond n)
Instruction n;
else instruction;
11
Application
Ecrire un programme qui lit un caractère au clavier et qui teste si c’est une voyelle
#include<stdio.h>
#include<conio.h>
void main()
clrscr();
char x;
printf(‘’Entrer un caractère:\n’’);
scanf(‘’%c’’,&x) ;
getch() ;
Incrémentation
x++ ;//x=x+1
++x ; //x=x+1
Décrémentation
x-- ; //x=x-1
--x ; // x=x-1
Pré-incrémentation
12
x=++a ;// ++a ; puis x=a ;
Remarques :
- ++ est un opérateur de pré-incrémentation lorsqu’il est placé à gauche de la lvalue sur laquelle il
porte
Post-incrémentation
Remarques :
- ++ est un opérateur de post-incrémentation lorsqu’il est placé à droite de la lvalue sur laquelle il
porte
Syntaxe : lvalue = lvalue opérateur expression ; < = > lvalue opérateur = expression ;
Exemples :
X+ = a ; // x = x + a ;
X- = a ; // x = x - a ;
X* = a ; // x = x * a ;
X/ = a ; // x = x / a ;
X% = a ; // x = x % a ;
5-8-L’opérateur séquentiel
Intérêt : permet d’exprimer plusieurs calculs successifs au sein d’une même expression
Par exemple : a*b ; i+j est une expression qui évalue d’abord a*b, puis i+j et qui prend comme valeur
la dernière calculée (donc ici celle de i+j). Certes, dans ce cas, le calcul de a*b est inutile puisqu’il
n’intervient pas dans la valeur de l’expression globale et qu’il ne réalise aucune action .
i++ ; a+b peut présenter un intérêt puisque la première expression (dont la valeur ne sera pas utilisée
) réalise en fait une incrémentation de la variable i
13
L’opérateur sizeof, dont l’emploi ressemble à celui d’une fonction, fournit la taille en octets
Exemple :
Supposons le type int est représenté sur 2 octets et le type double sur 8 octets
int n ;
double z ;
sizeof(n) vaudra 2
sizeof(z) vaudra 8
Intérêt : lorsque l’on souhaite écrire des programmes portables dans lesquels il est nécessaire de
connaître la taille exacte de certains objets
6-Exercices
Exercice 1
Exercice 2
Ecrire un programme qui retourne le maximum et le minimum de trois nombres entiers lus au clavier
Exercice 3
Ecrire un programme qui affiche le message « reçu », « admis aux épreuves orales » ou « ajourné »
selon que la note obtenue est supérieure ou égale à 10, compris entre 8 et 10, ou inférieure à 8
14
Chapitre 2 : Les structures de contrôle
La structure switch permet de faire des choix multiples (uniquement) sur une liste de valeurs
constantes. Elle correspond à une cascade d’instruction if … else .
Switch(expression)
default : instructions;
Si la valeur de l’expression est égale à l’une des constantes, les instructions correspondantes sont
exécutées. Sinon les instructions correspondantes à default sont exécutées
Exemple 1 :
#include<stdio.h>
#include<conio.h>
Void main()
clrscr();
int feu;
printf(“Quel feu:”);
15
scanf(‘’%d’’,&feu) ;
switch(feu)
getch() ;
Exemple 2 :
Ecrire un programme qui demande à l’utilisateur de fournir un nombre compris entre 0 et 3 et qui
l’affiche à l’écran.
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
Int n;
Printf(“saisir le nombre:”);
Scanf(‘’%d ‘’,&n) ;
Switch(n)
16
Printf(‘’fin’’) ;
getch() ;
Exemple 3 :
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
Char oper;
Float a,b;
Scanf(‘’%f%f’’,&a,&b) ;
Scanf(‘’%c’’,&oper) ;
Switch(oper)
Printf(‘’Error’’) ;
} break ;
default : printf
17
getch() ;
while (expression)
instruction ;
Tant que expression est vérifiée, l’instruction est exécutée. Si expression est non vérifiée au départ,
l’instruction ne sera jamais exécutée. L’instruction peut évidemment être une instruction composée.
Exemple 1 :
Ecrire un programme qui affiche les 100 premiers entiers non nuls
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
Int i =1;
While (i<=100)
Printf(“\n i=%d”,i);
I++;
Getch();
Exemple 2 :
#include<stdio.h>
#include<conio.h>
Void main()
18
{
Clrscr();
Int n, som=0;
While(som<100)
Printf(“Donnez un nombre:”);
Scanf(‘’%d”,&n);
Som+=n ;
getch() ;
Il peut arriver que l’on veuille effectuer le test d’arrêt qu’après avoir exécuté l’instruction.
do
Instruction ;
While (expression) ;
Cela signifie répéter l’instruction tant que l’expression est vraie. Ce qui veut dire également que
l’instruction est exécutée au moins une fois
Exemple 1 :
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
19
Int a;
Do
Scanf(‘’%d ‘’,&a) ;
while (a !=482);
getch();
Exemple 2:
Ecrire un programme qui calculi la somme des N premiers entiers non nulls
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
Int som=0;
Int n, i=1;
Printf(“Saisir N”);
Scanf(“%d”,&n);
do
Som+=i ;
i++ ;
While(i<=n) ;
20
printf(“La somme des %d premiers entiers non nulls vaut %d\n”, n, som);
getch() ;
Exemple 3 :
Ecrire un programme qui affiche les 100 premiers entiers par pas de 3
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
do
Printf(“%d\n”,i);
Compt++;
I+=3;
While(compt<=100);
Getch();
Exemple 4:
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
21
Const long int M=100000;
Long int p = 1;
do
Printf(“%ld\n”,p);
p=p*2;
while(p<=M);
getch();
Instruction ;
Exemple :
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
22
Int I;
For(i=0; i<10;i++)
Printf(“\n i=%d”,i);
Getch();
Remarque :
Une boucle for est un cas particulier de la boucle while et donc une version équivalente plus intuitive
de la boucle for est:
Expr1 ;
while(expr2)
instruction ;
Expr3 ;
Exemple :
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
Int I = 0;
While (i<=9)
Printf(“\n I = %d”,i);
I++;
getch();
23
}
Remarque :
Les trios expressions utilisées dans une boucle for peuvent être constituées de plusieurs expressions
séparées par des virgules. Cela permet par exemple de faire plusieurs initialisations à la fois ;
Exemple 1 :
#include<stdio.h>
#include<conio.h>
Void main()
clrscr();
Scanf(“%d”,&n);
Fact*=I;
Printf(“%d!=%d\n”,n,fact);
Getch();
Exemple 2:
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
Int I, cpt;
For(cpt=0,i=0;cpt<=100;i+=4,cpt++)
24
Printf(“%d\n”,i);
Getch();
5-L’instruction break
Exemple :
If(i==2) break;
Boucle for :
6-L’instruction continue
Exemple :
If(i==2) continue;
Printf(“%d fois\n”,i+1);
25
Boucle for : 2 fois
7-L’instruction goto
boucle for :
fin
L’instruction goto est généralement utilisée pour sortir d’une encapsulation de boucle
8-Exercices
Exercice 1
Exercice 2
Un nombre est dit magique lorsqu’il est égal à la somme de ses diviseurs sauf lui -même par exemple :
6 =1 + 2 +3
Exercice 3
26
Ecrire un programme qui affiche les 100 premiers nombres premiers (nombre ayant 2 diviseurs 1 et
lui-même)
Exercice 4
Exercice 5
Exercice 6
Afficher le minimum, le maximum et la moyenne des notes d’une classe de N élèves. N à saisir au
clavier
Exercice 7
Exercice 8
Ecrire un programme qui lit une série de notes au clavier et qui affiche leur moyenne.
Exercice 9
Ecrire un programme de jeu demandant de deviner un nombre entre 0 et 10 choisi par l’ordinateur.
On ne donnera pas d’indications avant la découverte de la solution, où l’on indiquera le nombre
d’essais. La solution sera choisie par l’ordinateur par la fonction rand() qui rend un entier aléatoire
(déclarée dans stdlib.h)
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr() ;
27
{ time_t ; srand((unsigned)time(&t)) ; /* initialiser le générateur à partir du compilateur de temps,
do
nb_essais++ ;
scanf(‘’%d ‘’,&reponse) ;
while(reponse !=solution) ;
Printf(‘’trouvé en %d essais\n’’,nb_essais) ;
getch() ;
Exercice 10
La fonction kbhit teste si un caractère a été frappé au clavier. Tant que ce n’est pas vrai kbhit renvoie
0
Exemple d’utilisation :
Bloc
Ou encore
While ( !kbhit()) // ici c’est pour dire tant que kbhit n’est pas vraie ie renvoie 0
Bloc
28
}
Exercice 11
Ecrire un programme qui affiche le carré des nombres 1, 2, 3,…, toutes les 500 ms tant que aucun
caractère n’ a été frappé au clavier
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
int I,n;
scanf(“%d”,&n);
scanf(‘’%f’’,¬e) ;
Som+=note ;
moy = som/n ;
getch() ;
29
Chapitre 3 : Les Tableaux
1-Définition
Un tableau est une structure de données permettant de stocker plusieurs informations de même
type. Un tableau est caractérisé par sa taille et par ses éléments
Cette déclaration signifie que le compilateur réserve dim places en mémoire pour ranger les
éléments du tableau
Exemples :
Int tab[10] ;
Float nombre[20] ;
Char matrice[30] ;
Utilisation :
Exemple : tab[2]= 5 ;
nombre[i] =6.789 ;
printf(‘’%d’’, tab[i]) ;
scanf(‘’%f’’,&nombre[i]) ;
Application 1
#include<stdio.h>
#include<conio.h>
Void main()
clrscr();
int I, tab[10];
tab[0] = 1;
30
for(i=1;i<10;i++)
tab[i]=2*tab[i-1];
for(i=0;i<10;i++)
printf(‘’%d\t’’,tab[i]) ;
getch();
Application 2
Saisir 10 réels, les ranger dans un tableau. Calculer et afficher la moyenne et l’écart entre note et
moyenne
#include<stdio.h>
#include<conio.h>
#define n 10
Void main()
Clrscr();
int I;
for(i=0;i<n;i++)
Scanf(‘’%f’’,&tab[i]) ;
for(i=0,som=0;i<n;i++)
Som+=tab[i];
moy=som/n;
31
for(i=0 ;i<n ;i++)
getch() ;
Donc :
Tab[0]=0 ;
Tab[1]=1 ;
Tab[2]=0 ;
Tab[3]=0 ;
Remarques :
Autres exemples :
Exemple :
I=ligne
J=colonne
mat[i][j] représente l’élément du tableau mat se trouvant à l’intersection entre la ligne i et la colonne
j
32
Application 1
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
Int mat[4][4], I, j;
For(i=0;i<4;i++)
For(j=0;j<4;j++)
Mat[i][j]=i*j;
printf(‘’%d\t’’, mat[i][j]);
printf(‘’\n”);
getch();
Application 2
33
Exemple :
Application
L M M J V SD
U A E E E A I
N R R U N M M
D D C D D E A
I I R I R D N
E E I C
D D H
I I E
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
int i,j;
printf(‘’%c\t’’, semaine[i][j]);
printf(‘’\n’’);
getch();
34
}
Exercice
#include<stdio.h>
#include<conio.h>
Void main()
Clrscr();
int mat[10][10], I, j;
if((j==0)||(j==i))
mat[i][j]=1;
else
mat[i][j]=mat[i-1][j-1]+mat[i-1][j];
For(j=0;j<=i;j++)
printf(‘’%d\t’’, mat[i][j]);
printf(‘’\n’’);
getch();
Chapitre 4 : L es Pointeurs
35
1- Définition
Un pointeur est une variable destinée à contenir l’adresse mémoire d’une autre variable
Remarques :
Exemple 1
Analyser le programme
Void main()
int i, j, *p ;
i=5 ;
p=&i ;
j=*p ;
*p=j + 2;
Exemple 2
#include <stdio.h>
#include<conio.h>
Void main()
36
{
Clrscr();
x=4 ;
*p = 1 ; // x = 1
getch() ;
Exemple 3
*p1=*p1 + 10 ; // x = 20
4- intérêts
- Le principal intérêt des pointeurs est qu’avec eux, on peut créer des nouvelles variables
indépendantes à tout moment
- Ils permettent de manipuler de façon simple des données pouvant être importantes ( au lieu de
passer à une fonction un élément très grand (taille), on pourra par exemple lui fournir un
pointeur vers cet élément)
- Les tableaux ne permettent de stocker qu’un nombre fixé d’éléments de même type. En stockant
des pointeurs dans les cases d’un tableau, il sera possible de stocker des éléments de taille
diverse, et même de rajouter des éléments au tableau en cours d’utilisation (c’est la notion de
tableau dynamique qui est très étroitement liée à celle de pointeur)
- Il est possible de créer les structures chaînées, c’est-à-dire comportant des maillons
- Incrémentation
float *p , x=3.12 ;
p=&x ;
37
p++ ; // incrémentation
Remarque : l’incrémentation d’un pointeur n’est autorisée que lorsque le pointeur pointe sur un
tableau
Exemple
Int tab[5]={0,0,0,0,0}, *p ;
*p = 1 ; // tab[0]=1
*p=2 ;
*p = 10 ; // tab[2]=10
- Décrémentation
p-- ; // décrémentation
E xemple 1
Exemple 2
Int a[20]={12, 23, 34, 45, 56, 67, 78, 89, 90}, *p ;
P=&a[0] ;
38
1) *p + 2 // a[0] + 2
2) *(p + 2) // a[2]=34
3) &p+1 // case suivante après l’adresse du pointeur
4) &a[4]-3 // &a[1]
5) P+3 // &a[3]
6) &a[7]-p // 7-0=7
7) P + (*p – 10) // &a[2]
8) *[p + *(p + 8) – a[7] ] // a[1]
- Comparaison de deux pointeurs
P1=&tab[0] ;
P2=&tab[9] ;
While(p1<p2)
P1++ ; // incrémentation
0 1 2 3 4 5 6
P1 p2
P2 – p1 = nombre d’élément du type en question situés entre les deux adresses correspondantes
B O N J O u r \o
P1 p2
Char ch[10] = {‘b’, ‘o’, ‘n’, ‘j’, ‘o’, ‘u’, ‘r’, ‘\o’} , *p1, *p2 ;
While(*p2 !=’\o’)
P2++ ; // incrémentation
39
Printf(‘’La longueur de la chaîne est : %p’’, p2 – p1) ;
6-Tableau et pointeur
On peut optimiser l’utilisation des tableaux et pointeurs en utilisant le fait que le nom d’un tableau
est l’adresse de son premier élément.
Exemple
Int t[7], *p ;
t &t[0] *t t[0]
Application 1
#include<stdio.h >
#include<conio.h>
Void main()
clrscr();
int I, t[5];
for(i=0;i<5;i++)
*(t + i) = 1;
for(i=0;i<5;i++)
printf(‘’%d\t’’,t[i]);
printf(‘’\n’’);
getch();
Application 2
40
Ecrire, de deux façons différentes, un programme qui lit 10 nombres entiers dans un tableau avant
d’en rechercher le plus grand et le plus petit :
Résolution
a) le formalisme tableau
#include<stdio.h>
#include<conio.h>
#define m 10
Void main()
Clrscr() ;
scanf(‘’%d’’,&t[i]) ;
max=min=t[0];
for(i=1;i<m;i++)
if(t[i]>max)
max=t[i];
if(t[i]<min)
min=t[i];
getch() ;
41
b) le formalisme pointeur
#include<stdio.h>
#include<conio.h>
#define m 10
Void main()
Clrscr() ;
scanf(‘’%d’’, t + i) ;
max=min=*t;
for(i=1;i<m;i++)
if(*(t + i)>max)
max=*(t + i);
if(*(t + i)<min)
min=*(t + i);
getch() ;
42
Chapitre 5 : Les fonctions
1) Définition
Une fonction est un sous programme qui réalise une action et qui a pour résultat de fournir une
valeur
- Un nom
- Un type
- Paramètres
Void titre()
printf(‘’Bonjour’’) ;
Remarque : le type void est utilisé si la fonction ne retourne aucune valeur. La fonction titre est
appelée par n’importe quelle fonction
Exemple 1 :
#include<stdio.h>
#include<conio.h>
Printf(‘’ Bonjour\n’’) ;
Void main()
43
getch() ;
Exemple 2 :
#include<stdio.h>
#include<conio.h>
Printf(‘’Bonjour\n ‘’) ;
Void coucou()
printf(‘’Coucou\n’’) ;
getch() ;
Exemple :
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int lance()
44
test=random(7);
return(test);
Void main()
int resultat;
randomize(); // initialise avec une valeur aléatoire le générateur interne de nombres aléatoires
resultat = lance() ;
getch() ;
#include<stdio.h>
#include<conio.h>
int carre(int x) // declaration de la fonction
{
45
int r ; // variable locale
r=x*x ;
return (r);
}
Void main ()
{
int n, resultat; // variables locales
printf(‘’Entrer un nombre :’’);
scanf(‘’%d’’,&n) ;
resultat = carre(n) ;
printf(‘’le carré de %d est :%d’’, n, resultat) ;
getch() ;
}
6) Déclaration d’une fonction
----//----
return(expression) ;
Void main()
{
------//----------
}
Exemple :
#include<stdio .h>
#include<conio.h>
46
void main()
clrscr() ;
int x, y ;
scanf(‘’%d%d’’,&x,&y) ;
getch() ;
return(x + y) ;
return(x*y) ;
Les variables locales ne sont pas initialisées (sauf si on le fait dans le programme) et elles perdent
leur valeur à chaque appel à la fonction. On peut allonge r la durée de vie d’une variable locale en la
déclarant static . Lors d’un nouvel appel à la fonction, la variable garde la valeur obtenue à la fin de
l’exécution précédente. Une variable static est initialisée à 0 lors du premier appel à la fonction
Exemple :
Exercice
47
Quelle sera la valeur finale de n si I est déclarée comme variable static, puis comme variable
automatique?
#include<stdio.h>
#include<conio.h>
i++ ;
printf(‘’i=%d\n’’,i) ;
n=n + i;
clrscr();
printf(‘’n=%d\n’’, n);
calcul();
getch();
En langage C, le passage de paramètres se fait uniquement par adresse. Autrement dit, une fonction
ne peut pas modifier la valeur des variables locales à main() ou à une fonction. Elle ne peut modifier
que le contenu de l’adresse de cette variable.
La fonction reçoit des valeurs par des noms des variables et la modification de ces variables n’est pas
répercutée à l’extérieur de la fonction
48
Exemple : syntaxe incorrect
#include<stdio.h>
#include<conio.h>
int tampon ;
tampon=x ;
x=y ;
y=tampon ;
void main()
int a = 5, b=8 ;
echange(a, b) ;
printf(‘’a=%d\n’’,a) ;
printf(‘’b=%d\n’’,b);
getch();
Le passage par adresse signifie que l’on passe en argument l’adresse de la variable. La fonction
manipulera donc l’adresse de la variable passée en argument. Si la valeur stockée à cette adresse est
modifiée par la fonction, la valeur de cette variable sera aussi modifiée à l’extérieur de la fonction. Le
passage par adresse se déclare en utilisant l’opérateur *
#include<stdio.h>
#include<conio.h>
49
int tampon ;
tampon=*x ;
*x=*y ;
*y=tampon ;
void main()
Int a = 5, b=8 ;
echange(&a, &b) ;
printf(‘’a=%d\n’’,a) ;
printf(‘’b=%d\n’’,b);
getch();
#include<stdio.h>
#include<conio.h>
Int fact(int n)
if(n==0)
return 1;
Void main ()
Clrscr();
50
int a = 4;
printf(‘’%d=%d’’, a, fact(a));
getch();
Exemple :
Int i, *grand ;
If(tab[i]>*grand)
grand=tab + i;
return(grand);
Application :
#include<stdio.h>
#include<conio.h>
Int i, *grand ;
If(tab[i]>*grand)
grand=tab + i;
return(grand);
51
Void main()
clrscr();
Int tab[10], i;
scanf(‘’%d’’,&tab[i]) ;
getch() ;
Exemple :
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define n 10
int tab[n];
// fonction initialization
for(int i =0;i<n;i++)
tab[i]=0;
// fonction initrandom
52
{
randomize();
for(int i=0;i<n;i++)
tab[i]=random(101);
//fonction saisie
scanf(‘’%d’’,&tab[i]);
//fonction affiche
printf(‘’%d\t’’,tab[i]);
//fonction menu
Void menu()
int choix;
do
clrscr() ;
53
printf(‘’---MENU GENERAL ---\n’’) ;
printf(‘’2: INITRANDOM\n’’) ;
printf(‘’3: SAISIE\n’’) ;
scanf(‘’%d’’,&choix) ;
switch(choix)
case 1 : { clrscr() ;
initialisation (tab) ;
printf(‘’MATRICE NULLE\n’’) ;
affiche (tab) ;
break ;
case 2 : { clrscr() ;
initrandom (tab) ;
printf(‘’MATRICE RANDOM\n’’) ;
affiche (tab) ;
break ;
case 3 :{ clrscr() ;
saisie (tab) ;
printf(‘’MATRICE SAISIE\n’’) ;
affiche(tab) ;
break ;
getch() ;
54
}
while(choix !=4) ;
getch() ;
menu() ;
En langage C, les chaînes de caractères sont des tableaux de caractères. Leur manipulation est donc
analogue à celle d'un tableau à une dimension:
nom = (char*)malloc(dim);
texte = (char*)malloc(10);
Le compilateur réserve (dim-1) places en mémoire pour la chaîne de caractères: En effet, il ajoute
toujours le caractère NUL ('\0') à la fin de la chaîne en mémoire.
Saisie : On peut utiliser la fonction scanf et le format %s. Une chaîne étant un pointeur, on n'écrit
pas le symbole &. On utilisera de préférence la fonction gets non formatée.
55
char texte[10];
Remarque : Pour saisir une chaîne de type "il fait beau", il faut utiliser gets. En effet scanf ne prend
pas en compte les espaces par contre gets prend en compte les espaces
A l'issue de la saisie d'une chaîne de caractères, le compilateur ajoute '\0' en mémoire après le
dernier caractère.
Application 1
#include<stdio.h>
#include<conio.h>
#include<string.h>
Int main()
gets(ville) ;
puts(ville) ;
getch() ;
return 0 ;
Application 2
#include<stdio.h>
#include<conio.h>
56
#include<string.h>
int main()
char tab[20] ;
int i ;
gets(tab) ;
printf(‘’%c’’, tab[i]) ;
getch() ;
return 0 ;
Application 3
#include<stdio.h>
#include<conio.h>
Void main()
char *adr ;
adr=’’bonjour’’ ;
while(*adr)
Printf(‘’%c’’,*adr) ;
Adr++ ;
Getch() ;
57
}
Commentaire :
Char *adr ; /* reserve simplement l’emplacement pour un pointeur sur un caractère ( ou sur une
suite de caractères) */
Adr=’’bonjour’’ ; /* la notation bonjour a comme valeur, non pas la valeur de la chaîne elle -même,
mais son adresse */
Voici un schéma illustrant ce phénomène ; la flèche en trait plein correspondant à la situation après
l’exécution de l’affectation : adr = ‘’bonjour’’ ; les autres flèches correspondent à l’évolution de la
valeur de adr , au cours de la boucle
B o N J o u r \o
Adr
Char tab[20] = ‘’bonjour’’ ; // char tab[20]={ ‘b’, ‘o’, ‘n’, ‘j’, ‘o’, ‘u’, ‘r’, ‘\0’} ;
Nous avons vu qu’une chaîne constante était traduite par le compilateur en une adresse que l’on
pouvait, par exemple, affecter à un pointeur sur une chaîne . Cela peut se généraliser à un tableau de
pointeur, comme suit :
/* cette déclaration réalise à a fois la création de 7 chaînes constantes correspondant aux 7 jours de
la semaine et à l’initialisation du tableau jour avec les 7 adresses de ces 7 chaînes */
Attention :
Exemple :
#include<stdio.h>
#include<conio.h>
58
#include<string .h>
Int main()
Int i ;
Scanf(‘’%d’’,&i) ;
Getch() ;
Return 0 ;
Application 4
Ecrire un programme qui lit un numéro de téléphone sous la forme (242)066438523 et extrait
l’indicatif international dans une chaîne et qui l’affiche à l’écran
Résolution
#include<stdio.h>
#include<conio.h>
#include<string .h>
Void main()
Gets(tel) ;
While(tel[i] !=’)’)
59
indicatif[j]=tel[i] ;
i++ ;
j++ :
getch() ;
Exercice 1
Saisir une chaîne de caractères, afficher les éléments de la chaîne et leur adresse (y compris le
dernier caractère '\0').
#include<stdio.h>
#include<conio.h>
#define n 25
Void main()
Char texte[n] ;
Int i ;
Gets(texte) ;
Getch() ;
60
Exercice 2
Les bibliothèques fournies avec les compilateurs contiennent de nombreuses fonctions de traitement
des chaînes de caractères. En BORLAND C++, elles appartiennent aux bibliothèques string.h ou
stdlib.h. En voici quelques exemples:
Générales (string.h)
void *strcat(char *chaine1,char *chaine2) concatène les 2 chaînes, résultat dans chaine1,
Exemple :
#include<stdio.h>
#include<conio.h>
#include<string.h>
Void main()
Gets(ch1) ;
Gets(ch2) ;
Strcat(ch1,ch2) ;
Getch() ;
Remarque :
61
Exemple : strlen(‘’bonjour’’) vaudra 7
void *strrev(char *chaine) inverse la chaîne et, renvoie l'adresse de la chaine inversée.
Application :
Comparaison (string.h)
- positif si la chaîne1 est supérieure à la chaine2 (au sens de l'ordre alphabétique c.à.d. chaîne1 arrive
avant chaîne2 )
Exemple :
Ch1=’’Bonjour’’ ;
Ch2=’’bonj’’ ;
ch2>ch1 donc strcmp(ch1,ch2)<0 /* la chaîne ch2 arrive après la chaîne ch1 au sens de l’ordre défini
par le code de caractère)
NB : il n’y a pas de type chaîne de caractère en C. donc on ne peut jamais transmettre la valeur d’une
chaîne en argument d’une fonction mais seulement son adresse, ou plus précisement un pointeur sur
son premier caractère.
Copie (string.h)
Remarque : la fonction strcnpy limite la recopie au nombre de caractère précisés dans le prototype
suivant :
#include<stdio.h>
62
#include<conio.h>
#include<string.h>
Void main()
Char ch1[10]=’’xxxxxxxxxx’’ ;
ch2[10] ;
Gets(ch2) ;
Strncpy(ch1,ch2,5) ;
Getch() ;
Recopie (string.h)
Ces fonctions renvoient l'adresse de l'information recherchée en cas de succès, sinon le pointeur
NULL (c'est à dire le pointeur de valeur 0 ou encore le pointeur faux)
Exercice 2
#include<stdio.h>
#include<conio.h>
#include<string.h>
Void main()
63
Int nlettre = 0 ;
Gets(texte) ;
while(adr=strchr((adr,lettre))
nlettre++ ;
adr++ ;
Getch() ;
Conversions (stdlib.h)
gets(texte);
n = atoi(texte) ;
64
cette fonction renvoie l'adresse de la chaîne.
Pour tous ces exemples, la notation void* signifie que la fonction renvoie un pointeur (l'adresse de
l'information recherchée), mais que ce pointeur n'est pas typé. On peut ensuite le typer à l'aide de
l'opérateur cast .
adr = (int*)strchr(texte,'O');
Syntaxe :
struct nom_de_structure {
type_de_donnee nom1 ;
type_de_donnee nom2 ;
} ; /* ne pas oublier le point-virgule ! */
ou bien
typedef struct {
type_de_donnee nom1 ;
type_de_donnee nom2 ;
} type_de_structure; /* ne pas oublier le point-virgule ! */
65
int année ;
};
7-2- Déclaration
ou bien
type_de_structure nom_de_variable ;
7-3- Utilisation
pour accéder à un champ d'une structure, c'est l'opérateur '.' qui est utilisé ou l'opérateur '->' dans le
cas d'une variable pointeur sur une structure.
Exemple 1
#include<stdio.h>
#include<conio.h>
#include<math.h>
Struct point
Float x ;
Float y ;
66
};
Int main()
struct point V ;
float x,y ;
scanf(‘’%f%f’’,&x,&y) ;
V.x=x ;
V.y=y ;
getch() ;
Exemple 2
#include<stdio.h>
#include<conio.h>
struct date
{
int jour ;
int mois ;
int année ;
};
Int main()
{
struct date hier ;
hier.jour = 30;
hier.mois = 5 ;
hier.année = 1986;
printf(‘’Hier le %d %d %d \n’’, hier.jour , hier.mois, hier.année) ;
getch() ;
}
Exemple 3
#include<stdio.h>
#include<conio.h>
struct date
{
67
int jour ;
int mois ;
int année ;
};
Int main()
{
struct date hier , *x;
x=&hier ;
hier->jour = 30 ;
hier->mois = 5 ;
hier->année = 1986 ;
printf(‘’Hier le %d %d %d \n’’, hier->jour , hier->mois, hier->année) ;
getch() ;
}
Exemple 4
#include <stdio.h>
#include <string.h>
struct salarie {
char nom[30] ;
float salaire ;
};
salarie dIOP, *NDIAYE, FATOU ;
int main(void) {
durant = new salarie ;
strcpy(DIOP.nom,"DIOP Emile") ;
...
DIOP.salaire = NDIAYE->salaire+1000 ;
Printf("le salaire de %s est %f" , diop.nom ,diop.salaire ) ;
}
7-4- Tableaux des structures
Exemple :
Struct point
Char nom ;
Int x ;
Int y ;
};
Struct point courbe[50] ;// courbe est un tableau de 50 éléments de type point
68
7-5- Structures comportant d’autres structures
struct date
{
int jour ;
int mois ;
int année ;
};
Struct personne
{
char nom[30] ;
char prenom[30] ;
float heure[31] ;
struct date date_embauche ;
}employe ;
Exemple :
Exemple :
#include<stdio.h>
#include<conio.h>
Struct enreg
{ int a ;
Float b ;
};
s.a = 0 ; s.b = 1 ;
Int main()
69
Struct enreg x ;
x.a=1 ;
x.b=12.5 ;
fct(x) ;
getch() ;
#include<stdio.h>
#include<conio.h>
Struct enreg
{ int a ;
Float b ;
};
s->a = 0 ; s->b = 1 ;
Int main()
Struct enreg x ;
x.a=1 ;
x.b=12.5 ;
fct(&x) ;
70
printf(‘’\n au retour dans main : %d %e’’, x.a, x.b) ;
getch() ;
Opérations possibles avec les fichiers: Créer - Ouvrir - Fermer - Lire - Ecrire - Détruire - Renommer. La
plupart des fonctions permettant la manipulation des fichiers sont rangées dans la bibliothèque
standard STDIO.H, certaines dans la bibliothèque IO.H pour le BORLAND C++.
1- Définition
Un fichier est un ensemble des données situées sur les mémoires de masse(disque dur, disquette, clé
USB)
En langage C, un fichier est une suite d’octets. Les informations contenues dans le fichier ne sont pas
forcément de même type (un char, un int , une structure ---)
pointeur
- Accès séquentiel
On accède à une cellule quelconque en se déplaçant (via un pointeur ) depuis la cellule de départ
- Accès direct
On peut directement accéder à une cellule
Il existe d’autre part deux façons de coder les informations stockées dans un fichier :
Fichiers binaires :
Les informations sont codées telles que ce sont en général des fichiers . ils ne sont pas listables
Fichiers texte :
Les informations sont codées en ASCII. Ces fichiers sont listables. Le dernier octet de ces fichi e rs e st
EOF (caractère ASCII spécifique)
71
On définit un pointeur. Il s'agit du pointeur représenté sur la figure du début de chapitre. Ce pointeur
fournit l'adresse d'une cellule donnée.
La déclaration des fichiers doit figurer AVANT la déclaration des autres variables.
« rb » lecture seule
72
Exemple : FILE *fichier ;
Il faut toujours fermer un fichier à la fin d'une session. mode (pour les fichiers TEXTE) :
fclose(fichier) ;
Ecrit la valeur de c à la position courante du pointeur , le pointeur avance d'une case mémoire.
73
int putw(int n, FILE *fichier);
Idem, n de type int, le pointeur avance du nombre de cases correspondant à la taille d'un entier (4
cases en C standard).
int fputs(char *chaîne, FILE *fichier); idem avec une chaîne de caractères, le pointeur avance de la
longueur de la chaine ('\0' n'est pas rangé dans le fichier).
int fwrite(void *p,int taille_bloc,int nb_bloc,FILE *fichier); p de type pointeur, écrit à partir de la
position courante du pointeur fichier nb_bloc X taille_bloc octets lus à partir de l'adresse p. Le
pointeur fichier avance d'autant.
Le pointeur p est vu comme une adresse, son type est sans importance.
int tab[10] ;
fwrite(tab,4,3,fichier) ;
int fprintf(FILE *fichier, char *format, liste d'expressions); réservée plutôt aux fichiers ASCII.
fprintf(fichier,%d,n);
- Lecture du fichier:
74
int getc(FILE *fichier); lit 1 caractère, mais retourne un entier n; retourne EOF si erreur ou fin de
fichier; le pointeur avance d'une case.
Exemple: char c ;
c = (char)getc(fichier) ;
int getw(FILE *fichier); idem avec un entier; le pointeur avance de la taille d'un entier.
Exemple: int n ;
n = getw(fichier) ;
char *fgets(char *chaine,int n,FILE *fichier); lit n-1 caractères à partir de la position du pointeur et
les range dans chaine en ajoutant '\0'.
int fscanf(FILE *fichier, char *format, liste d'adresses); analogue à fprintf en lecture.
fgets retourne le pointeur NULL en cas d'erreur ou si la fin du fichier est atteinte.
la fonction int feof(FILE *fichier) retourne 0 tant que la fin du fichier n’est pas atteinte.
la fonction int ferror(FILE *fichier) retourne 1 si une erreur est apparue lors d'une manipulation de
fichier, 0 dans le cas contraire.
75
int fseek(FILE *fichier,int offset,int direction) déplace le pointeur de offset cases à partir de
direction.
Exercice 1
Exercice 2
Programme qui permet de créer un fichier d’étudiant (numéro ,nom ,prénom, age) et d’afficher ces
étudiants.
SEANCE 2
Réservation et libération
L'utilisation des pointeurs permet d'allouer de la mémoire sans connaître la taille nécessaire au
moment de la compilation. L'instruction malloc permet de réserver une certaine quantité de
mémoire. Cette zone mémoire est ensuite accessible par un pointeur. L'exemple suivant permet
d'allouer une zone de 5 entiers
Exemple
int * ptr;
76
ptr = (int*) malloc(5*sizeof(int));
ptr[0] = 4;
ptr[4] = 1;
ou la notation de pointeur :
*ptr = 4;
*(ptr+4) = 1;
L'exemple suivant propose une fonction AllouerPersonne() qui renvoie un pointeur sur un
enregistrement de type TPersonne qui a été alloué.
Exemple
typedef
char nom[30];
int age;
} TPersonne;
TPersonne * ptr;
ptr = (TPersonne*)malloc(sizeof(TPersonne));
return ptr;
La libération de la mémoire allouée dynamiquement se fait par la commande free comme illustré
dans l'exemple suivant :
Exemple
voi main()
77
{
TPersonne * p;
p = AllouerPersonne("John Doe",33);
if (p==NULL)
else
Remarques .Si la réservation mémoire n'a pas pu se faire, malloc renvoie la valeur NULL .
Structures Dynamiques
Exemple
struct livre
int disponible;
int numero;
};
void main()
int i;
78
original = (struct livre*)malloc(sizeof(struct livre));
original->numero = 100;
original->disponible = 1;
for (i=0;i<10;i++)
copies[i].numero = 1000+i;
copies[i].disponible = 1;
/* ... */
free(original);
free(copies);
Remarques
La variable pointeur original pointe sur une zone mémoire de type struct livre .
La variable pointeur copies pointe sur une zone mémoire de 10 structures de type struct livre .
L'accés à chaque enregistrement de copie se fait grâce à la notation de type tableau ( copies[i] ).
Remarques
La fonction calloc permet d'allouer de la mémoire et d'en initialiser le contenu.
Pour créer une liste chaînée il faudra ajouter dans la structure un champs qui indique le pointeur
suivant .
79
EXERCICES RECAPITULATIFS TP N°5
• Programme qui permet de créer une liste d’entier et d’afficher ces entiers.
• Programme qui permet de créer une liste de livre (numéro ,titre ,disponible) et d’afficher
ces livres.
Exemple
struct livre
{char titre[30] ;
int disponible;
int numero;
};
liste L ;
Aie , on donne pas tous aux enfants voir si possible cours , Livre , recherche sur Internet ce n’est
plus l’initialisation au langage. Merci bonne continuation dans l’approfondissement de vos
connaissances en programmation avancées et courage
80
81
82