Vous êtes sur la page 1sur 220

Département Génie Civil & Département Mécanique Énergétique

Programmation Structurée
Langage C

Laurence.Bergougnoux@univ-amu.fr
http://iusti.polytech.univ-mrs.fr/~bergougnoux/
Plan du cours

1. Introduction
2. Les bases du langage C
3. Les pointeurs et les tableaux
4. Les fonctions
5. Les types utilisateurs
6. La gestion de fichiers
7. La programmation modulaire
8. L'allocation dynamique de mémoire
9. Les listes chaînées
UE 53 :
Mathématiques & Informatique I
• En GC  c'est tout ...
• En ME  Programmation en langage Fortran
avec Jacques Massoni au semestre 6

Commun avec MT et GII Rémy Burlot

Progr. struct. - C Introduction 3


L'équipe enseignante
Laurence BERGOUGNOUX Bureau 208
François GUILLARD Bureau 242
Christian MARIANI Bureau 321
Fabien PETITPAS Bureau 319B
Jérôme VICENTE Bureau 326

Prenom.Nom@polytech.univ-mrs.fr
ou
Prenom.Nom@univ-amu.fr

Avec la participation de Jean-Luc FIRPO

Progr. struct. - C Introduction 4


Organisation de l'enseignement
ME GC

20h cours 20h cours


15h TD 20h TD
15h TP 20h TP
Projet + oral
Examen ME Examen GC
+ +
Contrôle continu Contrôle continu

Progr. struct. - C Introduction 5


En pratique : le 1er TD c'est

• GC 3.1, Vendredi 5/10, 8 h


• GC 3.2, Vendredi 5/10, 10h

• ME 3.1, Mercredi 24/10, 13h30


• ME 3.2, Vendredi 26/10, 13h30
• ME 3.3, Jeudi 25/10, 8h
• ME 3.4, Mardi 23/10, 13h30

Progr. struct. - C Introduction 6


Les objectifs

• Apprendre à résoudre un problème grâce à un


algorithme,
• Apprendre à programmer en C à des débutants de
manière efficace,
• Initier à la programmation par gestion d'évènements,
• Pratiquer un environnement de développement
largement utilisé dans l'industrie,
• Être une introduction au C++
...

Progr. struct. - C Introduction 7


Progr. struct. - C Introduction 8
Quelques généralités
en programmation

• Qu'est-ce qu'un Algorithme ?


• Langages de Programmation
• Qu'est-ce qu'un programme ?
• La structure d'un programme
• L'exécution du programme

Progr. struct. - C Quelques généralités 9


Qu'est-ce qu'un Algorithme ?

Un algorithme énonce une résolution sous la


forme d’une série d’opérations à effectuer.

données Algorithme résultat


(entrées) (sorties)

Recette de cuisine
ingrédients plat

Progr. struct. - C Quelques généralités 10


Conception d'un Algorithme :
Analyse hiérarchisée
C'est faire une liste de tâches (ou d'actions) à
réaliser de manière séquentielle.

Recette du gâteau à la crème de marrons :


1) Préchauffer le four à 180°C
2) Faire fondre le chocolat et le beurre
3) Casser 3 œufs et les battre
4) Ajouter la crème de marrons, et mélanger
5) Incorporer le chocolat fondu à la préparation
6) Beurrer un moule à gâteau et y verser la préparation
8) Faire cuire 35 min à 180°C

Progr. struct. - C Quelques généralités 11


Langages de programmation :
Pourquoi faire?

• Pour écrire avec des mots et signes


compréhensibles par une intelligence humaine.
• Afin d'organiser, de structurer, le déroulement
du programme de manière claire et vérifiable.

Progr. struct. - C Quelques généralités 12


Quelques Langages

Par ordre chronologique :


• Assembleur 68000, 8086
• Fortran, Cobol
• Basic, Pascal, Langage C
• Langages Objets : C++, Java , C#, …

http://www.scriptol.fr/programmation/langages-populaires.php

Progr. struct. - C Quelques généralités 13


Programme exécutable

Suite d’instructions binaires que le µprocesseur


doit effectuer :
• Spécifiques à un type de µprocesseur.
• Stockées sur une mémoire de masse
(disque dur, disquette, CD Rom, clef usb).
• Chargées en mémoire centrale avant
l’exécution du programme.

Progr. struct. - C Quelques généralités 14


Comment réaliser un programme ?

• Éditer le code source : fichier texte qui obéit aux


règles de syntaxe du langage.
• Le sauvegarder de temps en temps.
• Le compiler, le traduire en langage machine pour
obtenir un fichier exécutable.

Fichier Compilation Fichier Éditeur Fichier


Source Objet de liens Exécutable

Progr. struct. - C Quelques généralités 15


L'exécution du programme
Au lancement du programme, le système
d’exploitation :
• Transfère le programme de la mémoire de
masse en mémoire centrale,
• Réserve de la place pour les données du
programme,
• Démarre l’exécution du programme,
• Reprend la main quand le programme s’achève.

Progr. struct. - C Quelques généralités 16


1er programme en C

• Langage C : histoire et qualités


• LabWindows/CVI
• Le fichier source en C
• On se lance …

Progr. struct. - C 1er programme 17


Le langage C
• Crée par K. Thompson, D. Ritchie et B. Kernighan
pour développer UNIX.

• C’est un langage structuré et portable.

• C’est le langage le plus utilisé par les professionnels


du logiciel.

• C’est la base du C++ qui permet la programmation


orientée objet.

Progr. struct. - C 1er programme 18


LabWindowsTM/CVI
• Environnement de Développement Intégré (IDE)
sous Windows, avec 1 compilateur C-ANSI.

• Programmation événementielle
et interface graphique.

• Logiciels de mesure et contrôle

Progr. struct. - C 1er programme 19


Premier Programme
en langage C
sous LabWindows/CVI

Progr. struct. - C 1er programme 20


Le fichier Source en C
source_1.c
#include <stdio.h> // fichier en-tête ou header où
se trouve la définition de printf()
int main()
//Fonction ou bloc principal
{
printf("Bienvenue a POLYTECH Marseille \n");
return(0);
}

Progr. struct. - C 1er programme 21


Département Génie Civil & Département Mécanique Énergétique

Les bases du langage C


1. Les types de données
2. Les variables
3. Les opérateurs
4. Les structures conditionnelles

Prog. Struct. - C Les bases 22


Types, variables et constantes

Qu'est-ce qu'une variable ?


• c'est le nom d’un emplacement mémoire

• on en crée presque autant qu’on veut


• son contenu peut changer dans le temps.
• elle contient toujours quelque chose !!!

Une variable sera toujours définie avant utilisation :


elle doit être associée à un type de données.

Prog. Struct. - C 1. Les types de données 23


Les types de données
Qu'est-ce qu'un type ?
• définit une convention de codage de l'information
• dans un emplacement de taille préfixée

1 nombre : entier ou réel


1 Variable en C

1 pointeur : adresse

Prog. Struct. - C 1. Les types de données 24


Les nombres entiers
Types
Signification Taille (octet) Plage de valeurs
prédéfinis
char Caractère 1 -128 à 127
Caractère non
unsigned char 1 0 à 255
signé
short int Entier court 2 -32 768 à 32 767
unsigned short Entier court non
2 0 à 65 535
int signé
2 (sur 16 bits) -32 768 à 32 767
int Entier 4 (sur 32 bits) -2 147 483 648 à
2 147 483 647
2 (sur 16 bits) 0 à 65 535
unsigned int Entier non signé
4 (sur 32 bits) 0 à 4 294 967 295
-2 147 483 648 à
long int Entier long 4
2 147 483 647
unsigned long Ent. long non
4 0 à 4 294 967 295
int signé

Prog. Struct. - C 1. Les types de données 25


Les nombres réels

Types
Signification Taille (octet) Plage de valeurs
prédéfinis
float Réel simple précision 4 3.4 x 10-38 à 3.4 x 1038
Réel double
double 8 1.7 10-308 à 1.7 10308
précision
Flottant double
long double 10 3.4 10-4932 à 3.4 104932
long

Prog. Struct. - C 1. Les types de données 26


Codage binaire
• des nombres entiers
1970 = 1024 + 512 + 256 + 128 + 32 + 16 + 2
          = 210 + 29   + 28    + 27     + 25 + 24 + 21
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

00 00 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1110110010

• des nombres réels


197,75 = 128 + 64 + 4 + 1 , 0.5 + 0.25
= 27 + 26+ 22 +20, 2-1 + 2-2
= 11000101,11
= 1,100010111 x 27 exposant = 7+127=134=1000 0110
signe
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

0 1 00 0 0 11 0 1 0 0 0 1 0 1 1 1 0 0 0 0 0000000000
exposant
mantisse
Prog. Struct. - C 1. Les types de données 27
Les pointeurs

Type Signification Taille (octet) Plage de valeurs


2 (sur 16 bits) 0x0000 à 0xFFFF
*pointeur adresse
4 (sur 32 bits) 0x00000000 à 0xFFFFFFFF

Prog. Struct. - C 1. Les types de données 28


