Vous êtes sur la page 1sur 41

AGP: Algorithmique et programmation

Tanguy Risset, Stéphane Ubéba


tanguy.risset@insa-lyon.fr, Stéphane.Ubéda@insa-lyon.fr
Lab CITI, INSA de Lyon
Version du November 20, 2007

- p. 1/81

Présentation du cours

introduction ■
● Présentation du cours
● Introduction
● Rappels d’architecture
■ Enseignants:
● Rappels d’architecture ◆ Cours 24h: Tanguy Risset, Stéphane Ubeda
● Compilation
● logiciel ◆ TD 30:
Les bases du C ◆ TP 28h
Les fonctions ■ Déroulement du cours:
Les entrées-sorties ◆ Principes de la programmation en C
Introduction ◆ Principes de l’algorithmique
Pointeur de fonctions ◆ Notions de recherche opérationnelle
Erreurs courante en C

- p. 2/81
Références utiles

introduction
● Présentation du cours
■ livres:
● Introduction ◆ Le langage C, Kernighan & Ritchie, Masson, 1990
● Rappels d’architecture
● Rappels d’architecture la référence pour la programmation en C ANSI
● Compilation
● logiciel ◆ Introduction à l’algorithmique, T. Cormen, C. Leiserson, R.
Les bases du C Rivest, 1994, Dunod
Les fonctions Approche complète et pédagogique de l’algorithmique
Les entrées-sorties ■ Sur le web
Introduction ◆ Poly de Bernard Cassagne (votre poly):
Pointeur de fonctions http://www-clips.imag.fr/commun/bernard.cassagne/Introduction_ANSI_C.htm
Erreurs courante en C ◆ C reference manual (version épurée du Kernighan &
Ritchie avec grammaire du langage):
http://cm.bell-labs.com/cm/cs/who/dmr/cman.pdf
◆ C library reference guide:
http://www.acm.uiuc.edu/webmonkeys/book/c_guide/
◆ Cours d’Anne Canteaut (beaucoup utilisé dans ces
transparents)
http://www-rocq.inria.fr/codes/Anne.Canteaut/COURS_C/

- p. 3/81

Introduction

introduction
● Présentation du cours
■ Historique
● Introduction ◆ Créé par Dennis Ritchie pour écrire Unix pour le PDP -11
● Rappels d’architecture
● Rappels d’architecture (publication 1978)
● Compilation
● logiciel ◆ Standard ANSI C (1990)
Les bases du C ■ Pourquoi C?
Les fonctions ◆ Avantages
Les entrées-sorties ■ Performance

