Vous êtes sur la page 1sur 26

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/52

Outils pour la programmation C

Outils pour la programmation


● GNU
■ Outils de développement GNU
● gcc
● make
■ gcc
● gdb
■ gdb
Introduction
■ make
Pointeur de fonctions

Erreurs courante en C

- p. 2/52
Le projet GNU

Outils pour la programmation


● GNU
■ Le projet GNU, initié par Richard Stallman en 1984, vise à
● gcc
● make
créer un système d’exploitation complet qui réponde aux
● gdb principes du logiciel libre
Introduction ■ Licence GPL (GNU General Public License) ou LGPL (GNU
Pointeur de fonctions
Lesser General Public License)
Erreurs courante en C
■ Philosophie unix: programmes modulaires assemblés en un
système complexe:
◆ Portabilité
◆ Standard Posix
◆ Performances

■ Prise en main plus difficile que les outils commerciaux.


■ Modèle économique de plus en plus suivi par les industriels.

- p. 3/52

principaux outils de développement GNU

Outils pour la programmation


● GNU
■ Le compilateur gcc est la pièce maîtresse du projet GNU.
● gcc
● make
Compilateur C, C++ et Objective-C de très grande qualité,
● gdb ses performances dépassent souvent celles des meilleurs
Introduction compilateurs commerciaux.
Pointeur de fonctions ■ Autres compilateurs g77, gnat, gpc,. . .
Erreurs courante en C
■ emacs éditeur de texte multifonction qui peut faire aussi
office d’environnement intégré de programmation (IDE)
■ make permet d’automatiser l’ordonnancement des
différentes étapes de compilation
■ gdb est un débogueur pour les langages C, C++ et Fortran.
ddd apporte une interface graphique au-dessus de gdb.
■ automake, autoconf permette de produire facilement des
programmes portables.
■ Tous ces programmes sont disponibles sur tous les type de
systèmes. Pour windows, c’est à travers l’environnement
cygwin
- p. 4/52
GCC

Outils pour la programmation


● GNU
■ La commande gcc lance plusieurs programmes suivant les
● gcc options
● make
● gdb ◆ Le pré-processeur cpp
Introduction ◆ Le compilateur cc1
Pointeur de fonctions ◆ L’assembleur gas
Erreurs courante en C ◆ L’éditeur de liens ld

- p. 5/52

Le pré-processeur: cpp ou gcc -E

Outils pour la programmation ■ gcc -E ex1.c -o ex1.i


● GNU
● gcc
● make
■ Les tâches du préprocesseur sont :
● gdb ◆ élimination des commentaires,
Introduction ◆ l’inclusion de fichier source,
Pointeur de fonctions ◆ la substitution de texte,
Erreurs courante en C ◆ la définition de macros,
◆ la compilation conditionnelle.

■ Exemple:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
ex1.c ...
f=MAX(3,b);

#define MAX(a, b) ((a) > (b) ? (a) : (b))


ex1.i ...
f=((3) > (b) ? (3) : (b));

- p. 6/52
Le compilateur cc1 ou gcc -S

Outils pour la programmation


● GNU
■ Génère du code assembleur
● gcc
● make
■ gcc -S exgcc.c -o exgcc.s
● gdb
■ Exemple:
Introduction

Pointeur de fonctions
#include <stdio.h>
Erreurs courante en C
int main()
{
printf("Hello world\n");

return(0);
}

- p. 7/52

Code assembleur du hello world (exgcc.s)


.file "exgcc.c"
.section .rodata
Outils pour la programmation .LC0:
● GNU
● gcc .string "Hello world\n"
● make
● gdb .text
Introduction
.globl main
Pointeur de fonctions
.type main, @function
Erreurs courante en C
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
movl $.LC0, (%esp)
call printf
movl $0, %eax
leave
ret
.size main, .-main
.section .note.GNU-stack,"",@progbits - p. 8/52
Assembleur as ou gas

Outils pour la programmation


● GNU
■ Transforme un fichier assembleur en un code objet
● gcc
● make
(représentation binaire du code assembleur)
● gdb
■ L’options -c de gcc permet de combiner compilation et
Introduction
assemblage:
Pointeur de fonctions
gcc -c ex1.c -o ex1.o
Erreurs courante en C