Les variables
Leur nom :
• Contient 32 caractères max
• Commence par une lettre
• Ne peut être un des mots réservés du C

auto default float register struct volatile


break do for return switch while
case double goto short typedef
char else if signed union
const enum int sizeof unsigned

continue extern long static void

Prog. Struct. - C 2. Les variables 29


La déclaration de variables
type nom_de_la_variable ;
exemple :
#include <stdio.h>
int main()
{
int a; //déclaration
char var_car = 'f'; // + initialisation
char *pointe_ici; // le pointeur

a = 127; //affectation
pointe_ici = &var_car;

printf("la valeur de a = %i",a); //affichage


printf("\n et celle de var_car %c", var_car);
}

Prog. Struct. - C 2. Les variables 31


Les constantes
#include <stdio.h>
//Directive du pré processeur
#define PI 3.14159
#define titi toto
int main()
{ float a;
//Déclaration d'une constante
const int douze=12;

a = douze*PI;
}
Prog. Struct. - C 2. Les variables 32
• Affichage à l'écran une variable
int x=3;
printf("Pour afficher à l\' écran\n");
printf("le contenu de x est %d",x);

• Saisie au clavier du contenu d'une variable


int x;
printf("Entrez le contenu de x");
scanf("%d",&x);

char  %c float  %f
int  %d double  %lf

Prog. Struct. - C 2. Les variables 33


Les opérateurs du C
• les opérateurs de calcul
• …………………… d'assignation
• …………………… d'incrémentation
• …………………… de comparaison
• …………………… logiques
• …………………… bit-à-bit
• …………………… de décalage de bit
• Les priorités

Prog. Struct. - C 3. Les opérateurs 34


Les opérateurs de calcul
Si Si
Opérateur Exemple
int x=10; float x=10.0;
+ d'addition x=x+3; 13 13.0
- de soustraction x=x-3; 7 7.0
* de multiplication x=x*3; 30 30.0
/ de division x=x/3; 3 3.3333333
Met la valeur 3 Met la valeur 3.0
= d'affectation x=3; dans la variable x dans la variable x

=

Prog. Struct. - C 3. Les opérateurs 35


Les opérateurs d'assignations
x=x+2; peut aussi s'écrire x+=2;
additionne deux valeurs et stocke le résultat dans la
+= variable (à gauche) x
-= soustrait deux valeurs et stocke le résultat dans la variable

*= multiplie deux valeurs et stocke le résultat dans la variable

/= divise deux valeurs et stocke le résultat dans la variable

x=a=b=3;  x= (a= (b=3));

Prog. Struct. - C 3. Les opérateurs 36


Les opérateurs d'incrémentation
• ++ : incrémentation de 1
x=3;
//post-incrémentation
y=x++;  y=x; x=x+1; //y=3, x=4
 
//pré incrémentation
y=++x;  x=x+1; y=x; //x=y=5
• -- : décrémentation de 1
y=x--;  y=x; x=x-1; //y=5, x=4

Prog. Struct. - C 3. Les opérateurs 37


Les opérateurs de comparaison

Opérateur Exemple Résultat si x vaut 7

Retourne 1 si x est égal à 3,


== égalité x==3
sinon 0
Retourne 1 si x est inférieur à
< infériorité stricte x<3
3, sinon 0
Retourne 1 si x est inférieur ou
<= infériorité x<=3
égal à 3, sinon 0
supériorité Retourne 1 si x est supérieur à
> x>3
stricte 3, sinon 0
Retourne 1 si x est supérieur
>= supériorité x>=3
ou égal à 3, sinon 0
Retourne 1 si x est différent de
!= différence x!=3
3, sinon 0

Prog. Struct. - C 3. Les opérateurs 38


Les opérateurs conditionnels
logiques
Opérateur Syntaxe

a b a||b a&&b !a
|| OU logique ((cond1)||(cond2))
0 0 0 0 1
0 1 1 0 1
&& ET logique ((cond1)&&(cond2)) 1 0 1 0 0
1 1 1 1 0
! NON logique (!condition)

Prog. Struct. - C 3. Les opérateurs 39


Les opérateurs bit-à-bit

Opérateur Syntaxe Résultat

1001
& ET 9 & 12 & 1100 8
1000

1001
| OU 9 | 12 | 1100 13
1101

1001
^ OU exclusif 9 ^ 12 ^ 1100 5
0101

Prog. Struct. - C 3. Les opérateurs 40


Les opérateurs de décalage de bit
Opérateur Syntaxe Résultat
6 << 1

<< Décalage à gauche 00000110 << 1 12


= 00001100
x2
6 >> 1

>>
Décalage à droite avec 00000110 >> 1 3
conservation du signe = 00000011
/2

En signé : -6 <<1 = -12 11111010 << 1


= 11110100
11111010 >> 1
-6 >>1 = -3 = 11111101
Prog. Struct. - C 3. Les opérateurs 41
Les priorités
+++ () []
-- ++ ! ~ -
* / %
+ -
<< >>
< <= >= >
== !=
&
^
|
&& ||
?:
= += -= etc.…
---

Prog. Struct. - C 3. Les opérateurs 42


4 types d'instructions

• Nulle  ;
• Expression  a=b+1;
• Prédéfinie  condition ou boucle  if ()
• Bloc  { }

Prog. Struct. - C 4. Les structures conditionnelles 43


Les structures conditionnelles

• Les instructions de branchement conditionnel


if(condition)
if(condition)… else
switch(variable) case

• Les instructions de boucle


while(condition)
do … while(condition);
for(initialisation;condition;incrementation)

Prog. Struct. - C 4. Les structures conditionnelles 44


L'instruction if

• syntaxe :
if(condition) FAUX
{ condition

instructions;
VRAI
}
instructions

Prog. Struct. - C 4. Les structures conditionnelles 45


L'instruction if(condition)…else

• syntaxe :
if(condition) FAUX
{ condition
instructions;
} VRAI
else instructions
{
instructions
instructions;
}

Prog. Struct. - C 4. Les structures conditionnelles 46


L'instruction if…else
• Exemple :

if (var1==0) //si c'est vrai


{
printf("La variable est nulle\n");
}
else //sinon c'est faux
{
if (var1 > 0)
{ printf("Elle est positive\n"); }
else
{ printf("Elle est négative"); }
}

Prog. Struct. - C 4. Les instructions conditionnelles 47


Attention aux forêts d'if()
• exemple :

if (var1!=0)
if (var1 > 0)
printf("Elle est positive\n");
else
printf("Elle est négative\n");

else se rapporte toujours au if le plus proche

Prog. Struct. - C 4. Les instructions conditionnelles 48


L'opérateur conditionnel
(condition) ? instruction_vrai : instruct_faux

• exemple :
x = 3;
y = 2;
max_xy = ((x>=y) ? x : y);
=
1
max_xy = x;

Prog. Struct. - C 4. Les instructions conditionnelles 49


L'instruction while
• tant que (condition vraie)

FAUX
• syntaxe : condition
while(condition)
VRAI
{
instructions
instructions;
}

Prog. Struct. - C 4. Les instructions conditionnelles 50


L'instruction do…while
• faire … tant que (condition vraie)

• syntaxe :
do
{ instructions
instructions;
}while(condition); VRAI FAUX
condition

Prog. Struct. - C 4. Les instructions conditionnelles 51


L'instruction for()
initialisation du
• syntaxe : compteur de boucle
for( init;condition;incrément)
{
instructions; FAUX
condition
}
• exemple : VRAI
for(i=0;i<100;i++) instructions
{
printf("%d\n",i); modification du
} compteur de boucle

Prog. Struct. - C 4. Les instructions conditionnelles 52


Attention aux boucles sans fin
;

•exemple : F
1
for( ; ; ) V
{ Affichage
printf("sans fin\n"); "sans fin"
}
;

Prog. Struct. - C 4. Les instructions conditionnelles 53


Les instructions de sortie :
continue
• exemple : x=1

x=1;
? F
while(x<=10) x <= 10
{
a=1/(x-7); V
printf("%f",a);
x++;
a=1/(x-7)
}
affichage a

x=x+1

Prog. Struct. - C 4. Les instructions conditionnelles 54


Les instructions de sortie :
continue x=1

• exemple : ?
x <= 10
F

x=1;
while(x<=10) V
{
? F
if (x==7) x ==7
{ printf("division par 0");
x++; V
continue; affiche /0
} x=x+1
a=1/(x-7);
printf("%f",a); a=1/(x-7)
x++; affichage de a
} x=x+1

Prog. Struct. - C 4. Les instructions conditionnelles 55


Les instructions de sortie :
break
• exemple :
x=1
x=1;
while(x<=10)
F
{ ?
a = x-7; x <=10
printf("%f", 1/a); V
x++;
a=x-7
}

affichage 1/a

x=x+1

Prog. Struct. - C 4. Les instructions conditionnelles 56


Les instructions de sortie :
break x=1
• exemple :
x=1; F
while(x<=10) ?
x <=10
{
a = x-7; V
if (a == 0) a=x-7
{
printf("/ par 0"); V
?
break; a == 0
} affiche /0
F
printf("%f", 1/a);
x++; affichage 1/a
} x=x+1