Introduction (http://shootout.alioth.debian.org),
Pointeur de fonctions portabilité, standard, proche de la machine
Erreurs courante en C ■ Permet de comprendre les mécanismes de l’exécution

de programmes ⇒ bonnes bases pour tous les autres


langages (bibliothèques, portabilité, etc.).
◆ Inconvénients
■ Dangereux (bugs!), nécessite beaucoup de rigueur,

programmation bas niveau,


■ Peu adapté aux ordinateurs non standard (temps réel,

systèmes distribués, parallélisme, etc.)


- p. 4/81
Rappels sur l’architecture d’un ordinateur

introduction
● Présentation du cours
■ Un ordinateur de bureau est composé (au moins):
● Introduction ◆ D’un processeur
● Rappels d’architecture
● Rappels d’architecture ◆ D’une mémoire (dite vive: rapide et non rémanente)
● Compilation
● logiciel ◆ D’un espace de stockage (disque dur: lent, rémanent)
Les bases du C ◆ De périphériques d’entrée/sortie (écran, claviers, etc.)
Les fonctions ■ Principe du processeur programmable:
Les entrées-sorties ◆ Le processeur lit un programme en mémoire (programme
Introduction exécutable, dépendant du type de processeur).
Pointeur de fonctions ◆ En fonction de ce programme
Erreurs courante en C ■ Il lit ou écrit des données en mémoire à une certaine

adresse mémoire (nombre entier sur 32 bits)


■ Il effectue des calculs entre ces données

- p. 5/81

Rappels d’architecture

introduction 7fffffffhex
● Présentation du cours
● Introduction
Stack seg
● Rappels d’architecture
● Rappels d’architecture
● Compilation
● logiciel
Interrupts
Processor
Les bases du C

Les fonctions
Cache

Les entrées-sorties
Dynamic data
Memory–I/O bus Data segm
Introduction
Static data
Pointeur de fonctions I/O I/O I/O 10000000hex
Main controller controller controller
Erreurs courante en C
memory Text segm
Disk Disk Graphics Network 400000hex
output Reserved

- p. 6/81
Architecture vue du programmeur

introduction
● Présentation du cours
■ Les systèmes modernes permettent
● Introduction ◆ D’exécuter plusieurs programmes indépendant en
● Rappels d’architecture
● Rappels d’architecture parallèle (processus)
● Compilation
● logiciel ◆ D’accéder à un espace mémoire plus grand que la
Les bases du C mémoire physique disponible (mémoire virtuelle)
Les fonctions ■ Pour le programmeur: tout cela est transparent
Les entrées-sorties ◆ Un seul programme s’exécute avec une mémoire très
Introduction grande disponible
Pointeur de fonctions
■ La mémoire vue du processeur contient:
Erreurs courante en C
◆ Le code à exécuter
◆ Les données statiques (taille connue à la compilation)
◆ Les données dynamiques (taille connues à l”exécution: le
tas, et l’espace necessaire à l’exécution elle-meme: la
pile)
■ Le programmeur lui ne voit que les données (statiques et
dynamiques)

- p. 7/81

Processus de compilation

introduction
● Présentation du cours
■ le processus complet va traduire un programme C en code
● Introduction
● Rappels d’architecture
exécutable (le chargement et l’exécution auront lieu plus
● Rappels d’architecture tard).
● Compilation
● logiciel code asm obj
compilateur assembleur
.c .s .o
Les bases du C

Les fonctions
lib
édition des
Les entrées-sorties .a liens

Introduction
Exécution
Pointeur de fonctions chargement exe
Simulation
Erreurs courante en C

■ On nomme souvent compilation l’ensemble


compilateur+assembleur
■ Le compilateur GCC inclut aussi un assembleur et un éditeur
de lien (accessibles par des options)

- p. 8/81
Votre processus de compilation

introduction
● Présentation du cours
■ Le programmeur:
● Introduction ◆ Écrit le programme C: ici le dans le fichier ex.c
● Rappels d’architecture
● Rappels d’architecture ◆ Compile vers un programme objet ex.o
● Compilation
● logiciel ◆ Fait l’édition de lien pour générer l’executable ex
Les bases du C
contenu de ex.c
Les fonctions
ex.c ex.o
Les entrées-sorties
gcc −c ex.c

Introduction

Pointeur de fonctions
stdio.h libstdio.a
gcc ex.o −o ex
Erreurs courante en C

ex
gcc ex.c −o ex

- p. 9/81

Dénomination à retenir

introduction
● Présentation du cours
■ Le programme C que vous écrivez est le programme source
● Introduction
● Rappels d’architecture
(ex.c)
● Rappels d’architecture
■ Le programme source est compilé en un programme objet
● Compilation
● logiciel
par le compilateur (ex.o)
Les bases du C
■ Le programme source inclut un fichier d’en-tete (stdio.h)
Les fonctions
pour vérifier les noms des fonctions externes utilisées
Les entrées-sorties
(printf)
Introduction
■ le programme executable est construit par l’éditeur de liens
Pointeur de fonctions
grâce au programme objet et aux bibliothèques.
Erreurs courante en C
■ Les bibliothèques (library en ex.o
ex.c
gcc −c ex.c
anglais) sont des codes
assembleurs (i.e. déjà compilés) de
stdio.h
fonctions fréquements utilisées. Ici libstdio.a
gcc ex.o −o e

la bibliothèque utilisée est


libstdio.a qui contient le code gcc ex.c −o ex
ex
de la fonction printf

- p. 10/81
Notions de génie logiciel

introduction
● Présentation du cours
■ Pour développer une application, on parle de logiciel plutôt
● Introduction
● Rappels d’architecture
que de programme
● Rappels d’architecture
● Compilation
■ Un logiciel est plus qu’un programme
● logiciel
■ Le cycle de vie du logiciel inclut:
Les bases du C
◆ L’analyse du problème à résoudre
Les fonctions
◆ La conception d’une solution (spécification)
Les entrées-sorties
◆ Le développement de la solution (programme)
Introduction
◆ Le test du programme
Pointeur de fonctions
◆ La livraison avec documentation associée
Erreurs courante en C
◆ La maintenance

- p. 11/81

Outils pour le développement logiciel

introduction
● Présentation du cours
■ Méthodes
● Introduction ◆ Réfléchir avant d’agir !
● Rappels d’architecture
● Rappels d’architecture ◆ règles de développement (Merise, programmation par
● Compilation
● logiciel test)
Les bases du C ◆ Language objet: C++, Java
Les fonctions ■ Outils
Les entrées-sorties ◆ Gestionnaire de compilation : make
Introduction ◆ Debugger : gbd, ddd, ....
Pointeur de fonctions ◆ Environnements de développement (intègrent tout):
Erreurs courante en C eclipse, VisualC++

- p. 12/81
Les bases du C

introduction ■ Instruction, expression, programme


Les bases du C
● Syntaxe ■ Éléments de base
● types de base
● Les opérateurs
◆ Variable et types de base
● Types construits
● Les tableaux
◆ Opérateurs
● chaînes de caractères
◆ Types construits
● contrôle de flot
◆ Opération de Contrôle de flôt
Les fonctions
◆ Fonctions et passage de paramètres
Les entrées-sorties
◆ Entrées-sorties
Introduction
◆ Visibilité et durée de vie des variables
Pointeur de fonctions

Erreurs courante en C
■ Exemple: le tri d’un tableau d’entier

- p. 13/81

Syntaxe

introduction ■ La syntaxe est définie par des règles de grammaire.


Les bases du C
● Syntaxe
■ Extrait de la grammaire:
● types de base
● Les opérateurs
expression::
● Types construits primary asgnop::
● Les tableaux
● chaînes de caractères | expression binop expression =
● contrôle de flot
| expression asgnop expression | +=
Les fonctions
| .... | ...
Les entrées-sorties
primary:: binop::
Introduction
identifier +
Pointeur de fonctions
| string | -
Erreurs courante en C
| constant | ...
| ...
■ x = 0 , a + b, a+=1 sont syntaxiquement corrects
(respectent la grammaire)
■ Un programme syntaxiquement correct n’est pas forcément
un programme C valide. Exemple: 1 = 0 est
syntaxiquement correct mais sémantiquement incorrect.
- p. 14/81
Expression, Instruction

introduction ■ Une expression est une suite de composants élémentaires syntaxiquement correcte,
Les bases du C par exemple: x = 0 ou bien
● Syntaxe (i >= 0) && (i < 10)
● types de base
● Les opérateurs ■ En C chaque expression produit:
● Types construits
◆ une action (modification possible de l’état des variables en mémoire)
● Les tableaux
● chaînes de caractères ◆ un résultat (valeur renvoyée par l’expression)
● contrôle de flot
■ Une instruction est une expression suivie d’un point-virgule. Le point-virgule signifie en
Les fonctions
quelque sorte “évaluer cette expression et oublier le resultat”.
Les entrées-sorties ■ Plusieurs instructions peuvent être rassemblées par des accolades { et } pour former
Introduction une instruction composée (ou bloc) qui est syntaxiquement équivalent à une
instruction. Par exemple,
Pointeur de fonctions
if (x != 0)
Erreurs courante en C
{
z = y / x;
t = y % x;
}

- p. 15/81

Structure d’un programme C

introduction ■ Un programme C se présente de la façon suivante :


Les bases du C
● Syntaxe directives au préprocesseur
● types de base
● Les opérateurs déclarations de variables globales
● Types construits
● Les tableaux fonctions secondaires
● chaînes de caractères
● contrôle de flot

Les fonctions
int main()
Les entrées-sorties
{ déclarations de variables internes
Introduction
instructions
Pointeur de fonctions
}
Erreurs courante en C

■ La fonction main est exécutée lors de l’exécution du


programme.
■ Le résultat de la fonction main est le résultat de l’exécution
du programme (code d’erreur en général)

- p. 16/81
Variables

introduction ■ La notion de variable est très importante en programmation


Les bases du C
● Syntaxe
■ Du point de vue sémantique, une variable est une entité qui
● types de base
● Les opérateurs
contient une information :
● Types construits
◆ Une variable possède un nom, on parle d’identifiant
● Les tableaux
● chaînes de caractères ◆ Une variable possède une valeur qui change au cours de
● contrôle de flot

Les fonctions
l’exécution du programme
◆ Une variable possède un type qui caractérise l’ensemble
Les entrées-sorties

Introduction
des valeurs qu’elle peut prendre
Pointeur de fonctions
■ Du point de vue pratique, une variable est une manière
Erreurs courante en C
mnémotechnique pour désigner une partie de la mémoire.
■ En C les noms des variables sont composés de la manière
suivante:
une suite de caractères parmis :
◆ les lettres (minuscules ou majuscules, mais non
accentuées),
◆ les chiffres (sauf en début de nom),
◆ le “blanc souligné” (_).
- p. 17/81

Types de base en C

introduction ■ En C, les variables doivent être déclarées avant d’être


Les bases du C
● Syntaxe
utilisées, on dit que C est un langage typé
● types de base
● Les opérateurs
■ Les types de base en C sont désignés par des spécificateurs
● Types construits
● Les tableaux
de type qui sont des mots clefs du langages:
● chaînes de caractères ◆ les caractères (char),
● contrôle de flot
◆ les entiers (int, short, , unsigned long)
Les fonctions
◆ les flottants (nombres réels, float, double).
Les entrées-sorties
◆ Il n’y a pas de type booleen, ils sont codés par des int
Introduction

Pointeur de fonctions
■ Une instruction composée d’un spécificateur de type et
Erreurs courante en C
d’une liste d’identificateurs éventuellement initialisés séparés
par une virgule est une déclaration. Par exemple:
int a;
int b = 1, c;
double x = 2.38e4;
char message[80];
■ Il existe de nombreuses conversions de types implicites

- p. 18/81
Représentation de l’information

introduction ■ Le type d’une variable indique au compilateur la manière de


Les bases du C
● Syntaxe
stocker la variabe en mémoire
● types de base
● Les opérateurs
■ Il est important de connaître comment sont stockées les
● Types construits
● Les tableaux
variables car C propose de nombreuses manipulations au
● chaînes de caractères
● contrôle de flot
niveau bit.
Les fonctions
■ La mémoire est une suite de bit structurée en octets (8 bits)
Les entrées-sorties
puis en mots (4 octets, 32 bits).
Introduction ■ L’adresse 1084 doit se lire comme “le 1084eme octet de la
Pointeur de fonctions mémoire”
Erreurs courante en C ■ On utilisera trois notations pour représenter les valeurs
entières en mémoire.
◆ La notation décimale usuelle (10 chiffres): 12dec vaut la
valeur 12
◆ La notation binaire (2 chiffres): 1100bin vaut la valeur 12
◆ La notation hexadécimale (16 chiffres) Chex vaut la valeur
12 (essentiellement pour représenter les adresses).

- p. 19/81

Les types entiers


mot-clef taille dénomination remarques
char 8 bits caractère peut être utilisé comme entier
introduction
short 16 bits entier court
Les bases du C
● Syntaxe
● types de base
int 32 bits entier
● Les opérateurs
● Types construits
long >=32 bits entier long souvent 64 bits
● Les tableaux
● chaînes de caractères
● contrôle de flot
■ En C les entiers signés sont représentés en complément à
Les fonctions
2, c’est à dire (pour un entier n sur 32 bit):
◆ le bit de poids fort (bit 32) représente le signe (0 pour
Les entrées-sorties
positif, 1 pour négatif)
Introduction
◆ Si l’entier est positif: les 31 autres bits correspondent à la
Pointeur de fonctions
décomposition de l’entier en base 2.
Erreurs courante en C
◆ Si l’entier est négatif les 31 autres bits correspondent à la
décomposition de l’entier 231 − |n|
◆ pour int n; on a donc les contraintes: −231 <= n < 231

- p. 20/81
Les types entier

introduction ■ Les mots-clef des types peuvent être précédés d’attributs.


Les bases du C
● Syntaxe
Par exemple unsigned int n indique que l’entier n est
● types de base
● Les opérateurs
positif, la représentation en complément à deux n’est pas
● Types construits utilisée on a alors 0 <= n < 232
● Les tableaux
signed char [−27 ; 27 [
● chaînes de caractères
● contrôle de flot
unsigned char [0; 28 [
short int [−215 ; 215 [
[0; 216 [
Les fonctions
unsigned short int
Les entrées-sorties int [−231 ; 231 [
unsigned int [0; 232 [
Introduction

Pointeur de fonctions
■ Le fonction sizeof calcul la taille d’un type ou d’une
Erreurs courante en C
expression. Le résultat est un entier égal au nombre d’octets
nécessaires pour stocker le type ou l’objet. Par exemple
ci-dessous taille prendra la valeur 2 les deux fois
unsigned short x;
taille = sizeof(unsigned short);
taille = sizeof(x);

- p. 21/81

Les types flottants

introduction
mot-clef taille DEC Alpha Taille PC Intel
Les bases du C
● Syntaxe float 32 bits 32 bits flottant
● types de base
● Les opérateurs double 64 bits 64 bits flottant double précision
● Types construits
● Les tableaux long double 64 bits 128 bits flottant quadruple précision
● chaînes de caractères
● contrôle de flot
■ Les flottants sont généralement stockés en mémoire sous la
Les fonctions

Les entrées-sorties
représentation de la virgule flottante normalisée. On écrit le nombre
Introduction
sous la forme
Pointeur de fonctions signe 0, mantisse B exposant
Erreurs courante en C (12, 3 ⇔ 0.123 ∗ 102 ). En général, B=2. Le digit de poids fort de la
mantisse n’est jamais nul.
■ Par exemple dans le standard EE754, en simple précision ( 32 bits):
s igne Mantisse Exposant
1bit 8 bits 23 bits

- p. 22/81
Les caractères

introduction ■ Un char peut contenir n’importe quel élément du jeu de caractères de la machine
Les bases du C utilisée.
● Syntaxe
■ un char est codé sur un octet ;
● types de base
● Les opérateurs ■ Le jeu de caractères utilisé correspond généralement au codage ASCII (sur 7 bits).
● Types construits
● Les tableaux ■ La plupart des machines utilisent désormais le jeu de caractères ISO-8859-1 (aussi
● chaînes de caractères
● contrôle de flot
appelée ISO-LATIN-1) dont les 128 premiers caractères correspondent aux caractères
ASCII.
Les fonctions
■ extrait de la table ASCII:
Les entrées-sorties
caractère valeur valeur · caractère valeur valeur
Introduction

Pointeur de fonctions
représenté (dec) (hex) représenté (dec) (hex)
Erreurs courante en C ! 33 21hex A 65 41hex
" 34 22hex B 66 42hex
# 35 23hex C 67 43hex
... ... ... ... ... ...
0 48 30hex a 97 61hex
1 49 31hex b 98 62hex
2 50 32hex ... ... ...
- p. 23/81

Les constantes

introduction ■ Les valeurs exprimées dans un programme C sont des


Les bases du C
● Syntaxe
constantes
● types de base
● Les opérateurs
■ Les constantes entière peuvent être exprimées en décimal
● Types construits
● Les tableaux
(int i=12) ou en hexadécimal (int i=0xA),
● chaînes de caractères
● contrôle de flot
■ On peut aussi indiquer qu’elle doivent être stockées sur un
Les fonctions long (12L) ou en unsigned (12U).
Les entrées-sorties ■ Les constantes réelles suivent le même principe
Introduction ■ 12.34 (double), 12.3e-4, (double), 12.34F (float),
Pointeur de fonctions
12.34L (Long)
Erreurs courante en C
■ Les caractères imprimable sont repérentés entre cotes (’):
char a=’Z’
■ Les caractères non imprimables sont représentés en code
octal (base 8) précédé d’un antislash, Les plus fréquent ont
des représentations standard: \n nouvelle ligne, \r retour
chariot, \t tabulation horizontale
\f saut de page,
- p. 24/81
Constantes et variables

introduction ■ La notion de constante n’est pas limitée aux valeurs fixes


Les bases du C
● Syntaxe
■ Une constante est une valeur non modifiable, par exemple
● types de base
● Les opérateurs
l’adresse d’une variable.
● Types construits
● Les tableaux ■ Il existe une différence fondamentale avec les variables: il
● chaînes de caractères
● contrôle de flot n’y a pas de place réservée pour une constante dans la
Les fonctions mémoire lors de l’exécution d’un programme.
Les entrées-sorties ■ C’est le compilateur qui met en dur la valeur de la constante
Introduction lorsqu’il génère l’instruction:
Pointeur de fonctions j=i+10⇒ add Rj,Ri,#10
Erreurs courante en C

- p. 25/81

Les opérateurs

introduction ■ affectation: variable = expression


Les bases du C
● Syntaxe
■ opérateurs arithmétiques +,-,*,/,%,
● types de base
● Les opérateurs
expression-1 op expression-2
● Types construits
● Les tableaux ■ opérateurs relationnels >,<, >=,<=,==,!=
● chaînes de caractères
● contrôle de flot ■ opérateurs logiques booléens &&, ||, !
Les fonctions
■ opérateurs logiques bit à bit &, |, ˆ , ˜ ,«,»
Les entrées-sorties
■ opérateurs d’affectation composée +=, -=, *=, /=,
Introduction
expression-1 op= expression-2
Pointeur de fonctions

Erreurs courante en C
expression-1 = expression-1 op expression-2
■ opérateurs d’incrémentation et de décrémentation, ++, - -
■ opérateur de conversion de type (type) objet
a=(int) c
■ opérateur adresse &,
a=&b

- p. 26/81
Règles de priorité des opérateurs

introduction ■ les opérateurs sont plus ou moins prioritaires,


Les bases du C
● Syntaxe
■ Dans le cas de priorité égales on a un ordre d’évaluation
● types de base
● Les opérateurs
(associatifs à droite ou à gauche)
● Types construits
● Les tableaux ■ ordre de priorité:
● chaînes de caractères opérateurs associativité
● contrôle de flot
() [] -> . droite
Les fonctions ! ++ – -(unaire) (type) *(indirection) &(adresse) sizeof gauche
*/% droite
Les entrées-sorties
+ -(binaire) droite
Introduction «» droite
Pointeur de fonctions < <= > >= droite
== != droite
Erreurs courante en C
&(et bit-à-bit) droite
| droite
&& droite
|| droite
?: gauche
= += -= *= /= %= &= =ˆ |= «= »= gauche
, droite

- p. 27/81

Types construits

introduction
■ À partir des types prédéfinis du C (caractères, entiers,
Les bases du C
● Syntaxe flottants), on peut créer de nouveaux types, appelés types
● types de base
● Les opérateurs
contruits, qui permettent de représenter des ensembles de
● Types construits
● Les tableaux
données organisées.
● chaînes de caractères
● contrôle de flot
■ Les tableaux
Les fonctions ■ Les structures
Les entrées-sorties ■ Les unions
Introduction
■ Les énumérations
Pointeur de fonctions

Erreurs courante en C
■ Les constructeurs de type

- p. 28/81
Les tableaux

introduction ■ Un tableau est un ensemble fini d’éléments de même type,


Les bases du C
● Syntaxe
stockés en mémoire à des adresses contiguës.
● types de base
● Les opérateurs
■ La déclaration d’un tableau tab de 10 entiers se fait de la
● Types construits
● Les tableaux
façon suivante : int tab[10];
● chaînes de caractères
● contrôle de flot
■ On accède au troisième élément du tableau tab par
Les fonctions l’expression tab[2]. Les tableaux en C commencent
Les entrées-sorties
toujours à 0.
Introduction ■ On peut définir des tableaux multidimensionnels. Exemple:
Pointeur de fonctions matrice M d’entiers de 10 lignes 5 colonnes int M[10][5]
Erreurs courante en C ■ Important: un tableau en C peut être vu comme un pointeur
sur le premier élément du tableau:
int *tab; ⇔ int tab[];
■ Mais il faut savoir qu’en C un tableau est une constante

- p. 29/81

Tableaux: exemple

introduction

Les bases du C char tab[10] = {’e’,’x’,’e’,’m’,’p’,’l’,’e’,’\0’};


● Syntaxe
● types de base
main()
● Les opérateurs
● Types construits
{
● Les tableaux
● chaînes de caractères
int i;
● contrôle de flot for (i = 0; i < 10; i++)
Les fonctions printf("tab[%d] = %c\n",i,tab[i]);
Les entrées-sorties }
Introduction

Pointeur de fonctions tab[0] = e


Erreurs courante en C tab[1] = x
tab[2] = e
tab[3] = m
tab[4] = p
tab[5] = l
tab[6] = e
tab[7] =
tab[8] =
tab[9] = - p. 30/81
Tableaux: exemple

introduction

Les bases du C
#define M 2
● Syntaxe
● types de base
#define N 3
● Les opérateurs int tab[M][N] = {{1, 2, 3}, {4, 5, 6}};
● Types construits
● Les tableaux
● chaînes de caractères
● contrôle de flot
main()
Les fonctions
{
Les entrées-sorties
int i, j;
for (i = 0 ; i < M; i++)
Introduction
{
Pointeur de fonctions
for (j = 0; j < N; j++)
Erreurs courante en C
printf("tab[%d][%d]=%d\n",i,j,tab[i][j]);
}
}
tab[0][0]=1
tab[0][1]=2
tab[0][2]=3
tab[1][0]=4
tab[1][1]=5
tab[1][2]=6 - p. 31/81

Retour sur les types: les chaînes de caractères

introduction ■ En C une chaine de caractères n’est pas un type de base:


Les bases du C
● Syntaxe
c’est un tableau de caractères terminé par le caractère
● types de base
● Les opérateurs
spécial ’\0’ (ou NULL: octet valant 0).
● Types construits
● Les tableaux
■ On peut la noter entre double cote:
● chaînes de caractères
● contrôle de flot
char chaine[10]="bonjour"
Les fonctions
■ Où comme un tableau de caractère (jamais utilisé):
Les entrées-sorties
char chaine[10]={’b’,’o’,’n’,’j’,’o’,’u’,’r’,’\0’}
Introduction ■ Comme un tableau en C est assimilé à un pointeur sur le
Pointeur de fonctions début du tableau on trouvera souvent des chaines de
Erreurs courante en C caractères déclarées comme:
char *chaine;
■ Pour l’instant on preferera la déclaration statique (tableau).
Attention il faut une case de plus que le nombre de lettres
(pour ’\0’).

- p. 32/81
Les structures

introduction ■ Une structure est une suite finie d’objets de types différents.
Les bases du C
● Syntaxe
■ Contrairement aux tableaux, les différents éléments d’une
● types de base
● Les opérateurs
structure n’occupent pas nécessairement des zones
● Types construits
● Les tableaux
contiguës en mémoire.
● chaînes de caractères
● contrôle de flot
■ Chaque élément de la structure, appelé membre ou champ,

Les fonctions est désigné par un identificateur.


Les entrées-sorties ■ Deux manières équivalentes de définir une variable z
Introduction complexe:
Pointeur de fonctions struct complexe struct complexe
Erreurs courante en C { {
double reelle; double reelle;
double imaginaire; double imaginaire;
} z; };
struct complexe z;

norme=sqrt(z.reelle*z.reelle+z.imaginaire*z.imaginaire);

- p. 33/81

Les structures de contrôle de flot

introduction ■ Les objets que nous avons rencontrés permettent de faire


Les bases du C
● Syntaxe
des calculs, pas de contrôler quels calculs sont faits
● types de base
● Les opérateurs
■ Les structures de contrôles sont de deux types:
● Types construits
◆ Les boucles
● Les tableaux
● chaînes de caractères ◆ Les instructions de branchement
● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 34/81
Les boucles

introduction ■ Boucles while:


Les bases du C
● Syntaxe
i = 1;
● types de base while (i < 10)
● Les opérateurs
● Types construits while (expression ) {
● Les tableaux
● chaînes de caractères instruction printf(" i = %d \n",i);
● contrôle de flot
i++;
Les fonctions
}
Les entrées-sorties

Introduction
■ Boucles for
Pointeur de fonctions
expr 1;
while (expr 2 )
Erreurs courante en C for (expr 1 ;expr 2 ;expr 3)
⇔ {instruction
instruction
expr 3;
}

- p. 35/81

Les instructions de branchement

introduction ■ Branchement conditionnel


Les bases du C if (expression-1 )
if (expression-1 )
● Syntaxe
● types de base
instruction-1 ou
instruction-1
● Les opérateurs
● Types construits
else instruction-2
● Les tableaux
● chaînes de caractères
■ Branchement multiple switch:
● contrôle de flot
switch (expression )
{case constante-1:
Les fonctions
liste d’instructions 1
Les entrées-sorties break;
Introduction case constante-2:
liste d’instructions 2
Pointeur de fonctions
break;
Erreurs courante en C
case constante-3:
liste d’instructions 3
break;
default:
liste d’instructions defaut
break;
}
■ Branchement non conditionnel: break, continue
■ Branchement à ne pas utiliser: goto
- p. 36/81
Les fonctions

introduction ■ On peut en C découper un programme en plusieurs


Les bases du C
fonctions.
Les fonctions
● Les fonctions
■ Seule la fonction main est obligatoire.
● Récursivité
● Portée des variables ■ Même si vous ne définissez pas de fonction, vous utilisez les
Les entrées-sorties fonctions des biblothèques C standard (return, printf
Introduction par exemple)
Pointeur de fonctions ■ Définition de fonction:
Erreurs courante en C int factorielle(int n)
type nom (type-1 arg-1,...,type-n arg-n) {int i, fact;
{[déclarations de variables locales ] for (i = 1,fact=1; i<=n; i++)
liste d’instructions fact *= i;
} return(fact);
}

■ La première ligne int factorielle(int n) s’appelle


l’en-tête (ou prototype, ou encore signature) de la fonction.
■ Appel de fonction (dans main() par exemple):
x=factorielle(10);
- p. 37/81

Passage de paramètres

introduction ■ Une fonction communique des valeurs avec son


Les bases du C
environnement appelant à travers les paramêtres et le
Les fonctions
● Les fonctions
résultats.
● Récursivité
● Portée des variables
■ dans int factorielle(int n), n est le paramètre
Les entrées-sorties
formel de la fonction. Il peut être utilisé dans le corps de la
Introduction
fonction comme une variable locale.
Pointeur de fonctions ■ dans x=factorielle(10);, 10 est le paramètre effectif
Erreurs courante en C utilisé lors de cet appel.
■ En C, tout ce passe lors de cette appel comme si on
exécutait le corps de la fonction avec la case mémoire pour
n contenant une copie de la case mémoire contenant 10. On
dit que les paramètres sont passés par valeur.
■ Lorsque l’appel est terminé, la case mémoire de n disparait.
■ Donc: on peut modifier la valeur du paramètre formel n dans
le corps de la fonction mais cela ne modifiera pas la valeur
du paramètre effectif (10).
- p. 38/81
Imbrication de fonctions

introduction ■ En C on ne peut pas définir une fonction à l’intérieur d’une


Les bases du C
fonction
Les fonctions
● Les fonctions
■ En revanche on peut utiliser une fonction dans une fonction.
● Récursivité
● Portée des variables ■ Pour cela il y a deux contraintes:
Les entrées-sorties 1. Au moment de la compilation, lorsque le compilateur
Introduction rencontre l’appel à une fonction factorielle, il faut qu’il
Pointeur de fonctions ai déjà rencontré l’en-tète de la fonction int
Erreurs courante en C factorielle(int n)
2. Au moment de l’édition de lien, il faut que l’un des codes
objet contienne le code compilé de la fonction factorielle.
■ On a plusieurs moyens pour assurer ces contraintes:
1. Un seul fichier
2. Déclarer les en-têtes de fonctions en début de fichier
3. Compilation séparée

- p. 39/81

Fonctions dans Un seul fichier

introduction
//fonction factorielle
Les bases du C
//calcule n! ou n entier
Les fonctions
int factorielle(int n)
● Les fonctions
● Récursivité {int i, fact;
● Portée des variables
//double initialisation
Les entrées-sorties
for (i = 1,fact=1; i<=n; i++)
Introduction
fact *= i;
Pointeur de fonctions
return(fact);
Erreurs courante en C
} ■ Compilation:
gcc fact1.c -o fact
//fonction main
//affiche 10! à l’ecran
int main()
{int x;
x=factorielle(10);
printf("10!=%d\n",x);
return(0);
}

- p. 40/81
Fonction avec déclaration des en-têtes
//Declaration en-tetes
int factorielle(int n);
introduction

Les bases du C
//fonction main
Les fonctions
//affiche 10! à l’ecran
● Les fonctions int main()
● Récursivité
● Portée des variables {int x;
Les entrées-sorties x=factorielle(10);
Introduction
printf("10!=%d\n",x); ■ attention au ; après
Pointeur de fonctions
return(0); l’en-tête.
Erreurs courante en C
} ■ Commande de
compilation:
//fonction factorielle gcc fact1.c -o
//calcule n! ou n entier fact
int factorielle(int n)
{int i, fact;
//double initialisation
for (i = 1,fact=1; i<=n; i++)
fact *= i;
return(fact);
}
- p. 41/81

Deux fichiers
//fichier main1.c
//fichier fact3.c
introduction
//Declaration en-tetes
Les bases du C
//fonction factorielle int factorielle(int n);
Les fonctions
//calcule n! ou n entier
● Les fonctions int factorielle(int n) //fonction main
● Récursivité
● Portée des variables {int i, fact; //affiche 10! à l’ecran
Les entrées-sorties //double initialisation int main()
Introduction for (i = 1,fact=1; i<=n; i++) {int x;
Pointeur de fonctions
fact *= i; x=factorielle(10);
Erreurs courante en C
return(fact); printf("10!=%d\n",x);
} return(0);

}
■ Commandes de compilation:
gcc -c fact3.c -o fact3.o
gcc -c main1.c -o main1.o
gcc main1.o fact3.o -o main1

- p. 42/81
Fonctions: La bonne manière de faire
//fichier fact3.h

//fichier fact3.c
introduction
//Declaration en-tetes
Les bases du C
int factorielle(int n);
//fonction factorielle
Les fonctions
//fichier main2.c
● Les fonctions
//calcule n! ou n entier
#include "fact3.h"
● Récursivité int factorielle(int n)
● Portée des variables //fonction main
{int i, fact;
Les entrées-sorties //affiche 10! à l’ecran
//double initialisation
Introduction int main()
for (i = 1,fact=1; i<=n; i++)
Pointeur de fonctions {int x;
fact *= i;
Erreurs courante en C
x=factorielle(10);
return(fact);
printf("10!=%d\n",x);
}
return(0);

}
■ On définit les en-têtes dans un fichier d’en-têtes pour la
réutilisation par d’autres programmes.
■ Commandes de compilation:
gcc -c fact3.c -o fact3.o
gcc -c main2.c -o main2.o
gcc main2.o fact3.o -o main2 - p. 43/81

Récursivité

introduction ■ Une fonction peu s’appeler elle-même, c’est alors une


Les bases du C
fonction récursive.
Les fonctions
● Les fonctions
■ la récursion est une autre manière d’effectuer des boucles.
● Récursivité
//fonction factRecurs
● Portée des variables
//calcule n! ou n entier>0
Les entrées-sorties
//de manière récursive
Introduction
int factRecurs(int n)
Pointeur de fonctions
{int fact;
Erreurs courante en C

if (n==1) //condition d’arret


fact=1;
else
fact=n*factRecurs(n-1);

return(fact);
}

- p. 44/81
Récursivité

introduction ■ La récursivité est très importante dans certains paradigmes


Les bases du C
de programmation (programmation fonctionnelle).
Les fonctions
● Les fonctions
■ Elle correspond à une méthode naturelle de décomposition
● Récursivité
● Portée des variables
d’un problème en problèmes plus simple:
◆ pour calculer n!, je cacule (n − 1)! (plus simple)
Les entrées-sorties

◆ puis je calcule n ∗ (n − 1)!


Introduction

Pointeur de fonctions ■ Pour s’assurer que. que le programme ne va pas boucler


Erreurs courante en C indéfiniement, il est impératif de;
◆ Définir la condition d’arret: ici c’est n==1
◆ Définir une quantité qui va croître (ou décroître) lors des
appels successifs de la fonction jusqu’à ce que la
condition d’arret soit vérifiée, ici cette quantitée est n la
valeur du paramètre.
◆ On peut formaliser cela avec la notion d’invariant

- p. 45/81

Portée des variable

introduction ■ Les variables manipulées dans un programme C ne sont pas


Les bases du C
toutes traitées de la même manière. En particulier, elles
Les fonctions
● Les fonctions
n’ont pas toutes la même durée de vie. On distingue deux
● Récursivité catégories de variables.
● Portée des variables
◆ Les variables permanentes (ou statiques)
Les entrées-sorties
◆ Les variables temporaires
Introduction

Pointeur de fonctions
■ Chaque variable déclarée a une portée (ou durée de vie) qui
Erreurs courante en C
est la portion de code dans laquelle elle est connue.
■ On peut déclarer des variables au début de chaque bloc
(début d’une fonction ou portion de code entre accolade). La
portée (ou durée de vie) de ces variables est limitée au bloc.
■ Les blocs sont forcément imbriqués lexicalement, lors d’une
utilisation d’une variable n, elle peut avoir été déclarée deux
fois dans la suite des blocs englobant. L’utilisation
correspond à celle de la première définition rencontrée
lorsque l’on remonte dans les blocs (i.e. la dernière
effectuée temporellement).
- p. 46/81
Portée: exemple

introduction int n = 10;


Les bases du C void fonction();
Les fonctions
● Les fonctions
● Récursivité
void fonction()
● Portée des variables {int n = 0;
Les entrées-sorties n++;
Introduction printf("appel numero %d\n",n);
Pointeur de fonctions return;
Erreurs courante en C }

main()
{int i;
for (i = 0; i < 5; i++)
fonction();
}
----------------
appel numero 1
appel numero 1
appel numero 1
appel numero 1 - p. 47/81

appel numero 1

Portée: exemple

introduction int n;
Les bases du C void fonction();
Les fonctions
● Les fonctions
● Récursivité
void fonction()
● Portée des variables { n++;
Les entrées-sorties printf("appel numero %d\n",n);
Introduction return;
Pointeur de fonctions }
Erreurs courante en C

main()
{ int i;
for (i = 0; i < 5; i++)
fonction();
}
-----------------
appel numero 1
appel numero 2
appel numero 3
appel numero 4
appel numero 5 - p. 48/81
Les entrées-sorties

introduction ■ La librairie standard libstdio.a propose des fonctions


Les bases du C
pour faire des entrées-sorties sur les périphériques
Les fonctions
standard: l’écran et le clavier.
Les entrées-sorties
● Les entrées-sorties
■ Ces fonctions sont printf pour écrire et scanf pour lire
Introduction ■ Il faut inclure la directive #include <stdio.h> au début
Pointeur de fonctions du fichier si on désire les utiliser.
Erreurs courante en C ■ Ce sont des fonctions d’impression formatée, ce qui signifie
que les données sont converties selon le format particulier
choisi.

- p. 49/81

La fonction printf

introduction ■ La syntaxe de la fonction printf est:


Les bases du C
printf("chaîne de contrôle ",expr-1, ..., expr-n);
Les fonctions
■ La "chaîne de contrôle" contient le texte à afficher et
Les entrées-sorties
● Les entrées-sorties les spécifications de format correspondant à chaque
Introduction expression à afficher.
Pointeur de fonctions ■ %d indique l’affichage d’un entier signé en décimal.
Erreurs courante en C ■ %u indique l’affichage d’un entier non signé en décimal.
■ %c indique l’affichage d’un caractère.
■ %f indique l’affichage d’un réel (double) en décimale.
■ exemples:
int a; int a;
a=10; a=10;
printf("a vaut %d \n",a); printf("a vaut %4d \n",a);
■ résultats:
a vaut 10 a vaut 10

- p. 50/81
printf: exemples

introduction ■ %x indique l’affichage d’un entier non signé en hexadécimal.


Les bases du C
■ exemples:
Les fonctions short a;
int a;
Les entrées-sorties a=10;
● Les entrées-sorties a=10;
//conversion en int
Introduction printf("a vaut (en hexa) %x \n",a);
printf("a vaut %d \n",a);
Pointeur de fonctions
■ résultats:
Erreurs courante en C
a vaut (en hexa) A a vaut 10
■ Attention ! Il y a une conversion de type:
■ exemples:
char a;
short a;
a=66;
a=66;
//conversion en int
printf("a vaut %c \n",a);
printf("a vaut %d \n",a);
■ résultats:
a vaut 66 a vaut B

- p. 51/81

Encore printf

introduction ■ exemples: %f, %e


Les bases du C
double x = 1e-8 + 1000; double x = 1e-8 + 1000;
Les fonctions
printf("x vaut %f \n",a); printf("x vaut %e \n",a);
■ résultats:
Les entrées-sorties
● Les entrées-sorties x vaut 1000.000000 x vaut 1.000000e+03
Introduction ■ exemples: (conversion vers unsigned)
Pointeur de fonctions int a;
int a;
Erreurs courante en C
a=-23674;;
a=-23674;;
//conversion en unsigned
printf("a vaut %d \n",a);
printf("a vaut %u \n",a);
■ résultats:
a vaut -23674 a vaut 4294943622

- p. 52/81
Encore printf

introduction ■ programme:
Les bases du C #include <stdio.h>
Les fonctions

Les entrées-sorties int main()


● Les entrées-sorties
{
Introduction
fprintf(stdout,"Ascii[%d]=%c, en octal: %o en hexa: %x\n",
Pointeur de fonctions
’\101’,’\101’,’\101’,’\101’);
Erreurs courante en C fprintf(stdout,"Ascii[%d]=%c, en octal: %o en hexa: %x\n",
65,65,65,65);

return(0);
}
■ résultat:
trisset@hom:~/cours/2005/AGP/cours_tri/transp$ exChar
Ascii[65]=A, en octal: 101 en hexa: 41
Ascii[65]=A, en octal: 101 en hexa: 41
trisset@hom:~/cours/2005/AGP/cours_tri/transp$

- p. 53/81

Attention aux chaines!

introduction ■ programme:
Les bases du C #include <stdio.h>
Les fonctions

Les entrées-sorties int main()


● Les entrées-sorties
{int i;
Introduction
char chaine[4]={’\101’,’\101’,’\101’,’\0’};
Pointeur de fonctions
char fausseChaine[3]={’\101’,’\101’,’\101’};
Erreurs courante en C

fprintf(stdout,"chaine=%s,\n",chaine);
fprintf(stdout,"fausseChaine=%s,\n",fausseChaine);

return(0);
}
■ résultat:
trisset@hom:~/cours/2005/AGP/cours_tri/transp$ exChar2
chaine=AAA,
fausseChaine=AAA·öÿ¨öÿ¿;<nAAA,
trisset@hom:~/cours/2005/AGP/cours_tri/transp$

- p. 54/81
La fonction scanf

introduction ■ La syntaxe de la fonction scanf est:


Les bases du C scanf("chaîne de contrôle ",expr-1, ..., expr-n);
Les fonctions ■ Ici, la "chaîne de contrôle" ne contient que les formats
Les entrées-sorties ■ Les données à entrer au clavier doivent être séparées par des blancs ou
● Les entrées-sorties
des <RETURN> sauf s’il s’agit de caractères (<RETURN> est un caractère).
Introduction

■ Les formats sont légèrement étendus par rapport à ceux de printf


Pointeur de fonctions

Erreurs courante en C
■ exemple:
#include <stdio.h>
main()
{
int i;
printf("entrez un entier sous forme hexadecimale i = ");
scanf("%x",&i);
printf("i = %d\n",i);
}
■ Si on entre au clavier la valeur 1a, le programme affiche i = 26.
■ Attention à bien donner l’adresse de la variable à affecter.

- p. 55/81

Passage de paramêtre par référence

introduction ■ Tout se passe comme si la fonction scanf modifiait un de


Les bases du C
ses argument.
Les fonctions
■ En fait comme les argument sont passé par valeurs, on doit
Les entrées-sorties
● Les entrées-sorties passer en paramêtre un pointeur sur l’objet à modifier (donc
Introduction passer l’adresse de l’objet)
Pointeur de fonctions ■ La fonction scanf ne peut modifier son argument, mais elle
Erreurs courante en C peut modifier l’objet pointé par l’argument.
■ Ce mechanisme est utilisé systématiquement en C, pour que
la fonction modifie un objet, il est passé en argument par
référence.

- p. 56/81
Fichiers

introduction ■ Les accès à un fichier se font par l’intermédiaire d’un tampon


Les bases du C
(buffer) qui permet de réduire le nombre d’accès aux
Les fonctions
périphériques (disque...).
Les entrées-sorties
● Les entrées-sorties
■ Pour pouvoir manipuler un fichier, un programme a besoin
Introduction d’un certain nombre d’informations : l’adresse du tampon,
Pointeur de fonctions
position dans le fichier, mode d’accès (lecture ou écriture) ...
Erreurs courante en C ■ Ces informations sont rassemblées dans une structure dont
le type, FILE *, est défini dans stdio.h. Un objet de type
FILE * est un stream (flot).
■ Avant de lire ou d’écrire dans un fichier, on l’ouvre par la
commande fich=fopen("nom-de-fichier","r").
Cette fonction dialogue
avec le système d’exploitation et initialise un stream fich,
qui sera ensuite utilisé lors de l’écriture ou de la lecture.
■ Après les traitements, on ferme le fichier grâce à la fonction
fclose(fich).

- p. 57/81

Fichiers

introduction ■ on peut ouvrir un fichier sous plusieurs modes: lecture ("r"), écriture au début ("w"),
Les bases du C écriture à la fin ("a"). fopen retourne 0 en cas d’echec.
Les fonctions
■ Exemple:
FILE *fich;
Les entrées-sorties
● Les entrées-sorties fich=fopen("./monFichier.txt");
if (!fich) fprintf(stderr,"Erreur d’ouverture : %s\n","./monFichier.txt");
Introduction
■ Un objet de type FILE est quelquefois appelé un déscripteur de fichier, c’est un entier
Pointeur de fonctions
désignant quel est le fichier manipulé.
Erreurs courante en C
■ Trois descripteurs de fichier peuvent être utilisés sans qu’il soit nécessaire de les ouvrir
(à condition d’utiliser stdio.h):
◆ stdin (standard input) : unité d’entrée (par défaut, le clavier, valeur du
descripteur: 1) ;
◆ stdout (standard output) : unité de sortie (par défaut, l’écran, valeur du
descripteur: 0) ;
◆ stderr (standard error) : unité d’affichage des messages d’erreur (par défaut,
l’écran, valeur du descripteur: 2).
■ Il est fortement conseillé d’afficher systématiquement les messages d’erreur sur stderr
afin que ces messages apparaissent à l’écran même lorsque la sortie standard est
redirigée.

- p. 58/81
Autres fonction de lecture/ecriture

introduction ■ Entrée/sorties de caractères


Les bases du C
◆ int fgetc(FILE* flot);
◆ int fputc(int caractere, FILE *flot)
Les fonctions
■ Entrée/sorties de chaînes de caractères
Les entrées-sorties
● Les entrées-sorties
◆ char *fgets(char *chaine, int taille, FILE* flot);
◆ int fputs(const char *chaine, FILE *flot)
Introduction
■ Entrée/sorties binaires
Pointeur de fonctions
◆ size_t fread(void *pointeur, size_t taille, size_t nombre,
Erreurs courante en C FILE *flot);
◆ size_t fwrite(void *pointeur, size_t taille, size_t nombre,
FILE *flot);
■ positionnement dans un fichier
◆ int fseek(FILE *flot, long deplacement, int origine);
◆ trois valeurs possibles pour origine: SEEK_SET (égale à 0) : début du fichier
,SEEK_CUR : position courante, SEEK_END (égale à 2) : fin du fichier.

- p. 59/81

fgetc, fputc: exemple


#include <stdio.h>
#include <stdlib.h>
#define ENTREE "entree.txt"
introduction #define SORTIE "sortie.txt"
Les bases du C
int main(void)
{FILE *f_in, *f_out;
Les fonctions
int c;
Les entrées-sorties
● Les entrées-sorties
if ((f_in = fopen(ENTREE,"r")) == NULL)
Introduction {
Pointeur de fonctions fprintf(stderr, "\nErreur: Impossible de lire le fichier %s\n",ENTREE);
Erreurs courante en C
return(EXIT_FAILURE);
}
if ((f_out = fopen(SORTIE,"w")) == NULL)
{
fprintf(stderr, "\nErreur: Impossible d’ecrire dans le fichier %s\n",
SORTIE);
return(EXIT_FAILURE);
}
while ((c = fgetc(f_in)) != EOF)
fputc(c, f_out);
fclose(f_in);
fclose(f_out);
return(EXIT_SUCCESS);
}

- p. 60/81
Arguments de la fonction main

introduction ■ La fonction main doit être présente si le programme est


Les bases du C
utilisé directement (pas comme une librairie), par exemple:
Les fonctions
appelé depuis le shell.
Les entrées-sorties
● Les entrées-sorties
■ En général, la fonction main retourne un code d’erreur de
Introduction type int.
Pointeur de fonctions ■ Lorsque l’on compile avec la commande gcc monProg.c
Erreurs courante en C -o monProg, l’exécution de la command monProg dans un
shell appelle la fonction main
■ Si on lance la commande monProg avec des arguments (ex:
monProg fichier1.txt, il est possible de récupérer dans
la fonction main la valeur de ces arguments sous forme de
chaînes de caractères: on utilise les arguments standard de
la fonction main: int argc (argument count), char
*argv[] (argument values) (on peut aussi récuperer des
variables d’environnement grâce à envp)

- p. 61/81

Exemple de fonction main

introduction ■ Multiplication de deux entier: gcc mult.c -o mult


Les bases du C
shell> mult 8 32
Les fonctions Le produit de 8 par 32 vaut: 256
Les entrées-sorties #include <stdio.h>
● Les entrées-sorties
#include <stdlib.h>
Introduction
int main(int argc, char *argv[])
Pointeur de fonctions
{
Erreurs courante en C
int a, b;
if (argc != 3)
{
printf("\nErreur : nombre invalide d’arguments");
printf("\nUsage: %s int int\n",argv[0]);
return(EXIT_FAILURE);
}
a = atoi(argv[1]);
b = atoi(argv[2]);
printf("\nLe produit de %d par %d vaut : %d\n", a, b, a * b);
return(EXIT_SUCCESS);
}
- p. 62/81
Convention d’écriture en C

introduction ■ Il existe très peu de contraintes dans l’écriture d’un


Les bases du C
programme C. Toutefois ne prendre aucune précaution
Les fonctions
aboutirait à des programmes illisibles.
Les entrées-sorties
● Les entrées-sorties
■ On n’écrit qu’une seule instruction par ligne : le point virgule
Introduction d’une instruction ou d’une déclaration est toujours le dernier
Pointeur de fonctions
caractère de la ligne.
Erreurs courante en C ■ Les instructions sont disposées de telle façon que la
structure modulaire du programme soit mise en évidence.
◆ une accolade ouvrante marquant le début d’un bloc doit
être seule sur sa ligne ou placée à la fin d’une ligne.
◆ Une accolade fermante est toujours seule sur sa ligne.

■ Les instructions doivent être indentées afin que toutes les


instructions d’un même bloc soient alignées. Le mieux est
d’utiliser le mode C d’emacs ou de vi.
■ On commente abondament le code

- p. 63/81

Plan

introduction ■ Pointeurs de fonctions


Les bases du C
■ Les erreurs courantes en C (source
Les fonctions
http://nicolasj.developpez.com/articles/erreurs/
Les entrées-sorties
par exemple)
Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 64/81
Utilité des pointeurs de fonction

introduction ■ Mécanismes dynamiques


Les bases du C ◆ plug-in
Les fonctions ◆ Modifier une fonctionnalité sans arrêter le programme
Les entrées-sorties ◆ ajouter de nouvelles fonctionnalités
Introduction
■ Exemple: fonction de décodage de trame niveau 2:
Pointeur de fonctions
dépendant de l’interface connectée (ethernet, wifi, etc.)
Erreurs courante en C

- p. 65/81

Un premier exemple

introduction
#include <stdio.h>
Les bases du C
#include <stdlib.h>
Les fonctions
//declaration de fonction
Les entrées-sorties
int fonct1(int a)
Introduction

Pointeur de fonctions
{
Erreurs courante en C
fprintf(stdout,"Je suis fonct1(%d)\n",a);
return(0);
}

int main()
{// declaration de pointeur de fonction
int (*foncPtr)(int a);

foncPtr=&fonct1;
(*foncPtr)(10);
return(0);
} - p. 66/81
Comprendre les déclarations

introduction ■ Déclaration d’une variable: int *q[3]


Les bases du C ◆ [] plus prioritaire que *, donc:
Les fonctions
int *q[3] ⇔ int (*(q[3]))
Les entrées-sorties ◆ l’expression (*(q[3])) est de type int
Introduction ◆ l’expression q[3] est de type pointeur vers un int
Pointeur de fonctions ◆ l’expression (i.e. la variable) q est de type tableau de
Erreurs courante en C pointeur vers un int
■ Déclaration d’une fonction:
int fonct1(int a)
◆ l’expression fonct1(int a) est de type int
◆ l’expression (i.e. la variable) fonct1 est de type fonction
qui prend un int et renvoie un int
◆ Les parenthèses après un symbole indique que le
symbole est une fonction (de même que les crochets
après un symbole indique que le symbole est un tableau).

- p. 67/81

Déclaration d’un pointeur de fonction

introduction ■ Déclaration d’un pointeur de fonction:


Les bases du C
int (*foncPtr)(int a)
Les fonctions ◆ l’expression (*foncPtr)(int a) est de type int
Les entrées-sorties ◆ l’expression (*foncPtr) est de type fonction qui prend
Introduction un int est renvoie un int
Pointeur de fonctions ◆ l’expression (i.e. la variable) foncPtr est de type pointeur
Erreurs courante en C vers une fonction qui prend un int et renvoie un int
■ lors de l’utilisation, (presque) tout se passe comme si la
fonction était une Lvalue:
◆ On peut affecter une adresse de fonction au pointeur de
fonction: foncPtr=&fonct1;
◆ Si on déréférence le pointeur de fonction, on obtient une
fonction: l’exécution de (*foncPtr)(10); affiche:
Je suis la fonction fonct1(10)

- p. 68/81
En fait, c’est un peu plus compliqué...

introduction ■ En C, une fonction est automatiquement castée en pointeur


Les bases du C
de fonction (et inversement):
Les fonctions
foncPtr=&fonct1 ⇔ foncPtr=fonct1
Les entrées-sorties
(*foncPtr)(10); ⇔ (foncPtr)(10)
Introduction
■ Tout comme pour les tableaux:
Pointeur de fonctions
tab ⇔ &tab
Erreurs courante en C
■ Pour les fonctions et les tableaux qui ne sont pas des
L-values (on les appelle quelquefois des labels) le
compilateur identifie a et &a
■ On peut donc écrire:
int (*foncPtr)(int a);

foncPtr=fonct1;
foncPtr(10);

- p. 69/81

On peut donc ecrire:

introduction
#include <stdio.h>
Les bases du C
#include <stdlib.h>
Les fonctions
//declaration de fonction
Les entrées-sorties
int fonct1(int a)
Introduction

Pointeur de fonctions
{
Erreurs courante en C
fprintf(stdout,"Je suis fonct1(%d)\n",a);
return(0);
}

int main()
{// declaration de pointeur de fonction
int (*foncPtr)(int a);

foncPtr=fonct1;
foncPtr(10);
return(0);
} - p. 70/81
Un autre exemple

introduction
int main(void)
Les bases du C
{
Les fonctions
//comparaison de deux entiers int i,t[6]={1,5,2,3,6,4};
Les entrées-sorties

Introduction
int croissant(int i, int j) trie(t, 6, croissant);
Pointeur de fonctions
{ for(i=0;i<6;i++)
Erreurs courante en C
if (i<=j) return 0; fprintf(stdout," %d ",t[
else return 1; fprintf(stdout,"\n");
}
int decroissant(int i, int j) trie(t, 6, decroissant);
{ for(i=0;i<6;i++)
if (i<=j) return 1; fprintf(stdout," %d ",t[
else return 0; fprintf(stdout,"\n");
} return 0;
}

- p. 71/81

... la fonction tri

introduction
void trie(int tableau[], int taille, int (fcomp)(int, int))
Les bases du C
{
Les fonctions
int i,j,min;
Les entrées-sorties
//tri par permuation avec fcomp comme fonction de comparaiso
Introduction

Pointeur de fonctions
for (i=0;i<taille;i++)
Erreurs courante en C
{
min=tableau[i];
for (j=i+1;j<taille;j++)
if (fcomp(tableau[i],tableau[j]))
{
min = tableau[j];
tableau[j]=tableau[i];
tableau[i]=min;
}
}
return ;
} - p. 72/81
Passage de fonction par référence

introduction ■ Comme pour une variable normale, on peut modifier un


Les bases du C
pointeur de fonction en le passant en paramêtre par
Les fonctions
référénce.
Les entrées-sorties
■ Pour avoir une fonction qui modifie un pointeur de fonction
Introduction
(i.e. qui modifie la qui fonction appelée lorsque le pointeur
Pointeur de fonctions
est invoqué), il faut que son paramêtre soit un pointeur sur
Erreurs courante en C
un pointeur de fonction.

- p. 73/81

Passage de fonction par référence


changeOrdre(int (**fcomp1)(int, int), int (*fcomp2)(int, int))
{
introduction
*fcomp1=fcomp2;
Les bases du C
}
Les fonctions
int main(void)
Les entrées-sorties
{
Introduction
int i,t[6]={1,5,2,3,6,4};
Pointeur de fonctions
int (*fcomp)(int,int);
Erreurs courante en C

fcomp=croissant;
trie(t, 6, fcomp);
for(i=0;i<6;i++)
fprintf(stdout," %d ",t[i]);
fprintf(stdout,"\n");

changeOrdre(&fcomp,decroissant);

trie(t, 6, fcomp);
for(i=0;i<6;i++) - p. 74/81
introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C
Les erreurs courantes en C

- p. 75/81

Confusion entre == et =

introduction
■ À ne pas faire:
Les bases du C
if (size = 0) ....
Les fonctions
■ Détection: l’option -Wall du compilateur avertit le
Les entrées-sorties
programmeur (warning)
Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 76/81
Confusion entre opérateurs logiques et binaires

introduction ■ Le ET logique (&&) qui retourne 0 ou 1 (en s’arrêtant au


Les bases du C
premier argument s’il est faux)
Les fonctions
■ Le ET binaire (&) évalue ses deux opérandes et effectue le
Les entrées-sorties
ET bit à bit entre ses deux opérandes.
Introduction

Pointeur de fonctions
■ Le OU logique (||) qui retourne 0 ou 1 (en s’arrêtant au
premier argument s’il est vrai)
Erreurs courante en C

■ Le OU binaire (|) évalue ses deux opérandes et effectue le


OU bit à bit entre ses deux opérandes.
■ Impossible à détecter à la compilation.

- p. 77/81

Problèmes de macros

introduction ■ On n’écrit pas


Les bases du C
#define MAX 10;
Les fonctions ◆ A[MAX] devient A[10;]
Les entrées-sorties
■ On n’écrit pas
Introduction
#define MAX=10
Pointeur de fonctions
◆ Erreur détectée à la compilation, mais lors de l’utilisation
Erreurs courante en C
de MAX (la ligne référencée n’est pas celle de la définition
de MAX).
■ On écrit
#define MAX 10
■ En cas de doute, on peut utiliser gcc -E pour vérifier
l’expansion correcte des macros.

- p. 78/81
Fonctions retournant un caractère getc...

introduction char c;
Les bases du C while ( (c = getchar ()) != EOF)
Les fonctions ...
Les entrées-sorties ■ La fonction getchar retourne un entier
Introduction
■ Les cast implicites effectués sont:
Pointeur de fonctions
while ( (int)(c = (char)getchar ()) != EOF)
Erreurs courante en C
■ le caractère EOF (qui marque la fin d’un fichier : End Of File)
est un caractère invalide généralement égal à -1 mais il peut
parfaitement être égal à 128, dans ce cas on dépasse la
capacité de stockage d’un char et l’on se retrouve avec un
résultat égal à -128 : la condition du while sera toujours
fausse, le programme boucle indéfiniment!
■ Il faut écrire:
int cInt;
char c;
while ( (cInt = getchar ()) != EOF)
{
c=(char)cInt; - p. 79/81

...

Erreurs avec if et for

introduction ■ point-virgule mal placé


Les bases du C if (a < b) ; for (i=0; i<N; i++);
Les fonctions a = b; printf("%d", i);
Les entrées-sorties ■ Le mauvais else
Introduction if (a < b)
Pointeur de fonctions if (b < c) then b = c;
Erreurs courante en C else
b = a;
■ Ce qu’il fallait faire:
if (a < b)
{ if (b < c) then b = c; }
else
b = a;

- p. 80/81
Et les plus courantes...

introduction ■ Mauvaise indentation


Les bases du C
■ Pas de makefile (ou pas de cible clean dans le makefile)
Les fonctions

Les entrées-sorties
■ exemple de fichier configuration vi:
Introduction
syntax on " coloration syntaxique
Pointeur de fonctions
set autoindent " identation
Erreurs courante en C
set cindent " pour C
set nopaste
set ts=4 " tabulation a 4 caracteres
set sw=4
■ Sous vi:
◆ == pour indenter la ligne courante,
◆ =G pour identer tout le fichier:

- p. 81/81