- p. 9/52

Éditeur de liens: ld

Outils pour la programmation


● GNU
■ Produit l’exécutable (a.out par défaut) à partir des codes
● gcc
● make
objets des programmes et des librairies utilisées.
● gdb
■ Il y a deux manières d’utiliser les librairies dans un
Introduction
programme
Pointeur de fonctions ◆ Librairies dynamiques ou partagées (shared, option par
Erreurs courante en C
défaut): le code de la librairie n’est pas inclus dans
l’exécutable, le système charge dynamiquement le code
de la librairie en mémoire lors de l’appel du programme.
On n’a besoin que d’une version de la librairie en mémoire
même si plusieurs programmes utilisent la même librairie.
La librairie doit donc être installée sur la machine, avant
d’exécuter le code.
◆ Librairies statiques (static): le code de la librairie est
inclus dans l’exécutable. Le fichier exécutable est plus
gros mais on peut l’exécuter sur une machine sur laquelle
la librairie n’est pas installée.

- p. 10/52
Manipuler les fichiers binaires

Outils pour la programmation


● GNU
Quelques commandes utiles:
● gcc ■ nm
● make
● gdb permet de connaître les symboles (en particulier les
Introduction fonctions) utilisés dans un fichier objet ou exécutable:
Pointeur de fonctions trisset@hom:~/cours/2005/AGP/cours_tri$ nm exgcc.o
Erreurs courante en C 00000000 T main
U printf
■ objdump permet d’analyser un fichier binaire. Par exemple
pour avoir la correspondance entre la représentation binaire
et le code assembleur:
objdump -S exgcc
08048384 <main>:
8048384: 55 push %ebp
8048385: 89 e5 mov %esp,%ebp
8048387: 83 ec 08 sub $0x8,%esp
804838a: 83 e4 f0 and $0xfffffff0,%esp
804838d: b8 00 00 00 00 mov $0x0,%eax
8048392: 29 c4 sub %eax,%esp
- p. 11/52
8048394: c7 04 24 c4 84 04 08 movl $0x80484c4,(%esp
804839b: e8 10 ff ff ff call 80482b0 <_init+0
Options utiles de gcc

Outils pour la programmation


● GNU
■ -c :pas d’édition de liens
● gcc
● make
■ -o file: renomme le fichier de sortie file au lieu de
● gdb
a.out
Introduction
■ -g : insère les informations nécessaires à l’utilisation d’un
Pointeur de fonctions
déboggeur (gbd, ddd).
Erreurs courante en C
■ -Wall : fait le maximum de vérifications statiques possibles
■ -Oval :(val est un entier compris entre 1 et 4), effectue des
optimisations de niveau val
■ -Ipath : recherche les fichiers d’en-tête dans le répertoire
path avant de les rechercher dans les répertoires standards
(/usr/include, /usr/local/include).
■ -Lpath : recherche les librairies dans le répertoire path
avant de les rechercher dans les répertoires standards
(/usr/lib, /usr/local/lib).
■ -Dflag=val : équivalent à écrire la directive
#define flag val dans le code
- p. 12/52
Make

Outils pour la programmation


● GNU
■ À l’aide d’un fichier de description, l’utilitaire make crée une
● gcc
● make
suite de commandes qui seront exécutées par le shell d’unix.
● gdb
■ Utilisé principalement pour le développement logiciel mais
Introduction
peut aussi servir à de nombreux projets: production de gros
Pointeur de fonctions
documents, mise en place d’expérimentations etc...
Erreurs courante en C
■ Le principal avantage est de ne pas tout recompiler lorsque
l’on a changé un seul fichier.
■ Lorsque l’on tape make, l’utilitaire recherche dans l’ordre un
fichier makefile puis un fichier Makefile, on peut lui
indiquer d’utiliser un autre fichier avec l’option -f:
make -f monFich.mk

- p. 13/52

Makefile: Cibles et dépendances

Outils pour la programmation


● GNU
■ Dans un fichier Makefile, une cible est un objet qui va être
● gcc
● make
produit (par exemple un exécutable) par une règle de
● gdb production.
Introduction ■ On produit une cible particulière à partir de fichiers
Pointeur de fonctions
particuliers, ces fichiers sont les dépendances de la cible.
Erreurs courante en C
■ Ces dépendances peuvent être à leur tour des cibles
d’autres règles de production.
■ Exemple (Attention, le caractère tab est nécessaire avant
les règles de production):
all: main

main: main.o
gcc main.o -o main

main.o: main.c type.h


gcc -c main.c -o main.o

- p. 14/52
Makefile: définitions de variables

Outils pour la programmation


● GNU
■ Les variables (ou macros) de make ont un comportement
● gcc
● make
similaire aux macros de C définies par #define.
● gdb
■ La syntaxe de la définition de variable:
Introduction
VAR1=quelquechose etencorequelquechose
Pointeur de fonctions
■ On utilise la variable en mettant $(VAR1) ou ${VAR1}
Erreurs courante en C
■ Exemple typique d’utilisation:
TARGET_BIN = ../bin
OBJ = main.o utils.o truc.o

main: $(OBJ)
gcc -o main $(OBJ)
mv main $(TARGET_BIN)
■ la commande make main exécute:
gcc -o main main.o utils.o truc.o
mv main ../bin

- p. 15/52

Makefile: Variables prédéfinies

Outils pour la programmation


● GNU
■ Un certain nombre de variables sont fournies par défaut par
● gcc
● make
make
● gdb
■ SHELL indique sous quel shell est exécuté la commande (en
Introduction
général sh
Pointeur de fonctions
■ CC indique le compilateur C utilisé par le système.
Erreurs courante en C
■ CFLAGS indique les options par défaut du compilateur.
■ LDFLAGS indique les options par défaut de l’éditeur de lien.
■ On peut visualiser l’ensemble des réglages par défaut de
make avec l’option -p

- p. 16/52
Makefile: substitution et variables dynamique

Outils pour la programmation


● GNU
■ Si on a défini une variable:
● gcc
● make
SRC = main.c utils.c truc.c
● gdb
■ Alors l’expression ${SRC:.c=.o} vaudra:
Introduction
main.o utils.o truc.o
Pointeur de fonctions
■ Certaines variables sont positionnées dynamiquement lors
Erreurs courante en C
de l’évaluation d’une règle, par exemple $@ est le nom de la
cible de la règle:
main: main.o utils.o truc.o
${CC} -o $@ main.o utils.o truc.o
■ $< est le nom de la première dépendance sélectionnée

- p. 17/52

Makefile: règles implicites

Outils pour la programmation


● GNU
■ La compilation de programme C suit toujours le même
● gcc
● make
schéma, par exemple: gcc -c monprog.c -o
● gdb monprog.o
Introduction ■ On peut définir des règles par défaut pour les cibles ayant un
Pointeur de fonctions
suffixe particulier. Pour cela on indique à make quels sont
Erreurs courante en C
les suffixes intéressants et on spécifie la règle implicite. Par
exemple
.SUFFIXES : .o .c
.c.o :
${CC} ${CFLAGS} -c $< -o $@
■ On spécifie alors uniquement les dépendances pour chaque
fichier .o
.SUFFIXES : .o .c
.c.o :
${CC} ${CFLAGS} -c $< -o $@
main.o: main.c type.h

- p. 18/52
Makefile: Exemple
CC =gcc
EXE =ex1 ex1.1 ex1.2 ex1.3 ex2.1 ex3.1
Outils pour la programmation
● GNU
● gcc
SRC=$(EXE:=.c)
● make OBJ=$(SRC:.c=.o)
● gdb

Introduction
all: $(EXE)
Pointeur de fonctions

Erreurs courante en C
tar: dummy
make clean
cd ..;tar -cvf TD1_corr.tar TD1/ex*.c TD1/test*.i

.SUFFIXES : .o .c
.c.o :
${CC} ${CFLAGS} -c $< -o $@
dummy:

clean:
-rm -f *~ *.out $(EXE) *.o

- p. 19/52

Makefile: Exemple
Résultat de l’exécution de la commande make
gcc ex1.1.c -o ex1.1
Outils pour la programmation gcc ex1.2.c -o ex1.2
● GNU
● gcc
gcc ex1.3.c -o ex1.3
● make
● gdb
gcc ex2.1.c -o ex2.1
Introduction
gcc ex3.1.c -o ex3.1
Pointeur de fonctions

Erreurs courante en C

- p. 20/52
gdb: GNU symbolic debugger

Outils pour la programmation


● GNU
■ gdb est un debugger symbolique, c’est-à-dire un utilitaire
● gcc
● make
Unix permettant de contrôler le déroulement de programmes
● gdb C.
Introduction ■ gdb permet (entre autres) de mettre des points d’arrêt dans
Pointeur de fonctions
un programme, de visualiser l’état de ses variables, de
Erreurs courante en C
calculer des expressions, d’appeler interactivement des
fonctions, etc.
■ xxgdb ou ddd sont des interfaces graphiques qui facilitent
l’utilisation de gdb sous X-Window.
■ gdb ne nécessite aucun système de fenêtrage, il peut
s’exécuter sur un simple terminal shell (mode console).
■ Il est indispensable de comprendre le fonctionnement en
mode de gdb pour pouvoir utiliser les ddd.

- p. 21/52

Exemple de session gdb


#include <stdio.h>

Outils pour la programmation int main()


● GNU
● gcc {int i,*p;
● make
● gdb

Introduction
i=1;
Pointeur de fonctions
p=(int *)malloc(sizeof(int));
Erreurs courante en C *p=2;
*p+=i;
fprintf(stdout,"i=%d, p=%X, *p=%d\n",i,p,*p);
free(p);
return(0);
}
■ compilation avec -g:
shell$ gcc -g exgdb.c -o exgdb
■ lancement de gdb: shell$ gdb exgdb
GNU gdb 6.3-debian
(gbd)

- p. 22/52
Exemple de session gdb

Outils pour la programmation


● GNU
■ Lorsque l’on lance gdb avec la commande gdb exgdb.c,
● gcc gdb a chargé l’exécutable, il attend alors une commande
● make
● gdb gdb, comme par exemple run (pour exécuter le
Introduction programme), break (pour mettre un point d’arret dans le
Pointeur de fonctions programme), step (pour avancer d’une instruction dans le
Erreurs courante en C programme), etc.
■ Les points d’arrêt peuvent se positionner au début des
fonctions (break main, par exemple), ou à une certaine
ligne (break 6, par exemple), ou lorsqu’une variable
change de valeur (watch i, par exemple).

- p. 23/52

Exemple de session gdb


■ Suite de la session:
(gdb) break main
Outils pour la programmation
Breakpoint 1 at 0x8048424: file exgdb.c, line 6.
● GNU
● gcc
(gdb) run
● make
● gdb
Starting program: /home/trisset/cours/2005/AGP/cours_tr
Introduction
Breakpoint 1, main () at exgdb.c:6
Pointeur de fonctions
6 i=1;
Erreurs courante en C
(gdb)
gdb a lancé l’exécutable et arrêté l’exécution à la ligne 6 du
fichier (à la première ligne de la fonction main), le code de
cette ligne apparaît à l”écran.
■ On peut avancer d’un pas dans le programme:
(gdb) step
7 p=(int *)malloc(sizeof(int));
(gdb)
■ On peut afficher la valeur de i;
(gdb) print i
$1 = 1
(gdb) - p. 24/52
Exemple de session gdb
■ Affichage permanent de variables: display
(gdb) display i
Outils pour la programmation 1: i = 1
● GNU
● gcc (gdb)
● make
● gdb ■ Affichage de pointeurs (comme une variable):
Introduction
(gdb) display p
Pointeur de fonctions
2: p = (int *) 0xb8000540
Erreurs courante en C
(gdb)
■ Affichage d’objet pointés par les pointeurs :
(gdb) display *p
3: *p = -1208053760
(gdb)
(gdb) step
8 *p=2;
3: *p = 0
2: p = (int *) 0x804a008
1: i = 1
(gdb)
- p. 25/52

Exemple de session gdb


(gdb) step
9 *p+=i;
Outils pour la programmation 3: *p = 2
● GNU
● gcc 2: p = (int *) 0x804a008
● make
● gdb 1: i = 1
Introduction (gdb) step
Pointeur de fonctions 10 fprintf(stdout,"i=%d, p=%X, *p=%d\n",i,p,*p);
Erreurs courante en C 3: *p = 3
2: p = (int *) 0x804a008
1: i = 1
(gdb) next
i=1, p=804A008, *p=3
11 free(p);
3: *p = 3
2: p = (int *) 0x804a008
1: i = 1
(gdb) cont
Continuing.

Program exited normally. - p. 26/52


gdb commandes abrégées

Outils pour la programmation


● GNU
■ On peut taper la première lettres des commandesx:
● gcc
● make
■ r est équivalent à run
● gdb
■ b main est équivalent à break main
Introduction

Pointeur de fonctions
■ p var est équivalent à print var
Erreurs courante en C
■ d var est équivalent à display var
■ s est équivalent à step
■ n est équivalent à next
■ c est équivalent à continue
■ La commande run peut prendre des arguments, le
programme est alors exécuté avec les arguments donnés
■ la commande info permet d’afficher des informations sur
l’état du programme dans le débugger. Par exemple info b
liste les points d’arrêt.
■ La commande help est l’aide en ligne de gdb

- p. 27/52

ddd: data display debugger

Outils pour la programmation


● GNU
■ ddd est une interface graphique pour gdb.
● gcc
● make
■ Après avoir compilé avec l’option -g, on tape:
● gdb
ddd nomduprog
Introduction
Par exemple:
Pointeur de fonctions
ddd exgdb
Erreurs courante en C

- p. 28/52
ddd: haut de la fenêtre

Outils pour la programmation


● GNU
● gcc
● make
● gdb

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 29/52

ddd: bas de la fenêtre

Outils pour la programmation


● GNU
● gcc
● make
● gdb

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 30/52
ddd: fenêtre de commande

Outils pour la programmation


● GNU
● gcc
● make
● gdb

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 31/52

ddd: breakpoint

Outils pour la programmation


● GNU
● gcc
● make
● gdb

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 32/52
ddd: display

Outils pour la programmation


● GNU
● gcc
● make
● gdb

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 33/52

Liens à connaître

Outils pour la programmation


● GNU
■ make, documentation
● gcc http://www.gnu.org/software/make/manual/make.html
● make
● gdb ■ gcc home page: http://gcc.gnu.org/
Introduction
■ gdb documentation
Pointeur de fonctions
http://www.gnu.org/software/gdb/documentation/,
Erreurs courante en C
■ ddd documentation
http://www.gnu.org/software/ddd/manual/

- p. 34/52
Plan

Outils pour la programmation ■ Pointeurs de fonctions


Introduction
■ Les erreurs courantes en C (source
Pointeur de fonctions
http://nicolasj.developpez.com/articles/erreurs/
Erreurs courante en C
par exemple)

- p. 35/52

Utilité des pointeurs de fonction

Outils pour la programmation ■ Mécanismes dynamiques


Introduction ◆ plug-in
Pointeur de fonctions ◆ Modifier une fonctionnalité sans arrêter le programme
Erreurs courante en C ◆ ajouter de nouvelles fonctionnalités

■ Exemple: fonction de décodage de trame niveau 2:


dépendant de l’interface connectée (ethernet, wifi, etc.)

- p. 36/52
Un premier exemple

Outils pour la programmation


#include <stdio.h>
Introduction
#include <stdlib.h>
Pointeur de fonctions
//declaration de fonction
Erreurs courante en C
int fonct1(int a)
{
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. 37/52

Comprendre les déclarations

Outils pour la programmation ■ Déclaration d’une variable: int *q[3]


Introduction ◆ [] plus prioritaire que *, donc:
Pointeur de fonctions
int *q[3] ⇔ int (*(q[3]))
Erreurs courante en C ◆ l’expression (*(q[3])) est de type int
◆ l’expression q[3] est de type pointeur vers un int
◆ l’expression (i.e. la variable) q est de type tableau de
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. 38/52
Déclaration d’un pointeur de fonction

Outils pour la programmation ■ Déclaration d’un pointeur de fonction:


Introduction
int (*foncPtr)(int a)
Pointeur de fonctions ◆ l’expression (*foncPtr)(int a) est de type int
Erreurs courante en C ◆ l’expression (*foncPtr) est de type fonction qui prend
un int est renvoie un int
◆ l’expression (i.e. la variable) foncPtr est de type pointeur
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. 39/52

En fait, c’est un peu plus compliqué...

Outils pour la programmation ■ En C, une fonction est automatiquement castée en pointeur


Introduction
de fonction (et inversement):
Pointeur de fonctions
foncPtr=&fonct1 ⇔ foncPtr=fonct1
Erreurs courante en C (*foncPtr)(10); ⇔ (foncPtr)(10)
■ Tout comme pour les tableaux:
tab ⇔ &tab
■ 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. 40/52
On peut donc ecrire:

Outils pour la programmation


#include <stdio.h>
Introduction
#include <stdlib.h>
Pointeur de fonctions
//declaration de fonction
Erreurs courante en C
int fonct1(int a)
{
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. 41/52

Un autre exemple

Outils pour la programmation


int main(void)
Introduction
{
Pointeur de fonctions
//comparaison de deux entiers int i,t[6]={1,5,2,3,6,4};
Erreurs courante en C

int croissant(int i, int j) trie(t, 6, croissant);


{ for(i=0;i<6;i++)
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. 42/52
... la fonction tri

Outils pour la programmation


void trie(int tableau[], int taille, int (fcomp)(int, int))
Introduction
{
Pointeur de fonctions
int i,j,min;
Erreurs courante en C
//tri par permuation avec fcomp comme fonction de comparaiso
for (i=0;i<taille;i++)
{
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. 43/52

Passage de fonction par référence

Outils pour la programmation ■ Comme pour une variable normale, on peut modifier un
Introduction
pointeur de fonction en le passant en paramêtre par
Pointeur de fonctions
référénce.
Erreurs courante en C
■ Pour avoir une fonction qui modifie un pointeur de fonction
(i.e. qui modifie la qui fonction appelée lorsque le pointeur
est invoqué), il faut que son paramêtre soit un pointeur sur
un pointeur de fonction.

- p. 44/52
Passage de fonction par référence
changeOrdre(int (**fcomp1)(int, int), int (*fcomp2)(int, int))
{
Outils pour la programmation
*fcomp1=fcomp2;
Introduction
}
Pointeur de fonctions
int main(void)
Erreurs courante en C
{
int i,t[6]={1,5,2,3,6,4};
int (*fcomp)(int,int);

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. 45/52

fprintf(stdout," %d ",t[i]);

Outils pour la programmation

Introduction

Pointeur de fonctions

Erreurs courante en C

Les erreurs courantes en C

- p. 46/52
Confusion entre == et =

Outils pour la programmation


■ À ne pas faire:
Introduction
if (size = 0) ....
Pointeur de fonctions
■ Détection: l’option -Wall du compilateur avertit le
Erreurs courante en C
programmeur (warning)

- p. 47/52

Confusion entre opérateurs logiques et binaires

Outils pour la programmation ■ Le ET logique (&&) qui retourne 0 ou 1 (en s’arrêtant au


Introduction
premier argument s’il est faux)
Pointeur de fonctions
■ Le ET binaire (&) évalue ses deux opérandes et effectue le
Erreurs courante en C
ET bit à bit entre ses deux opérandes.
■ Le OU logique (||) qui retourne 0 ou 1 (en s’arrêtant au
premier argument s’il est vrai)
■ 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. 48/52
Problèmes de macros

Outils pour la programmation ■ On n’écrit pas


Introduction
#define MAX 10;
Pointeur de fonctions ◆ A[MAX] devient A[10;]
Erreurs courante en C
■ On n’écrit pas
#define MAX=10
◆ Erreur détectée à la compilation, mais lors de l’utilisation
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. 49/52

Fonctions retournant un caractère getc...

Outils pour la programmation char c;


Introduction while ( (c = getchar ()) != EOF)
Pointeur de fonctions ...
Erreurs courante en C ■ La fonction getchar retourne un entier

■ Les cast implicites effectués sont:


while ( (int)(c = (char)getchar ()) != EOF)
■ 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. 50/52
Erreurs avec if et for

Outils pour la programmation ■ point-virgule mal placé


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

- p. 51/52

Et les plus courantes...

Outils pour la programmation ■ Mauvaise indentation


Introduction
■ Pas de makefile (ou pas de cible clean dans le makefile)
Pointeur de fonctions

Erreurs courante en C
■ exemple de fichier configuration vi:
syntax on " coloration syntaxique
set autoindent " identation
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. 52/52

Vous aimerez peut-être aussi