Prog. Struct. - C 4. Les instructions conditionnelles 57


Les instructions de sortie :
return
• syntaxe :
return(expression);

• exemple :
int main()
{

return(0);
}

Prog. Struct. - C 4. Les instructions conditionnelles 58


L'instruction de choix multiples :
• Syntaxe :
switch
switch (expr) F
?
==const1
{ case const1:
instructions;
V F
break; ?
==const2
case const2: instr.
instructions; V
break; instr.
default:
instructions; ?
!=const1,2
break;
V
}
instr.

Prog. Struct. - C 4. Les instructions conditionnelles 59


• exemple :
switch
char choix;
printf("Taper 1 ou 2");
scanf("%c",&choix);
switch(choix)
{ case '1':
printf("vous avez tape 1\n");
break;
case '2':
printf("vous avez tape 2\n");
break;
default :
printf("je vous ai dit 1 ou 2 pas %c\n",choix);
break;
}

Prog. Struct. - C 4. Les instructions conditionnelles 60


Département Génie Civil & Département Mécanique Énergétique

Exemples

• Résolution numérique d'une équation du


second degré
• Programme mystère
• Affectation et récurrence
Résolution de ax2+bx+c=0 :
Organisation du programme
Initialisation :
Acquisition au clavier
des valeurs de a,b,c

Algorithme de calcul

Présentation des
résultats sur l’écran

Prog. Struct. C 5. Ex : équation du 2nd degré 62


Résolution de ax2+bx+c=0 : Organigramme
Acquisition de a, b, c

VRAI FAUX
a= = 0 Calcul de D

V F F
Affichage pas D<0 D==0
2° degré
V
Pas de racines
Racine 2 Racines
double Distinctes

fin

Prog. Struct. C 5. Ex : équation du 2nd degré 63


Le squelette
#include <stdio.h>
#include <math.h> Directives du pré processeur
int main()
{
/*Déclaration de variables a,b,c,delta,x1,x2*/
/*Entrée des valeurs pour a, b, c*/
/*Test du contenu de a*/
//si a  0
/*Calcul de delta */
/*Test sur delta*/
//si delta <0 -> affichage pas de racines
//si delta =0 -> affichage racine double
//si delta >0 -> affichage 2 racines réelles
}

Prog. Struct. C 5. Ex : équation du 2nd degré 64


II
Fonction main ()

int main()
{
/*Déclaration de variables */
float a,b,c;
float delta;
float x1,x2;
/*Fin de la déclaration des variables*/

Prog. Struct. C 5. Ex : équation du 2nd degré 65


Fonction main () … suite
/*Entrée/saisie des valeurs contenues dans les
variables a, b, c*/
printf("Donnez la valeur de a:");
scanf ("%f",&a);

printf("\nDonnez la valeur de b:");


scanf ("%f",&b);

printf("\nDonnez la valeur de c:");


scanf ("%f",&c);
/* Fin de l'initialisation*/
 
Prog. Struct. C 5. Ex : équation du 2nd degré 66
toujours dans la fonction main ()
/*Test du contenu de a*/
if (a == 0.0)
{
printf("\nCe n'est pas une eq. du second degré");
}
else
{ /*Ouverture du bloc d'instruction a != de 0*/
/*Calcul de delta */
delta = b*b-4*a*c;
/*Test sur delta*/
if (delta < 0)
printf("\nPas de racines");
else
{ /*ouverture du bloc d'instruction delta >=0*/
Prog. Struct. C 5. Ex : équation du 2nd degré 67
Fin du main ()
if (delta == 0) /*Test delta nul*/
{ x1 = -b/(2*a);
printf ("\nRacine double :%f",x1);
}
else /*Bloc d'intruction delta positif*/
{ x1=(-b-sqrt(delta))/a/2;
x2=(-b+sqrt(delta))/a/2;
printf("x1=%f x2=%f \n",x1,x2);
}/*fin delta>0*/
}/*Fin delta <0*/
}/*Fin a != 0*/
return 0;
}/*Fin programme*/
secondeg.c

Prog. Struct. C 5. Ex : équation du 2nd degré 68


Récurrence

• Mathématiquement une relation de


récurrence, c'est :
xi+1 = f(xi) avec x0 donné
permet de déterminer toutes les valeurs des
termes de la suite xk.
• La valeur d'un nouveau terme se déduit à
partir de celle du précédent.

Prog. Struct. C 5. Ex : équation du 2nd degré 69


Affectation
x = expression(x);

  
x  expression(x);
Le nouveau contenu de la variable x après l'exécution de
l'instruction est le résultat de l'évaluation de l'expression
avec le contenu actuel de x.

Prog. Struct. C 5. Ex : équation du 2nd degré 70


Exemple : Calculer Sn  
n
 1 i 1

i 1 i
Ce qui donne la relation de récurrence :

S k  S k 1 
 1
k 1

k
Avec S1  1
recurrence.c

Prog. Struct. C 5. Ex : équation du 2nd degré 71


Département Génie Civil & Département Mécanique Énergétique

Exemples
– Résolution numérique d'une équation du second
degré
– Programme mystère
– Affectation et récurrence
Résolution de ax2+bx+c=0 :
Organisation du programme
Initialisation :
Acquisition au clavier
des valeurs de a,b,c

Algorithme de calcul

Présentation des
résultats sur l’écran

Prog. Struct. C 5. Ex : équation du 2nd degré 73


Soit a,b,c,D,x1 et x2 des réels
Lire les coefficients a, b, c
si1 a est égal 0
Alors1 Afficher "trop facile C pas du 2nd degré"
sinon1 D  b*b - 4 a*c
  si2 D est inférieur à 0
alors2 Afficher "pas de racines réelles"
sinon2
si D est égal à 0
   3
alors3 x1 -b/2a
Afficher x1
sinon3 x1 (-b -sqrt(D))/2a
x2 (-b+sqrt(D))/2a
Afficher x1 et x2
Fin si3
Fin si2
Fin si1

Prog. Struct. C 5. Ex : équation du 2nd degré 74


Résolution de ax2+bx+c=0 : Organigramme
Acquisition de a, b, c

VRAI FAUX
a= = 0 Calcul de D

V F F
Affichage pas D<0 D==0
2° degré
V
Pas de racines
Racine 2 Racines
double Distinctes

fin

Prog. Struct. C 5. Ex : équation du 2nd degré 75


Le squelette
#include <stdio.h>
#include <math.h> Directives du pré processeur
int main()
{
/*Déclaration de variables a,b,c,delta,x1,x2*/
/*Entrée des valeurs pour a, b, c*/
/*Test du contenu de a*/
//si a  0
/*Calcul de delta */
/*Test sur delta*/
//si delta <0 -> affichage pas de racines
//si delta =0 -> affichage racine double
//si delta >0 -> affichage 2 racines réelles
}

Prog. Struct. C 5. Ex : équation du 2nd degré 76


II
Fonction main ()

int main()
{
/*Déclaration de variables */
float a,b,c;
float delta;
float x1,x2;
/*Fin de la déclaration des variables*/

Prog. Struct. C 5. Ex : équation du 2nd degré 77


Fonction main () … suite
/*Entrée/saisie des valeurs contenues dans les
variables a, b, c*/
printf("Donnez la valeur de a:");
scanf ("%f",&a);

printf("\nDonnez la valeur de b:");


scanf ("%f",&b);

printf("\nDonnez la valeur de c:");


scanf ("%f",&c);
/* Fin de l'initialisation*/
 
Prog. Struct. C 5. Ex : équation du 2nd degré 78
toujours dans la fonction main ()
/*Test du contenu de a*/
if (a == 0.0)
{
printf("\nCe n'est pas une eq. du second degré");
}
else
{ /*Ouverture du bloc d'instruction a != de 0*/
/*Calcul de delta */
delta = b*b-4*a*c;
/*Test sur delta*/
if (delta < 0)
printf("\nPas de racines");
else
{ /*ouverture du bloc d'instruction delta >=0*/
Prog. Struct. C 5. Ex : équation du 2nd degré 79
Fin du main ()
if (delta == 0) /*Test delta nul*/
{ x1 = -b/(2*a);
printf ("\nRacine double :%f",x1);
}
else /*Bloc d'intruction delta positif*/
{ x1=(-b-sqrt(delta))/a/2;
x2=(-b+sqrt(delta))/a/2;
printf("x1=%f x2=%f \n",x1,x2);
}/*fin delta>0*/
}/*Fin delta <0*/
}/*Fin a != 0*/
return 0;
}/*Fin programme*/
secondeg.c

Prog. Struct. C 5. Ex : équation du 2nd degré 80


#include <stdio.h>
Algorithme int main()
{

mystérieux
float a, b,r;
printf("\nentrez la valeur de a :");
scanf("%f",&a);
printf("\nentrez la valeur de b :");
Soit a, b, r réels ; scanf("%f",&b);
r=0.0;
lire(a) ; while (b!=0.0)
lire(b) ; {
r <- 0 ; if(((int)b)%2 ==0)
{
tant-que (b ≠ 0) b=b/2;
si (b est pair) a=2*a;
b <- b/2 ; }
else
a <- 2*a ; {
sinon b=b-1;
b <- b-1 ; }
r=r+a;
r <- r+a ; }
fin si printf("\n r = %f",r);
fin tant-que }
return(0);
écrire(r) ;

Prog. Struct. C 5. Ex : équation du 2nd degré 81


Récurrence

• Mathématiquement une relation de


récurrence, c'est :
xi+1 = f(xi) avec x0 donné
permet de déterminer toutes les valeurs des
termes de la suite xk.
• La valeur d'un nouveau terme se déduit à
partir de celle du précédent.

Prog. Struct. C 5. Ex : équation du 2nd degré 82


Affectation
x = expression(x);

  
x  expression(x);
Le nouveau contenu de la variable x après l'exécution de
l'instruction est le résultat de l'évaluation de l'expression
avec le contenu actuel de x.

Prog. Struct. C 5. Ex : équation du 2nd degré 83


Exemple : Calculer Sn  
n
 1 i 1

i 1 i
Ce qui donne la relation de récurrence :

S k  S k 1 
 1
k 1

k
Avec S1  1
recurrence.c

Prog. Struct. C 5. Ex : équation du 2nd degré 84


Département Génie Civil & Département Mécanique Énergétique

Les pointeurs et les tableaux


1. Les pointeurs
2. Les tableaux
• Les chaînes de caractères
• Les tableaux à plusieurs indices

Prog. struct. : C III-Les pointeurs et les tableaux 85


Les pointeurs : définition

Un pointeur est une variable qui contient


l'adresse d'une autre variable :
• d’une donnée,
• d’une fonction (fera l'objet du prochain cours).

Prog. struct. : C III-Les pointeurs ... 86


Les pointeurs sur donnée

a) Déclaration d’un pointeur sur donnée


b) Mécanisme de l'adressage indirect
c) Arithmétique des pointeurs

Prog. struct. : C III-Les pointeurs ... 87


Déclaration d’un pointeur sur donnée

• La déclaration :
Type_donnee *Ident_ptr;

• Exemple :
int *pAdi;
pAdi est codé sur 4 octets (adressage 32 bits) et contiendra
l'adresse d'un entier

Prog. struct. : C III-Les pointeurs ... 88


Mémoire, adresse et pointeur

http://www.siteduzero.com/

Prog. struct. : C III-Les pointeurs ... 89


L’adressage indirect
contenu contenant

i 10 Adresse de i
int i,*pAdi; 
 i=10; 
 pAdi = &i;
contenu contenant
*pAdi = 12;
pAdi Adresse de i Adresse de pAdi

Prog. struct. : C III-Les pointeurs ... 90


L’adressage indirect

contenu contenant
12 Adresse de i
int i,*pAdi; i
i=10;

 pAdi = &i;  
contenu contenant
 *pAdi = 12;
Adresse de i Adresse de pAdi
pAdi

Prog. struct. : C III-Les pointeurs ... 91


& et *
int i;
int *padi;

&  pour accéder à l'adresse d'une donnée


ex : &i  le numéro de la case mémoire
correspondant à la variable i  padi = &i;

*  pour accéder au contenu d'une adresse


ex : *padi  permet d'accéder au contenu de
l'adresse padi  contenu de l'adresse de i  i

Prog. struct. : C III-Les pointeurs ... 92


Arithmétique des pointeurs
sur données
• Additions et soustractions d'entiers sur les adresses
contenues dans les pointeurs

• Elles les déplacent de la quantité, qui a été


additionnée ou soustraite, multipliée par la taille en
octet du type de l'objet pointé.

Prog. struct. : C III-Les pointeurs ... 93


Exemple :
contenant contenu nom
int i = 80;
60 80 i
double xx=3.1415; 64 3.1415 xx
double *pAd; 100 ? pAd
… 60 80 i
pAd = &xx; 64 3.1415 xx
100 64 pAd
pAd = pAd+i;
/*pAd +i*sizeof(double) 60 80 i
c.a.d. 64 + 80*8 octets*/ 64 3.1415 xx
100 704 pAd

Prog. struct. : C III-Les pointeurs ... 94


Les Tableaux

1. Les tableaux mono-dimensionnels


2. Les chaînes de caractères
3. Les tableaux de tableaux …

Prog. struct. : C III- ... Les tableaux 95


Les Tableaux : déclaration et définition

Type_donnee Ident_Tab [NbElem];

• int, double, char …


• NbElem  le nbre d’éléments du tableau  constante
littérale ou symbolique (#define)
• Ident_Tab  le nom du tableau  le pointeur sur le
tableau  contient l'adresse du 1er élément du tableau

Prog. struct. : C III- ... Les tableaux 96


Exemples
double Toto [100];
//Toto est un tableau de 100 doubles

int MyTab [5] = {1,4,8,7,6};


//MyTab est un tableau de 5 entiers initialisé à :
//MyTab [0]= 1, … , MyTab [4]= 6

#define NBELEM 512


float SonTab [NBELEM];
//SonTab est un tableau de NBELEM float

Prog. struct. : C III- ... Les tableaux 97


Tableaux à un seul indice et Pointeur

int Tab[N];

Tab[0] Tab[1] Tab[2] … Tab[N-1]

Tab+i &Tab[i]
pointeur tableau
*(Tab+i) Tab [i]

printf("%d",*Tab); ou printf("%d",Tab[0]);
scanf("%d",Tab+2); ou scanf("%d",&Tab[2]);

Prog. struct. : C III- ... Les tableaux 98


Exemple : Saisir et afficher
les éléments d'un tableau

Mon premier tableau

Prog. struct. : C III- ... Les tableaux 99


Exemple de Tableau 1D :
Les chaînes de caractères (string)
• Déclaration et initialisation :
char chaine[10];
char source[]="Ma premier chaine de char";
char lettre[]={'t','a','r','a','t','a','t','a',0};
• Format :
printf("\nLe contenu de source est %s",source);
scanf("%s",chaine); ou gets(chaine);

Pas besoin de & car le contenu de chaine est une adresse


Prog. struct. : C III- ... Les tableaux 100
Chaînes de caractères
char *pfin;
char cBonjour [] = "Bonjour";

printf("%s\n", cBonjour);
pfin = cBonjour + 3;
printf("%s\n", pfin);

pfin = cBonjour+strlen(cBonjour);
do
{
printf ("%c",*--pfin);
}while (pfin != cBonjour);

Prog. struct. : C III- ... Les tableaux 101


Pour comprendre

'B' 'o' 'n' 'j' 'o' 'u' 'r' Ø

cBonjour pfin ← cBonjour+3

printf("%s\n", cBonjour); Bonjour


pfin = cBonjour + 3;
printf("%s\n", pfin); jour

Prog. struct. : C III- ... Les tableaux 102


Pour comprendre

'B' 'o' 'n' 'j' 'o' 'u' 'r' Ø

cBonjour pfin
strlen(cBonjour) renvoie 7

Adresse pointée par pfin ← Adresse pointée par cBonjour+7

Prog. struct. : C III- ... Les tableaux 103


Chaîne de Caractères
Exemple

!OG

Prog. struct. : C III- ... Les tableaux 104


Tableau de Tableaux
• Déclaration :
Type_donne Indent_Tab_Tab[Nlign][Ncol];
Nlign et Ncol sont des constantes entières littérales
ou symbolique.
• Exemple :
float mat[3][3];
int trice[3][3]={{1,1,1}, {1,1,1}, {1,1,1}};

printf("%d %d %d", trice[0][0],trice[1][1],trice[2][2]);


scanf("%f",&mat[0][0]); ou scanf("%f",mat[0]);

Prog. Struct. - C III - ... Les tableaux 105


Tableau à deux indices
Ligne0 Ligne1

...

NCol NCol NCol

NLign x NCol

Prog. Struct. - C III - ... Les tableaux 106


Tableau à 2 indices et Pointeurs
Tab[i]  &Tab[i][0]
Tab[i] est un pointeur constant sur un tableau de nCol
éléments
Tab est un pointeur constant sur un tableau d’adresses
de tableaux de nCol éléments
Tab[i][j]  *(*(Tab+i)+j)

int **pptab; //pptab => pointeur de pointeur


int tableau[4][4]; // contiendra l'adresse d'une
pptab = tableau; // adresse d'entier

Prog. Struct. - C III - ... Les tableaux 107


Département Génie Civil & Département Mécanique Énergétique

Les fonctions
1. Introduction
2. Mise en œuvre
3. Passage par valeur et par adresse
4. Pour aller plus loin

Prog. Struct. - C IV - Les Fonctions 108


Introduction
Une fonction vue par un débutant
C'est un morceau de code
qui sert à faire quelque chose de précis.

Entrée Fonction Sortie


=
brique

Le but : simplifier le code source, pour ne pas avoir à


réécrire le même code plusieurs fois.

Prog. Struct. - C IV - Les Fonctions 109


Introduction
Une fonction vue du processeur

• C'est un code exécutable terminé par une instruction de retour


situé à une certaine adresse en mémoire.
• À l'appel de la fonction, le processeur exécute le code à partir de
l'adresse de la fonction et l'instruction retour le fait revenir à
l'instruction suivant l'appel.
• Des données peuvent être transmises à la fonction en paramètres.
Lors du retour, une valeur peut être récupérée/renvoyée.

Prog. Struct. - C IV - Les Fonctions 110


Instruction i ;
Appel MaFonction() ;

Adresse Instruction i+2 ;

MaFonction Ligne n°1 de MaFonction()


La suite de MaFonction()
Instruction return();

Prog. Struct. - C IV - Les Fonctions 111


Exemple avec la fonction sqrt() :

Instruction i ;
Adresse X = sqrt(4) ; 
Instruction i+2 ;

4
sqrt(argument) if (argument>0)
 Le calcul de sqrt(4)

return(2) Retour de 2

Prog. Struct. - C IV - Les Fonctions 112


Une fonction vue du programmeur

• En programmation structurée, le programme


est divisé en fonctions qui réalisent chacune une partie de la
tâche. Ceci facilite l'organisation et la mise au point du
programme.
 Un programme est un ensemble de fonctions, qui s'exécute à
partir de la fonction main ()

• Un programmeur professionnel utilise des bibliothèques de


fonctions pour accélérer le développement de son application.

Prog. Struct. - C IV - Les Fonctions 113


Instruction i;
MaFonction(10,x+y,z); z Passage de
x+y paramètres
Instruction_suiv;
10

MaFonction {
Instructions
De MaFonction

return;
}

Prog. Struct. - C IV - Les Fonctions 114


Fonction : Mise en œuvre
#include <stdio.h>

/* 1) Le Prototypage */

int main()
{

/* 3) L'appel */

}

/* 2) La définition */

Prog. Struct. - C IV - Les Fonctions 115


1) Le Prototypage
Type_Ret Ident_fonc (…,Type Argument,…);

Exemples de prototypages :
double CalcDiscri (double Arga,double Argb,double Argc);
int printf (const char *pFormat,… );
void fdouble (double *pVar);

Où ça se trouve dans le programme ?


#include <stdio.h>
// → c'est ICI pour le prototypage des fonctions !!!

int main()
{

}

Prog. Struct. - C IV - Les Fonctions 116


2) La Définition
Arguments formels

Exemple :
double CalcDisc(double Arga,double Argb,double Argc)
{
//Déclaration des variables si besoin
return Argb*Argb-4*Arga*Argc;
}

Localisation :
#include <stdio.h>
//prototypage des fonctions
int main()
{

}
//Définition des fonctions

Prog. Struct. - C IV - Les Fonctions 117


3) L'appel de la fonction
{ Paramètres de la fonction
double ValDisc;

ValDisc = CalcDisc (a,b,c);

}
Où fait-on appel à la fonction ?
Dans n'importe quelle définition de fonction, par ex.
dans la fonction main(), y compris dans sa propre
définition  Récursivité

Prog. Struct. - C IV - Les Fonctions 118


Ma première fonction

\fonctions\exemple1.prj

Prog. Struct. - C IV - Les Fonctions 119


2 types de fonctions
- Les fonctions qui retournent quelque chose (si on
ne met rien, une fonction retourne un entier (int) par défaut).

Pour cela, il faut utiliser l'instruction return :


return expression;

EXEMPLE :
/* Une fonction calculant le produit de deux entiers */
/* Paramètres d'entrée : deux entiers, Type retour : entier */
int calcule_produit (int iExp1, int iExp2)
{
int iProduit;

iProduit = iExp1 * iExp2;


return iProduit;
}
Prog. Struct. - C IV - Les Fonctions 120
2 types de fonctions
- Les fonctions qui ne retournent rien (void). Elles
sont également appelées procédures.
void nom_fonction(déclarations_d'arguments)

EXEMPLE :
/* Procédure affichant le produit de deux entiers */
/* Paramètres d'entrée : deux entiers, Type retour : rien */
void affiche_produit (int iExp1, int iExp2)
{
int iProduit;

iProduit = iExp1 * iExp2;


printf ("Le produit de %d et %d est égal à %d",
iExp1, iExp2, iProduit);
}
Prog. Struct. - C IV - Les Fonctions 121
Passage de paramètres :
par valeurs
On indique au compilateur
que fonction1 est une
//Prototypage
fonction qui ne retourne
void fonction1(double z);
rien et qui admet pour
paramètre un double
//Définition
void fonction1(double z)
{ On donne le code de la
z = z * 2.0; fonction. Le compilateur
printf("z = %lf\n",z); réserve 8 octets de la pile
désignés par z. Pour le
}
moment, le contenu de cette
Lors de l'appel de la fonction, le zone est indéterminé.
contenu de la zone repérée par z
sera * par 2
Prog. Struct. - C IV - Les Fonctions 122
Après l’exécution d'une fonction où les
paramètres sont passés par valeur

Zone de 8 octets
réservée pour x de 20.0
nouveau accessible

La zone mémoire réservée pour z n’est plus


accessible,
et le contenu de x n’a pas été modifié !

Prog. Struct. - C IV - Les Fonctions 125


Passage de paramètres : par
adresse
On indique au compilateur que :
- fonction2 ne retourne rien,
- et admet pour paramètre un pointeur sur double
//Prototypage
void fonction2(double *pz);

void fonction2 (double *pz) 4 octets désignés par pz


{ sont réservés dans la
pile.
*pz = (*pz)*2.0;
}
Ce qui est pointé par pz sera x 2 lors de l'appel de la fonction.

Prog. Struct. - C IV - Les Fonctions 126


Après l’exécution
8 octets
réservés pour x de 40.0
nouveau accessible

La zone mémoire réservée pour pz


n’est plus accessible
et le contenu de x a été modifié par
pile
adressage indirect !

Prog. Struct. - C IV - Les Fonctions 129


Ma deuxième fonction

val_et_adr.prj
Exemple

Prog. Struct. - C IV - Les Fonctions 130


Rappels sur les fonctions

• 3 étapes pour la mise en œuvre : le prototypage,


la définition, et l'appel.

Les arguments/paramètres : constante, variable,
expression, fonction
• Si pas void alors return à la fin de la définition
• Le passage des arguments peut se faire par
valeur ou par adresse si on souhaite modifier la
variable passée en argument.

Prog. Struct. - C IV - Les Fonctions 131


Squelette d'un programme
Zone des directives de préprocesseur
#include …
#define … Que se cache-t-il dans stdio.h ?

Déclaration des variables de portée fichier


Prototypage des fonctions

Définition de la fonction main()


int main()
{
}

Définition de vos fonctions

Prog. Struct. - C IV - Les Fonctions 132


 !
A RETENIR !!!

• Pour modifier le contenu d'une variable déclarée dans la


fonction appelante par la fonction appelée, il est nécessaire de
passer en paramètre l'adresse de cette variable.

• Donc, dans le prototypage et la définition de la fonction,


l'argument doit être un pointeur.

Prog. Struct. - C IV - Les Fonctions 133


Pour aller plus loin

1. La récursivité
2. La portée des variables : locales ou globales
3. Les tableaux comme arguments
4. Les pointeurs sur fonctions

Prog. Struct. - C IV - Les Fonctions 134


1) La Récursivité :
La fonction s'appelle elle-même !

• Exemple :
double Factorielle (int n); //Prototype

double Factorielle (int n)


{
if (n <= 0)
return 1; Condition d'arrêt
return n*Factorielle (n-1);
}
Appel récursif

factorielle.prj

Prog. Struct. - C IV - Les Fonctions 135


2) La portée des variables

• Les variables locales sont temporaires

• Les variables globales sont permanentes

Attention à ne pas toutes les appeler n!!!

varlife.prj

Prog. Struct. - C IV - Les Fonctions 136


3) Tableaux passés en
paramètres à une fonction
• Tableaux à une dimension (un indice)
Type_ret Ident(Type_Tab *ptab, int nSize, …);

OU

Type_ret Ident(Type_Tab Tab[], int nSize, …);

ex : void affichetableau(float *ptab, int Nb);

Prog. Struct. - C IV - Les Fonctions 137


3) Tableaux passés en
paramètres à une fonction

• Tableaux à deux dimensions (2 indices)

Type_ret Ident(Type_Tab Tab[][NCOL], int nLign, …);

OU

Type_ret Ident(Type_Tab (*pTab)[NCOL], int nLign, …);

ex : void affiche2D(float *ptab[10], int Nblig);

Prog. Struct. - C IV - Les Fonctions 138


4) Les Pointeurs sur fonction

• Déclaration
• Affectation
• Utilisation

Prog. Struct. - C IV - Les Fonctions 139


Déclaration d'un pointeur sur
fonction

Type_Val_Ret(*Ident_ptr_Fonc)(Signature_fonc);
Liste ordonnée des types des
Signature_fonc arguments de la fonction sans
les identificateurs des
arguments

Exemple pFonc est un pointeur sur une


fonction retournant un double et
double (*pFonc)(double); admettant un double en
argument.

Prog. Struct. - C IV - Les Fonctions 140


Initialisation, Affectation d'un
pointeur sur fonction
Nécessite
double (*pFonc)(double); #include <math.h>

double (*pTabFonc [3])(double)={sin,cos,tan};

pFonc = MaFonc;

Le prototype de MaFonc doit être connu par le


compilateur.

Prog. Struct. - C IV - Les Fonctions 141


Pointeurs sur fonction

pointfonct.prj

Prog. Struct. - C IV - Les Fonctions 142


Département Génie Civil & Département Mécanique Énergétique

Les types utilisateurs


1. Les structures
2. Les unions
3. Les énumérations

http://iusti.polytech.univ-mrs.fr/~bergougnoux/enseignement.htm

Prog. struct. C
Les types utilisateurs
comment créer ses
propres types de variables
Pour manipuler :
- des nombres complexes,
- des cordonnées (x,y,z) de points,
- des images,
....
- un ensemble de variables qui peuvent être de type ≠

Prog. struct. C V- Les structures 144


De la fiche à la structure
• Pour gérer une clientèle, une bibliothèque, un stock de
pièces détachées, etc…
on a besoin d'informations sur chacun des éléments de
l'ensemble.

• Ces informations sont consignées dans des fiches qui sont


remplies grâce à un formulaire unique.
• C'est le formulaire qui structure les informations contenues
dans les fiches.

Prog. struct. C V- Les structures 145


La fiche d'un élève Polytech

Nom : PIGNON Prénom : François


Adresse : 12 place du marché 13013 Marseille
Département Polytech : MT
Année : 3
Spécialité :aucune
Login : PIGNMT12 Password : juste12
Email : Francois.Pignon@polytech.univ-mrs.fr

Prog. struct. C V- Les structures 146


Traduction Informatique

• Formulaire • Type de donnée


Structure struct modèle

• Fiche • Variable de type objet


struct

• Fichier • Tableau ou liste de Ensemble


variables de type d'objets
struct

Prog. struct. C V- Les structures 147


Déclaration du nouveau type
de donnée
• Syntaxe :

struct nom_struct
{
type_1 ident_champ1;
type_2 ident_champ2,ident_champ3;

type_N ident_champM;

}nom_var1, ... ,nom_varP;

Prog. struct. C V- Les structures 148


Déclaration du nouveau type
de donnée
• Localisation : Après les include
#include <stdio.h>
struct nom_struct
{
type_1 ident_champ1;
type_2 ident_champ2,ident_champ3;
};
//Les prototypes des fonctions
int main()
{

}
Prog. struct. C V- Les structures 149
Exemple 1 : Définition du type POLYTECH

struct POLYTECH
{
char Nom[80];
char Prenom[80];
char Adresse[200]; 9 champs avec des
int Depart; identificateurs  pas
int Annee; contigus mais à la suite
int Spec;
char Login[10];
char Passw[8];
char Email[30];
};

Prog. struct. C V- Les structures 150


Déclaration d'une donnée

• Syntaxe :
struct nom_struct nom_var;

• Exemple :
struct POLYTECH UnEleve; //variable
struct POLYTECH TabElev[250]; //tableau
struct POLYTECH *pElev; //pointeur

Prog. struct. C V- Les structures 151


Accès aux champs de la donnée

• Syntaxe : nom_struct.nom_var

ex : UnEleve.Annee = 1;

• Si pointeur sur type nom_struct :


nom_ptr_struc->nom_var

(*nom_ptr_struc).nom_var

exemple : TabElev->Annee = 1;

Prog. struct. C V- Les structures 152


Ex 1 : accès aux champs de POLYTECH

int main()
{
struct POLYTECH TabElev[250];
struct POLYTECH UnEleve;

printf("\nNom de l'élève :");
scanf ("%s",UnEleve.Nom);

TabElev[10] = UnEleve;
(TabElev+10)->Annee = 1;
}

Prog. struct. C V- Les structures 153


Exemple 1 :Utilisation suite
• Arguments et paramètres d'une fonction,
sans la structure :
void NewElev(char *pNom,char *pPrenom,char
*pAdr,int *pDepart,int *pAnnee,int
*pSpec,char *lplogin,char *ppass,char
*pemail);

•En utilisant la structure :


void NewElev(struct POLYTECH *pNouveau);

structures/POLYTECH.prj
Prog. struct. C V- Les structures 154
Définition de type composé
Structure nommée
struct tComplex
{
double Re;
double Im;
ce nouveau type suit le
modèle struct tComplex
};
typedef struct tComplex Complex;

Le nom de ce nouveau
définition d'un nouveau type type est Complex
Prog. struct. C V- Les structures 155
Exemple 2 : Représentation des
nombres complexes

Complex zI = {0,1.0};

Déclarations des variables
Complex *pz;
zI, pz et zTabVal de type
Complex zTabVal [10]; Complex

pz = &zI;
pz->Re = sqrt(2)/2;
Utilisation de ces
pz->Im = pz->Re;
variables
zTabVal[0].Re = 11.5;
(zTabVal+5)->Im = sqrt(2);

Prog. struct. C V- Les structures 156


Union
Ensemble de variables de type différents pouvant
alternativement occuper la même zone mémoire.
• Syntaxe de déclaration :
la même que pour une structure ...
union jour
{ char lettre;
int numero;
};

• Le stockage en mémoire : tous les champs de l'union


commencent à la même adresse. La taille de l'union est
donc celle du plus grand champ.  On peut donc atteindre
une même zone mémoire de plusieurs façons.

Prog. struct. C V- ... Les unions 157


Énumération
Permet de définir un type par la liste des valeurs qu'il
peut prendre.
• Syntaxe :
enum modele
{ constante_1,constante_2,…,constante_n
};

• Exemple :
enum tBool{FAUX,VRAI};
typedef enum tBool BOOLEEN;
...
enum jours_ouv{lundi,mardi,mercredi,jeudi,vendredi};

Prog. struct. C V-... les énumérations 158


Exemple

enum tdepart{GC,GII,ME,MT};
typedef enum tdepart DEPART;

POLYTECH *pElev;
… /*Mettre une adresse valide dans pElev*/
pElev->Depart = MT;

Prog. struct. C V- Les structures 159


Département Génie Civil & Département Mécanique Énergétique

La gestion de fichiers
#Diapo 160
1. Les Flots
2. Ouverture / Fermeture d'un fichier
3. Lecture / Écriture dans un fichier
4. Formats
1 Fichier sur 1 Disque

• Chemin d'accès "path" :

C:\Repertoire\SousRep1\...\SousRepN\Nom.ext

Structure arborescente de
répertoire, sous répertoires, …
Unité logique Nom du Fichier
• Le mode d'accès et son extension
• Les attributs de protection.

Prog. struct. C VI- La gestion de fichiers 161


Gestion de Fichiers
pour le programmeur

• Transférer une ou des informations d'une


source vers une destination.
• Donc gérer un flot d'informations.

Prog. struct. C VI- La gestion de fichiers 162


Flot d’informations
Source : Destination :

• Mémoire • Mémoire de
octets masse
de masse
• Clavier Flot • Console
Flot//stream
stream
• Port Série • Port Série

• Mémoire • Mémoire

• Carte SD • Carte SD

• ... • ...

Prog. struct. C VI- La gestion de fichiers 163


La direction du Flot

• Dans la gestion d'un flot, au moins l'une des destinations est la


mémoire de l'ordinateur.

• Pour écrire dans le fichier des informations stockées dans la


mémoire, il faut accèder au fichier en écriture.
 Le flot est en sortie.

• Pour lire les informations du fichier et les stocker dans la


mémoire, on accède au fichier en lecture.
 Le flot est en entrée.

Prog. struct. C VI- La gestion de fichiers 164


<stdio.h>
standard input output

C'est là qu'est définie la structure FILE !

Prog. struct. C VI- La gestion de fichiers 165


Ouverture/Fermeture
de flots en C (ANSI)
• Toutes les fonctions de gestion des flots
admettent comme paramètre un pointeur sur
la structure FILE définie dans stdio.h.

• Le flot est ouvert en appelant fopen() qui


affecte une valeur à cette variable pointeur.
Le flot est fermé par fclose().

Prog. struct. C VI- La gestion de fichiers 166


Les Modes d'ouverture
Les flots/fichiers peuvent être ouverts en mode :
• Lecture "r"  la destination existe
"r+"  possibilité d'écriture
• Ecriture "w"  la destination est créée ou ouverte
"w+"  possibilité de lecture
• Ajout "a"  écriture à la fin du fichier
"a+"  possibilité de lecture
Si la lecture ou l'écriture doivent être faits en binaire,
il faut ajouter "b" au mode (ex : "rb").

Prog. struct. C VI- La gestion de fichiers 167


Les Fonctions générales

• Création, ouverture d'un fichier


FILE *fopen(const char *nom,const char *mode)
• Fermeture d'un fichier
FILE *fclose(FILE *stream)
• Création d'un fichier temporaire
FILE *tmpfile(void)
• Test de fin d'un fichier
int feof(FILE *stream)

Prog. struct. C VI- La gestion de fichiers 168


Exemple
#include <stdio.h>
int main()
{
//pointeurs sur fichier
FILE *pFascii,*pFbin;

pFascii = fopen("totoascii.txt","w");
pFbin = fopen("totobin.moi","wb");

fclose(pFascii);
fclose(pFbin);
texte_bin.prj
}

Prog. struct. C VI- La gestion de fichiers 169


Les Flots prédéfinis

3 pointeurs sur structure FILE sont gérés


par le système d'exploitation :
•stdin gère les informations envoyées par
le clavier (entrée).
•stdout gère les informations dirigées vers
l'écran (sortie).
•stderr dirige les informations générées par
les erreurs vers un périphérique de sortie.

Prog. struct. C VI- La gestion de fichiers 170


Exemple

#include <stdio.h>
int main()
{
fprintf(stdout,"1ere alternative à printf()\n");

fputs("\n En voila une autre",stdout);


}
ecran.prj

Prog. struct. C VI- La gestion de fichiers 171


Écriture dans un fichier
• Ecriture au format texte :
int fprintf(FILE *pfile,const char *format,)
/* écrit la chaîne formatée dans le fichier, retourne le nbre de
caractères écrits, ou un nombre <0 si erreur */

int fputc(int caractere,FILE *pfile)


/* écrit le caractère dans le fichier, le caractère écrit est retourné,
EOF sinon */

int fputs(const char *s,FILE *pfile)


/* la chaîne s dans le fichier, et retourne une valeur positive ou
nulle, EOF s'il y a eu une erreur */

• Ecriture au format binaire :


size_t fwrite(const void *source,size_t taille,
size_t nombre,FILE *pfile)
/* écrit nombre objets, chacun ayant la taille indiquée, les uns à la suite
des autres à l'adresse indiquée par source. Renvoie le nombre d'objets
écrits, qui peut être inférieur au nombre demandé (en cas d'erreur) */

Prog. struct. C VI- La gestion de fichiers 172


Lecture dans un fichier
• Lecture au format texte :
int fscanf(FILE *pfile,const char *format,)
/* Lit la chaîne formatée dans le fichier et retourne le nombre de
caractères luts, ou un nombre <0 si erreur */

int fgetc(FILE *pfile)


/* Renvoie le caractère suivant sur le flot indiqué, ou EOF si la fin
du fichier est atteinte ou si une erreur survient. C'est une vraie
fonction */

int fgets(char *s,int n,FILE *pfile)


/* Lit des caractères dans le fichier et les place dans l'espace
pointé par s. S'arrête lorsqu'elle a lu n-1 caractères ou lorsqu'elle
a rencontré un caractère '\n' */

• Lecture au format binaire :


size_t fread(void *dest, size_t taille, size_t
nombre, FILE *pfile)
/* Lit sur le flot indiqué le nombre objets, chacun ayant la taille
indiquée, et les copie les uns à la suite des autres dans l'espace
pointé par destination */
Prog. struct. C VI- La gestion de fichiers 173
Positionnement dans un fichier
• Déplacement :
int fseek(FILE *pfile,long deplacement,int orig)
avec orig = SEEK_SET le début du fichier,
SEEK_CUR la position courante,
SEEK_END la fin du fichier
• Re-positionnement au début du fichier :
void rewind(FILE *pfile)
• ConnaîtreA la
u position dans le fichier :
tilis *flot, fpos_t *ptr)
void fgetpos(FILE e
r av
ec p
/*Place dans ptr la position courante dans le fichier indiqué en
vue de son utilisation par fsetpos*/
réca:
Fixer la position dans le fichier
void fsetpos(FILE *flot, const utiofpos_t *ptr)
n !!

Prog. struct. C VI- La gestion de fichiers 174


Renommer ou Supprimer
un fichier
• Renommer
int rename(const char *ancienNom, const char
*nouveauNom);
• Supprimer
int remove(const char *FichieraSuppr);

Prog. struct. C VI- La gestion de fichiers 175


Formats d'écriture

%[flags][width][.precision][{h|L|l}]type
• flags (-,+,0, ,#) : mise en forme du texte
• width : Longueur minimum du texte
• .precision : Nombre de chiffres après la virgule (.)
• type : 1) Flottants e,E,f,g,G
2) Entiers généralisés c,d,i,o,u,x,X
3) Chaînes de caractères s
[{h|L|l}] en option h pour court, l ou L pour long

Prog. struct. C VI- La gestion de fichiers 176


Formats de lecture

%[*] [width] [{h | l }]type

• Même signification de width et de type.


• * signifie que la lecture suivante sera faite, mais
non transférée en mémoire.

Prog. struct. C VI- La gestion de fichiers 177


Flots textes formatés
• En écriture :
int printf (const char *format,)
int fprintf (FILE *pfile,const char *format,)
int sprintf (char *pdesti,const char *format,)

• En lecture :

int scanf (const char *format,)


int fscanf (FILE *pfile,const char *format,)
int sscanf (const char *psource, const char
*format,)

Prog. struct. C VI- La gestion de fichiers 178


Exemple 1 :
texte formaté -> fichier binaire
...
int main()
{
FILE *srce; /* fichier de texte */
FILE *dest; /* fichier binaire */
...
if ((srce = fopen(nomfich, "r")) == NULL)
exit(ERREUR_OUVERTURE);
...
for (;;) //tant qu'il y a des choses à lire
{
if ((nb=fscanf(srce, "%s %s\n", art.nom, art.prenom)) != 2)
break;
fichier.prj
...
}
...
} Prog. struct. C VI- La gestion de fichiers 179
Exemple 2 : les formats

#include <stdio.h>
int main()
{
const double pi=4*atan(1);

printf("%lf\n",pi);
printf("%1.3lf",pi);
}

formats.prj

Prog. struct. C VI- La gestion de fichiers 180


Département Génie Civil & Département Mécanique Énergétique

Programmation modulaire
(multi-fichiers)
1. Généralités
2. Mise en œuvre
3. Macros
4. Variables de portée fichier
Généralités
• Un logiciel doit être conçu comme la réunion de
plusieurs modules.
• Chaque module regroupe des fonctions de même
nature (Graphisme, Algorithmes principaux, interface
utilisateur, …)
• Un seul des modules contient la fonction main ()

Prog. Struct. C IX - Prog. Modulaire 182


Les avantages …
• En séparant les fonctionnalités du projet en unités le
moins possible interdépendantes, on simplifie la mise
au point du logiciel qui se fait module par module.
• La compilation est beaucoup plus rapide, car seuls les
modules modifiés sont compilés.
• Certains modules (s’ils sont bien conçus) peuvent être
ré-utilisés dans d’autres projets.

Prog. Struct. C IX - Prog. Modulaire 183


Conséquences :
Le fichier *.prj s'agrandit

Prog. Struct. C IX - Prog. Modulaire 185


Le contenu de l'en-tête
 Directives de pré-processeur : #xxxx
Ex : #include <stdio.h> ou #define PI 3.14159
 Déclaration des types utilisateurs : struct
Ex : struct POLYTECH

 Définition des variables de portée fichier


Ex : static int panelhandle;
 Déclaration des variables définies de manière externe :
extern
 Déclaration des prototypes des fonctions
Ex : void ma_fonction(void);
++++  Mon_Fichier.h
Prog. Struct. C IX - Prog. Modulaire 186
 La directive #include
• Syntaxe :
#include <stdio.h>
#include "[nomchemin\…\]nomfichier.h"

• Action : Inclure
Avant la compilation, le pré-processeur met en lieu et
place de la directive le fichier.h

Prog. Struct. C IX - Prog. Modulaire 187


 La directive #include
/* Fichier.h
contenant les
prototype des #include "fichier.h"
fonctions de
fichier.c */ int main()
{
}
/*fichier .c */

Prog. Struct. C IX - Prog. Modulaire 188


 La directive #define
• Syntaxe :
#define BUFSIZE 512
#define PI 3.14159

• Action : Rechercher/Remplacer
Partout où la chaîne de caractères BUFSIZE est
rencontrée, elle est remplacée par 512
La compilation se fera sur le code transformé!

Prog. Struct. C IX - Prog. Modulaire 189


#define pour la taille des tableaux
Le programme est
#define NMAX 10 développé avec 10 pour
.... remplacer NMAX.
Après le programmeur
int main() pourra mettre 10000 ...
{
float vect[NMAX];

for(i=0 ; i<NMAX; i++)


{ ....
}
}
Prog. Struct. C IX - Prog. Modulaire 190
Comment faire une Macro ?

Au sein d'un #define


• Exemple :
#define MAX(a,b) (((a)>(b))?(a):(b))
MAX(expr1,expr2) sera utilisée comme
(((expr1)>(expr2))?(expr1):(expr2))

Les parenthèses servent à fixer les priorités.

Prog. Struct. C IX - Prog. Modulaire 191


Comment faire une Macro ?

• Autre Exemple :
#define MAJEUR(age) if (age>=18)\
printf("Vous etes majeur");
int main()
{
MAJEUR(22);
}
Lors de l'exécution il s'affichera :
Vous etes majeur

Prog. Struct. C IX - Prog. Modulaire 192


Avantages des macros

• Remplacer des fonctions courtes.


Le temps d’exécution du programme  puisqu’il n’y a
pas d’appel de fonction.
Mais le code exécutable est plus long.

• Les compilateurs modernes utilisent les macros pour


générer automatiquement du code répétitif à la place du
programmeur.

Prog. Struct. C IX - Prog. Modulaire 193


Définition de constantes
#define CONSTANTE
Il est alors possible d'utiliser #ifdef et #endif
#define WINDOWS
#ifdef WINDOWS
//code source pour Windows
#endif
#ifdef LINUX
//code source pour Linux
#endif

Prog. Struct. C IX - Prog. Modulaire 194


Les variables globales
en programmation modulaire
• Une variable globale a la portée et la durée de vie du
programme.

Prog. Struct. C IX - Prog. Modulaire 195


Les variables globales
en programmation modulaire

Pour être reconnue par le compilateur dans d'autres


modules du programme, elle doit :
- y être déclarée mais sans réservation de
Mémoire
- et précédée de extern dans un fichier .h à inclure
dans les fichiers .c, où cette variable est utilisée.

Prog. Struct. C IX - Prog. Modulaire 196


Les variables globales
(suite)
• Si, on veut restreindre la portée de cette variable au seul
module où elle a été définie, on fait précéder sa
définition de static.
• Dans d’autres modules, une autre variable de portée
fichier de même identificateur pourra être définie sans
conflit de déclaration.

Prog. Struct. C IX - Prog. Modulaire 197


Exemple

modulaire.prj

Prog. Struct. C IX - Prog. Modulaire 198


Département
Département Génie
Génie Civil
Civil &
& Département
Département Mécanique
Mécanique Énergétique
Énergétique

Allocation Dynamique
de Mémoire
1. Généralités
2. Les fonctions malloc() & Cie
Quand l'utiliser ?

• Si le nombre d’objets à stocker dans le tableau n’est


connu qu’à l’exécution, il faut avoir recours à
l’allocation dynamique.

• Pour les tableaux à plusieurs indices même si les


dimensions sont connues à priori.
• Pour stoker des données volumineuses.

Prog. struct. C X - Alloc. dyn. mem. 200


Déclaration de variables
=
Demande d'allocation mémoire
int maVariable = 12;
1) le programme demande à Windows la permission
d'utiliser un peu de mémoire,
2) Windows répond en indiquant où votre
programme peut stocker maVariable
 il lui alloue une adresse
3) lorsque la fonction est terminée, maVariable
est automatiquement supprimée de la mémoire.
Votre programme dit à Windows "Je n'ai plus besoin
de cet espace mémoire"

Prog. struct. C X - Alloc. dyn. mem. 201


Connaître la taille des variables grâce à
sizeof()

sizeof(char)  1
sizeof(short int)  2
sizeof(int)  4
sizeof(double)  8
sizeof(int *)  4

Prog. struct. C X - Alloc. dyn. mem. 202


Configuration de la mémoire
pendant l’exécution
Le tas (heap) est
la mémoire
Tas Variables inutilisée lors de
statiques l’exécution du
programme.
Programme Pile

OS (windows par ex.)

C'est là que va se faire l'allocation dynamique de


mémoire.
Prog. struct. C X - Alloc. dyn. mem. 203
La Mise en œuvre
Il faut :
• Une variable de type pointeur sur la donnée
à stocker
• Utiliser la fonction malloc() ou une similaire
pour affecter une adresse à cette variable.
• Libérer la mémoire lorsque l'on en n'a plus
besoin avec la fonction free().

Prog. struct. C X - Alloc. dyn. mem. 204


La fonction malloc()
• Prototype dans <stdlib.h> ou <malloc.h> :
void * malloc (size_t nSize);

• Appel :
typedef struct POLYTECH_EL ELP;
ELP *pTabElev;
int nNbEl;

pTabElev = (ELP*)malloc(nNbEl* sizeof(ELP));

On type l'adresse Taille d'une variable de type ELP


Prog. struct. C X - Alloc. dyn. mem. 205
La fonction malloc()…
• Erreur mémoire insuffisante :
Quand la demande ne peut pas être satisfaite, la
fonction malloc()retourne le pointeur NULL.
D’où le test d’erreur :
if (pTabElev == NULL)
{
… Gestion Erreur
}

Prog. struct. C X - Alloc. dyn. mem. 206


Allocation pour un tableau à 2
dimensions
Exemple :
double **MAT;
...
MAT = malloc(nl * sizeof(double *));
if (MAT == NULL)
return 0;
for (i = 0; i < nl; i++)
{ MAT[i] = malloc(nc * sizeof(double));
}

Prog. struct. C X - Alloc. dyn. mem. 207


La fonction calloc()
• Prototype :
void *calloc(size_t nElem,size_t Taille_Elem);

• Appel :
pTabElev =(struct POLYTECH_EL*)calloc (nNbEl,
sizeof(struct POLYTECH_EL));

• Mise à 0 des octets réservés.


• Si mémoire insuffisante réagit comme malloc()

Prog. struct. C X - Alloc. dyn. mem. 208


La fonction realloc()

• Prototype :
void *realloc (void *ptrAlloc,size_t New_Size);

• Si la taille de la mémoire précédemment allouée doit être


réduite.
Le contenu du pointeur et de la mémoire sont préservés.

Prog. struct. C X - Alloc. dyn. mem. 209


La fonction free()
• Prototype :
void free (void * pMemAlloue);

• Appel :
free(pTabElev);

• Action :
Libère la zone mémoire allouée par une des fonctions de
la famille malloc().
Doit s’utiliser dès que l’on n’a plus besoin de cette
mémoire.

Prog. struct. C X - Alloc. dyn. mem. 210


La fonction free() …

• Si la fonction free() a pour paramètre la valeur


NULL, elle s’exécute sans erreur et sans rien faire.

•  si l'adresse passée à free() ne résulte pas d’un


appel
! à une fonction de la famille malloc(), le
résultat est catastrophique !!!

Prog. struct. C X - Alloc. dyn. mem. 211


Exemple

allocat.prj

Prog. struct. C X - Alloc. dyn. mem. 212


Les listes chaînées
- Ça sert à organiser ses données en mémoire.
- C'est beaucoup plus flexible qu'un tableau !!!
- mise en œuvre avec des structures...

Prog. struct. C X - Alloc. dyn. mem. 213


Listes chaînées vs Tableaux

Une fois créé, on ne


1 Tableau peut plus le modifier !

Prog. struct. C X - Alloc. dyn. mem. 214


Listes chaînées vs Tableaux

1 Liste Une fois créée, on peut la modifier !


Prog. struct. C X - Alloc. dyn. mem. 215
Construction d'une liste
chaînée
Exemple : une liste de nombres ou d'étudiants …

Comment créer un ?
typedef struct Element Element;
struct Element
{
int nombre;
Element *suivant_sur_la_liste;
};

Prog. struct. C X - Alloc. dyn. mem. 216


Pour contrôler l'ensemble de la liste, il faut :
typedef struct Liste Liste;
struct Liste
{
Element *premier_sur_la_liste;
};
Puis il faut écrire les fonctions gérant la liste :
- pour l'initialiser,
- pour ajouter un élément,
- pour supprimer un élément,
- pour afficher le contenu de la liste,
- pour supprimer la liste entière..

Prog. struct. C X - Alloc. dyn. mem. 217


Exemple de fonction pour l'initialisation :
Liste *initialisation(void)
{
Liste *liste=malloc(sizeof(*liste));
Element *element=malloc(sizeof(*element));
if (liste==NULL || element==NULL)
{
exit(EXIT_FAILURE);
}
element->nombre=0;
element->suivant_sur_la_liste=NULL;
liste->premier_sur_la_liste=element;
}

Prog. struct. C X - Alloc. dyn. mem. 218


Pour en savoir plus
A la bibliothèque en salle 112 :
• H. Garreta, C: Langage, bibliothèque, applications,
InterEditions (1992)
• B. Kernighan et D. Ritchie, Le Langage C, Masson
(Dernière Edition) - Pour se perfectionner.
• B. Gottfried, Programmation en C, Série Schaum,
Pour les exercices.
• H. Schildt, Référence Complète C++, First Interactive
(2002).

Progr. struct. - C Bibliographie 219


Pour en savoir plus
Cours de C sur le Web :
• http://www.commentcamarche.net
• Henri Garreta
http://www.dil.univ-mrs.fr/~garreta
• http://c.developpez.com/cours
• http://www.siteduzero.com/tutoriel-3-14189-apprenez-
• http://iusti.polytech.univ-mrs.fr/~bergougnoux/enseignement.htm

IDE en open source Dev-C++


• À télécharger à partir de
http://www.commentcamarche.net

Progr. struct. - C Sources 220

Vous aimerez peut-être aussi