AGP: Algorithmique et...

41
- p. 1/81 AGP: Algorithmique et programmation Tanguy Risset, Stéphane Ubéba [email protected], Stéphane.Ubé[email protected] Lab CITI, INSA de Lyon Version du November 20, 2007 introduction Présentation du cours Introduction Rappels d’architecture Rappels d’architecture Compilation logiciel Les bases du C Les fonctions Les entrées-sorties Introduction Pointeur de fonctions Erreurs courante en C - p. 2/81 Présentation du cours Enseignants: Cours 24h: Tanguy Risset, Stéphane Ubeda TD 30: TP 28h Déroulement du cours: Principes de la programmation en C Principes de l’algorithmique Notions de recherche opérationnelle

Transcript of AGP: Algorithmique et...

- p. 1/81

AGP: Algorithmique et programmation

Tanguy Risset, Stéphane Ubé[email protected], Stéphane.Ubé[email protected]

Lab CITI, INSA de LyonVersion du November 20, 2007

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 2/81

Présentation du cours

■ Enseignants:◆ Cours 24h: Tanguy Risset, Stéphane Ubeda◆ TD 30:◆ TP 28h

■ Déroulement du cours:◆ Principes de la programmation en C◆ Principes de l’algorithmique◆ Notions de recherche opérationnelle

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 3/81

Références utiles

■ livres:◆ Le langage C, Kernighan & Ritchie, Masson, 1990

la référence pour la programmation en C ANSI◆ Introduction à l’algorithmique, T. Cormen, C. Leiserson, R.

Rivest, 1994, DunodApproche complète et pédagogique de l’algorithmique

■ Sur le web◆ Poly de Bernard Cassagne (votre poly):

http://www-clips.imag.fr/commun/bernard.cassagne/In troduction_ANSI_C.htm

◆ 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 cestransparents)http://www-rocq.inria.fr/codes/Anne.Canteaut/COURS_ C/

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 4/81

Introduction

■ Historique◆ Créé par Dennis Ritchie pour écrire Unix pour le PDP-11

(publication 1978)◆ Standard ANSI C (1990)

■ Pourquoi C?◆ Avantages

■ Performance(http://shootout.alioth.debian.org ),portabilité, standard, proche de la machine

■ Permet de comprendre les mécanismes de l’exécutionde programmes ⇒ bonnes bases pour tous les autreslangages (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.)

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 5/81

Rappels sur l’architecture d’un ordinateur

■ Un ordinateur de bureau est composé (au moins):◆ D’un processeur◆ D’une mémoire (dite vive: rapide et non rémanente)◆ D’un espace de stockage (disque dur: lent, rémanent)◆ De périphériques d’entrée/sortie (écran, claviers, etc.)

■ Principe du processeur programmable:◆ Le processeur lit un programme en mémoire (programme

exécutable, dépendant du type de processeur).◆ En fonction de ce programme

■ Il lit ou écrit des données en mémoire à une certaineadresse mémoire (nombre entier sur 32 bits)

■ Il effectue des calculs entre ces données

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 6/81

Rappels d’architecture

Main

memory

I/O

controller

I/O

controller

I/O

controller

Disk Graphics

output

Network

Memory–I/O bus

Processor

Cache

Interrupts

Disk

Dynamic data

Static data

Reserved

Stack segment

Data segment

Text segment

7fffffffhex

10000000hex

400000hex

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 7/81

Architecture vue du programmeur

■ Les systèmes modernes permettent◆ D’exécuter plusieurs programmes indépendant en

parallèle (processus)◆ D’accéder à un espace mémoire plus grand que la

mémoire physique disponible (mémoire virtuelle)■ Pour le programmeur: tout cela est transparent

◆ Un seul programme s’exécute avec une mémoire trèsgrande disponible

■ La mémoire vue du processeur contient:◆ 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: lapile)

■ Le programmeur lui ne voit que les données (statiques etdynamiques)

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 8/81

Processus de compilation

■ le processus complet va traduire un programme C en codeexécutable (le chargement et l’exécution auront lieu plustard).

code asmassembleur

liensédition des

exechargement

compilateurobj

.o

Simulation

Exécution

.c .s

.alib

■ On nomme souvent compilation l’ensemblecompilateur+assembleur

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

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 9/81

Votre processus de compilation

■ Le programmeur:◆ Écrit le programme C: ici le dans le fichier ex.c◆ Compile vers un programme objet ex.o◆ Fait l’édition de lien pour générer l’executable ex

contenu de ex.cex.o

gcc −c ex.c

exgcc ex.c −o ex

stdio.h

ex.c

libstdio.a gcc ex.o −o ex

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 10/81

Dénomination à retenir

■ Le programme C que vous écrivez est le programme source(ex.c )

■ Le programme source est compilé en un programme objetpar le compilateur (ex.o )

■ Le programme source inclut un fichier d’en-tete (stdio.h )pour vérifier les noms des fonctions externes utilisées(printf )

■ le programme executable est construit par l’éditeur de liensgrâce au programme objet et aux bibliothèques.

■ Les bibliothèques (library enanglais) sont des codesassembleurs (i.e. déjà compilés) defonctions fréquements utilisées. Icila bibliothèque utilisée estlibstdio.a qui contient le codede la fonction printf

ex.ogcc −c ex.c

exgcc ex.c −o ex

stdio.h

ex.c

libstdio.a gcc ex.o −o ex

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 11/81

Notions de génie logiciel

■ Pour développer une application, on parle de logiciel plutôtque de programme

■ Un logiciel est plus qu’un programme■ Le cycle de vie du logiciel inclut:

◆ L’analyse du problème à résoudre◆ La conception d’une solution (spécification)◆ Le développement de la solution (programme)◆ Le test du programme◆ La livraison avec documentation associée◆ La maintenance

introduction

● Présentation du cours

● Introduction

● Rappels d’architecture

● Rappels d’architecture

● Compilation

● logiciel

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 12/81

Outils pour le développement logiciel

■ Méthodes◆ Réfléchir avant d’agir !◆ règles de développement (Merise, programmation par

test)◆ Language objet: C++, Java

■ Outils◆ Gestionnaire de compilation : make◆ Debugger : gbd, ddd, ....◆ Environnements de développement (intègrent tout):

eclipse, VisualC++

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 13/81

Les bases du C

■ Instruction, expression, programme

■ Éléments de base◆ Variable et types de base◆ Opérateurs◆ Types construits◆ Opération de Contrôle de flôt◆ Fonctions et passage de paramètres◆ Entrées-sorties◆ Visibilité et durée de vie des variables

■ Exemple: le tri d’un tableau d’entier

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 14/81

Syntaxe

■ La syntaxe est définie par des règles de grammaire.■ Extrait de la grammaire:

expression::primary| expression binop expression| expression asgnop expression| ....

primary::identifier| string| constant| ...

asgnop::=| +=| ...

binop::+| -| ...

■ x = 0 , a + b , a+=1 sont syntaxiquement corrects(respectent la grammaire)

■ Un programme syntaxiquement correct n’est pas forcémentun programme C valide. Exemple: 1 = 0 estsyntaxiquement correct mais sémantiquement incorrect.

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 15/81

Expression, Instruction

■ Une expression est une suite de composants élémentaires syntaxiquement correcte,par exemple: x = 0 ou bien(i >= 0) && (i < 10)

■ En C chaque expression produit:◆ une action (modification possible de l’état des variables en mémoire)◆ un résultat (valeur renvoyée par l’expression)

■ Une instruction est une expression suivie d’un point-virgule. Le point-virgule signifie enquelque sorte “évaluer cette expression et oublier le resultat”.

■ Plusieurs instructions peuvent être rassemblées par des accolades { et } pour formerune instruction composée (ou bloc) qui est syntaxiquement équivalent à uneinstruction. Par exemple,if (x != 0)

{

z = y / x;

t = y % x;

}

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 16/81

Structure d’un programme C

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

directives au préprocesseurdéclarations de variables globales

fonctions secondaires

int main(){ déclarations de variables internes

instructions}

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

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

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 17/81

Variables

■ La notion de variable est très importante en programmation■ Du point de vue sémantique, une variable est une entité qui

contient une information :◆ Une variable possède un nom, on parle d’identifiant◆ Une variable possède une valeur qui change au cours de

l’exécution du programme◆ Une variable possède un type qui caractérise l’ensemble

des valeurs qu’elle peut prendre■ Du point de vue pratique, une variable est une manière

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é” (_).

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 18/81

Types de base en C

■ En C, les variables doivent être déclarées avant d’êtreutilisées, on dit que C est un langage typé

■ Les types de base en C sont désignés par des spécificateursde type qui sont des mots clefs du langages:◆ les caractères (char ),◆ les entiers (int, short, , unsigned long )◆ les flottants (nombres réels, float, double ).◆ Il n’y a pas de type booleen, ils sont codés par des int

■ Une instruction composée d’un spécificateur de type etd’une liste d’identificateurs éventuellement initialisés séparéspar 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

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 19/81

Représentation de l’information

■ Le type d’une variable indique au compilateur la manière destocker la variabe en mémoire

■ Il est important de connaître comment sont stockées lesvariables car C propose de nombreuses manipulations auniveau bit.

■ La mémoire est une suite de bit structurée en octets (8 bits)puis en mots (4 octets, 32 bits).

■ L’adresse 1084 doit se lire comme “le 1084eme octet de lamémoire”

■ On utilisera trois notations pour représenter les valeursentiè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).

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 20/81

Les types entiers

mot-clef taille dénomination remarques

char 8 bits caractère peut être utilisé comme entiershort 16 bits entier court

int 32 bits entierlong >=32 bits entier long souvent 64 bits

■ En C les entiers signés sont représentés en complément à2, c’est à dire (pour un entier n sur 32 bit):◆ le bit de poids fort (bit 32) représente le signe (0 pour

positif, 1 pour négatif)◆ Si l’entier est positif: les 31 autres bits correspondent à la

décomposition de l’entier en base 2.◆ 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

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 21/81

Les types entier

■ Les mots-clef des types peuvent être précédés d’attributs.Par exemple unsigned int n indique que l’entier n estpositif, la représentation en complément à deux n’est pasutilisée on a alors 0 <= n < 232

signed char [−27; 27[

unsigned char [0; 28[

short int [−215; 215[

unsigned short int [0; 216[

int [−231; 231[

unsigned int [0; 232[

■ Le fonction sizeof calcul la taille d’un type ou d’uneexpression. Le résultat est un entier égal au nombre d’octetsnécessaires pour stocker le type ou l’objet. Par exempleci-dessous taille prendra la valeur 2 les deux foisunsigned short x;taille = sizeof(unsigned short);taille = sizeof(x);

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 22/81

Les types flottants

mot-clef taille DEC Alpha Taille PC Intel

float 32 bits 32 bits flottant

double 64 bits 64 bits flottant double précision

long double 64 bits 128 bits flottant quadruple précision

■ Les flottants sont généralement stockés en mémoire sous la

représentation de la virgule flottante normalisée. On écrit le nombresous la forme

signe 0,mantisse Bexposant

(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

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 23/81

Les caractères

■ Un char peut contenir n’importe quel élément du jeu de caractères de la machineutilisée.

■ un char est codé sur un octet ;

■ Le jeu de caractères utilisé correspond généralement au codage ASCII (sur 7 bits).

■ La plupart des machines utilisent désormais le jeu de caractères ISO-8859-1 (aussiappelée ISO-LATIN-1) dont les 128 premiers caractères correspondent aux caractèresASCII.

■ extrait de la table ASCII:

caractère valeur valeur · caractère valeur valeurreprésenté (dec) (hex) représenté (dec) (hex)

! 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 . . . . . . . . .

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 24/81

Les constantes

■ Les valeurs exprimées dans un programme C sont desconstantes

■ Les constantes entière peuvent être exprimées en décimal(int i=12 ) ou en hexadécimal (int i=0xA ),

■ On peut aussi indiquer qu’elle doivent être stockées sur unlong (12L ) ou en unsigned (12U).

■ Les constantes réelles suivent le même principe■ 12.34 (double ), 12.3e-4 , (double ), 12.34F (float ),

12.34L (Long )■ Les caractères imprimable sont repérentés entre cotes (’):

char a=’Z’

■ Les caractères non imprimables sont représentés en codeoctal (base 8) précédé d’un antislash, Les plus fréquent ontdes représentations standard: \n nouvelle ligne, \r retourchariot, \t tabulation horizontale\f saut de page,

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 25/81

Constantes et variables

■ La notion de constante n’est pas limitée aux valeurs fixes■ Une constante est une valeur non modifiable, par exemple

l’adresse d’une variable.■ Il existe une différence fondamentale avec les variables: il

n’y a pas de place réservée pour une constante dans lamémoire lors de l’exécution d’un programme.

■ C’est le compilateur qui met en dur la valeur de la constantelorsqu’il génère l’instruction:j=i+10 ⇒ add Rj,Ri,#10

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 26/81

Les opérateurs

■ affectation: variable = expression

■ opérateurs arithmétiques +,-, * ,/,% ,expression-1 op expression-2

■ opérateurs relationnels >,<, >=,<=,==,!=

■ opérateurs logiques booléens &&, ||, !

■ opérateurs logiques bit à bit &, |, ˆ, ˜,«,»

■ opérateurs d’affectation composée +=, -=, * =, /= ,expression-1 op= expression-2⇔expression-1 = expression-1 op expression-2

■ opérateurs d’incrémentation et de décrémentation, ++, - -

■ opérateur de conversion de type (type) objeta=(int) c

■ opérateur adresse &,a=&b

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 27/81

Règles de priorité des opérateurs

■ les opérateurs sont plus ou moins prioritaires,■ Dans le cas de priorité égales on a un ordre d’évaluation

(associatifs à droite ou à gauche)■ ordre de priorité:

opérateurs associativité

() [] -> . droite

! ++ – -(unaire) (type) *(indirection) &(adresse) sizeof gauche

* / % droite

+ -(binaire) droite

« » droite

< <= > >= droite

== != droite

&(et bit-à-bit) droite

| droite

&& droite

|| droite

? : gauche

= += -= *= /= %= &= =̂ |= «= »= gauche

, droite

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 28/81

Types construits

■ À partir des types prédéfinis du C (caractères, entiers,flottants), on peut créer de nouveaux types, appelés typescontruits, qui permettent de représenter des ensembles dedonnées organisées.

■ Les tableaux■ Les structures■ Les unions■ Les énumérations■ Les constructeurs de type

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 29/81

Les tableaux

■ Un tableau est un ensemble fini d’éléments de même type,stockés en mémoire à des adresses contiguës.

■ La déclaration d’un tableau tab de 10 entiers se fait de lafaçon suivante : int tab[10];

■ On accède au troisième élément du tableau tab parl’expression tab[2] . Les tableaux en C commencenttoujours à 0.

■ On peut définir des tableaux multidimensionnels. Exemple:matrice Md’entiers de 10 lignes 5 colonnes int M[10][5]

■ Important: un tableau en C peut être vu comme un pointeursur le premier élément du tableau:int * tab; ⇔ int tab[];

■ Mais il faut savoir qu’en C un tableau est une constante

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 30/81

Tableaux: exemple

char tab[10] = {’e’,’x’,’e’,’m’,’p’,’l’,’e’,’\0’};main(){

int i;for (i = 0; i < 10; i++)

printf("tab[%d] = %c\n",i,tab[i]);}

tab[0] = etab[1] = xtab[2] = etab[3] = mtab[4] = ptab[5] = ltab[6] = etab[7] =tab[8] =tab[9] =

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 31/81

Tableaux: exemple

#define M 2

#define N 3

int tab[M][N] = {{1, 2, 3}, {4, 5, 6}};

main()

{

int i, j;

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

{

for (j = 0; j < N; j++)

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

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 32/81

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

■ En C une chaine de caractères n’est pas un type de base:c’est un tableau de caractères terminé par le caractèrespécial ’\ 0’ (ou NULL: octet valant 0).

■ On peut la noter entre double cote:char chaine[10]="bonjour"

■ Où comme un tableau de caractère (jamais utilisé):char chaine[10]={’b’,’o’,’n’,’j’,’o’,’u’,’r’,’\0’}

■ Comme un tableau en C est assimilé à un pointeur sur ledébut du tableau on trouvera souvent des chaines decaractè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’).

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 33/81

Les structures

■ Une structure est une suite finie d’objets de types différents.■ Contrairement aux tableaux, les différents éléments d’une

structure n’occupent pas nécessairement des zonescontiguës en mémoire.

■ Chaque élément de la structure, appelé membre ou champ,est désigné par un identificateur.

■ Deux manières équivalentes de définir une variable zcomplexe:

struct complexe{

double reelle;double imaginaire;

} z;

struct complexe{

double reelle;double imaginaire;

};struct complexe z;

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

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 34/81

Les structures de contrôle de flot

■ Les objets que nous avons rencontrés permettent de fairedes calculs, pas de contrôler quels calculs sont faits

■ Les structures de contrôles sont de deux types:◆ Les boucles◆ Les instructions de branchement

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 35/81

Les boucles

■ Boucles while :

while (expression )instruction

i = 1;while (i < 10)

{printf(" i = %d \n",i);i++;

}

■ Boucles for

for (expr 1 ;expr 2 ;expr 3)instruction

expr 1;while (expr 2 )

{instructionexpr 3;

}

introduction

Les bases du C

● Syntaxe

● types de base

● Les opérateurs

● Types construits

● Les tableaux

● chaînes de caractères

● contrôle de flot

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 36/81

Les instructions de branchement

■ Branchement conditionnelif (expression-1 )

instruction-1else instruction-2

ou if (expression-1 )instruction-1

■ Branchement multiple switch :switch (expression )

{case constante-1:

liste d’instructions 1

break;

case constante-2:

liste d’instructions 2

break;

case constante-3:

liste d’instructions 3

break;

default:

liste d’instructions defaut

break;

}

■ Branchement non conditionnel: break, continue

■ Branchement à ne pas utiliser: goto

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 37/81

Les fonctions

■ On peut en C découper un programme en plusieursfonctions.

■ Seule la fonction main est obligatoire.■ Même si vous ne définissez pas de fonction, vous utilisez les

fonctions des biblothèques C standard (return, printfpar exemple)

■ Définition de fonction:

type nom (type-1 arg-1,...,type-n arg-n)

{[déclarations de variables locales ]

liste d’instructions

}

int factorielle(int n)

{int i, fact;

for (i = 1,fact=1; i<=n; i++)

fact * = i;

return(fact);

}

■ La première ligne int factorielle(int n) s’appellel’en-tête (ou prototype, ou encore signature) de la fonction.

■ Appel de fonction (dans main() par exemple):x=factorielle(10);

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 38/81

Passage de paramètres

■ Une fonction communique des valeurs avec sonenvironnement appelant à travers les paramêtres et lerésultats.

■ dans int factorielle(int n) , n est le paramètreformel de la fonction. Il peut être utilisé dans le corps de lafonction comme une variable locale.

■ dans x=factorielle(10); , 10 est le paramètre effectifutilisé lors de cet appel.

■ En C, tout ce passe lors de cette appel comme si onexécutait le corps de la fonction avec la case mémoire pourn contenant une copie de la case mémoire contenant 10. Ondit 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 valeurdu paramètre effectif (10).

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 39/81

Imbrication de fonctions

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

■ En revanche on peut utiliser une fonction dans une fonction.■ Pour cela il y a deux contraintes:

1. Au moment de la compilation, lorsque le compilateurrencontre l’appel à une fonction factorielle , il faut qu’ilai déjà rencontré l’en-tète de la fonction intfactorielle(int n)

2. Au moment de l’édition de lien, il faut que l’un des codesobjet contienne le code compilé de la fonction factorielle.

■ On a plusieurs moyens pour assurer ces contraintes:1. Un seul fichier2. Déclarer les en-têtes de fonctions en début de fichier3. Compilation séparée

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 40/81

Fonctions dans Un seul fichier

//fonction factorielle

//calcule n! ou n entier

int factorielle(int n)

{int i, fact;

//double initialisation

for (i = 1,fact=1; i<=n; i++)

fact * = i;

return(fact);

}

//fonction main

//affiche 10! à l’ecran

int main()

{int x;

x=factorielle(10);

printf("10!=%d\n",x);

return(0);

}

■ Compilation:gcc fact1.c -o fact

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 41/81

Fonction avec déclaration des en-têtes//Declaration en-tetes

int factorielle(int n);

//fonction main

//affiche 10! à l’ecran

int main()

{int x;

x=factorielle(10);

printf("10!=%d\n",x);

return(0);

}

//fonction factorielle

//calcule n! ou n entier

int factorielle(int n)

{int i, fact;

//double initialisation

for (i = 1,fact=1; i<=n; i++)

fact * = i;

return(fact);

}

■ attention au ; aprèsl’en-tête.

■ Commande decompilation:gcc fact1.c -ofact

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 42/81

Deux fichiers

//fichier fact3.c

//fonction factorielle

//calcule n! ou n entier

int factorielle(int n)

{int i, fact;

//double initialisation

for (i = 1,fact=1; i<=n; i++)

fact * = i;

return(fact);

}

//fichier main1.c

//Declaration en-tetes

int factorielle(int n);

//fonction main

//affiche 10! à l’ecran

int main()

{int x;

x=factorielle(10);

printf("10!=%d\n",x);

return(0);

}

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

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 43/81

Fonctions: La bonne manière de faire

//fichier fact3.c

//fonction factorielle

//calcule n! ou n entier

int factorielle(int n)

{int i, fact;

//double initialisation

for (i = 1,fact=1; i<=n; i++)

fact * = i;

return(fact);

}

//fichier fact3.h

//Declaration en-tetes

int factorielle(int n);

//fichier main2.c

#include "fact3.h"

//fonction main

//affiche 10! à l’ecran

int main()

{int x;

x=factorielle(10);

printf("10!=%d\n",x);

return(0);

}

■ On définit les en-têtes dans un fichier d’en-têtes pour laréutilisation par d’autres programmes.

■ Commandes de compilation:gcc -c fact3.c -o fact3.ogcc -c main2.c -o main2.ogcc main2.o fact3.o -o main2

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 44/81

Récursivité

■ Une fonction peu s’appeler elle-même, c’est alors unefonction récursive.

■ la récursion est une autre manière d’effectuer des boucles.//fonction factRecurs

//calcule n! ou n entier>0

//de manière récursive

int factRecurs(int n)

{int fact;

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

fact=1;

else

fact=n * factRecurs(n-1);

return(fact);

}

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 45/81

Récursivité

■ La récursivité est très importante dans certains paradigmesde programmation (programmation fonctionnelle).

■ Elle correspond à une méthode naturelle de décompositiond’un problème en problèmes plus simple:◆ pour calculer n!, je cacule (n − 1)! (plus simple)◆ puis je calcule n ∗ (n − 1)!

■ Pour s’assurer que. que le programme ne va pas bouclerindé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 lacondition d’arret soit vérifiée, ici cette quantitée est n lavaleur du paramètre.

◆ On peut formaliser cela avec la notion d’invariant

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 46/81

Portée des variable

■ Les variables manipulées dans un programme C ne sont pastoutes traitées de la même manière. En particulier, ellesn’ont pas toutes la même durée de vie. On distingue deuxcatégories de variables.◆ Les variables permanentes (ou statiques)◆ Les variables temporaires

■ Chaque variable déclarée a une portée (ou durée de vie) quiest 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). Laportée (ou durée de vie) de ces variables est limitée au bloc.

■ Les blocs sont forcément imbriqués lexicalement, lors d’uneutilisation d’une variable n, elle peut avoir été déclarée deuxfois dans la suite des blocs englobant. L’utilisationcorrespond à celle de la première définition rencontréelorsque l’on remonte dans les blocs (i.e. la dernièreeffectuée temporellement).

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 47/81

Portée: exemple

int n = 10;

void fonction();

void fonction()

{int n = 0;

n++;

printf("appel numero %d\n",n);

return;

}

main()

{int i;

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

fonction();

}

----------------

appel numero 1

appel numero 1

appel numero 1

appel numero 1

appel numero 1

introduction

Les bases du C

Les fonctions

● Les fonctions

● Récursivité

● Portée des variables

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 48/81

Portée: exemple

int n;

void fonction();

void fonction()

{ n++;

printf("appel numero %d\n",n);

return;

}

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

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 49/81

Les entrées-sorties

■ La librairie standard libstdio.a propose des fonctionspour faire des entrées-sorties sur les périphériquesstandard: l’écran et le clavier.

■ Ces fonctions sont printf pour écrire et scanf pour lire■ Il faut inclure la directive #include <stdio.h> au début

du fichier si on désire les utiliser.■ Ce sont des fonctions d’impression formatée, ce qui signifie

que les données sont converties selon le format particulierchoisi.

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 50/81

La fonction printf

■ La syntaxe de la fonction printf est:printf("chaîne de contrôle ",expr-1, ..., expr-n);

■ La "chaîne de contrôle" contient le texte à afficher etles spécifications de format correspondant à chaqueexpression à afficher.

■ %dindique l’affichage d’un entier signé en décimal.■ %uindique 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;

a=10;

printf("a vaut %d \n",a);

int a;

a=10;

printf("a vaut %4d \n",a);■ résultats:

a vaut 10 a vaut 10

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 51/81

printf : exemples

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

int a;

a=10;

printf("a vaut (en hexa) %x \n",a);

short a;

a=10;

//conversion en int

printf("a vaut %d \n",a);■ résultats:

a vaut (en hexa) A a vaut 10

■ Attention ! Il y a une conversion de type:

■ exemples:char a;

a=66;

//conversion en int

printf("a vaut %d \n",a);

short a;

a=66;

printf("a vaut %c \n",a);

■ résultats:

a vaut 66 a vaut B

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 52/81

Encore printf

■ exemples: %f, %edouble x = 1e-8 + 1000;

printf("x vaut %f \n",a);

double x = 1e-8 + 1000;

printf("x vaut %e \n",a);■ résultats:

x vaut 1000.000000 x vaut 1.000000e+03

■ exemples: (conversion vers unsigned )

int a;

a=-23674;;

printf("a vaut %d \n",a);

int a;

a=-23674;;

//conversion en unsigned

printf("a vaut %u \n",a);■ résultats:

a vaut -23674 a vaut 4294943622

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 53/81

Encore printf

■ programme:#include <stdio.h>

int main()

{

fprintf(stdout,"Ascii[%d]=%c, en octal: %o en hexa: %x\n" ,

’\101’,’\101’,’\101’,’\101’);

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$ exCha r

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$

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 54/81

Attention aux chaines!

■ programme:#include <stdio.h>

int main()

{int i;

char chaine[4]={’\101’,’\101’,’\101’,’\0’};

char fausseChaine[3]={’\101’,’\101’,’\101’};

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

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

return(0);

}■ résultat:

trisset@hom:~/cours/2005/AGP/cours_tri/transp$ exCha r2

chaine=AAA,

fausseChaine=AAA ·öÿ¨öÿ¿;<nAAA,

trisset@hom:~/cours/2005/AGP/cours_tri/transp$

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 55/81

La fonction scanf

■ La syntaxe de la fonction scanf est:scanf("chaîne de contrôle ",expr-1, ..., expr-n);

■ Ici, la "chaîne de contrôle" ne contient que les formats

■ Les données à entrer au clavier doivent être séparées par des blancs oudes <RETURN> sauf s’il s’agit de caractères (<RETURN> est un caractère).

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

■ 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.

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 56/81

Passage de paramêtre par référence

■ Tout se passe comme si la fonction scanf modifiait un deses argument.

■ En fait comme les argument sont passé par valeurs, on doitpasser en paramêtre un pointeur sur l’objet à modifier (doncpasser l’adresse de l’objet)

■ La fonction scanf ne peut modifier son argument, mais ellepeut modifier l’objet pointé par l’argument.

■ Ce mechanisme est utilisé systématiquement en C, pour quela fonction modifie un objet, il est passé en argument parréférence.

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 57/81

Fichiers

■ Les accès à un fichier se font par l’intermédiaire d’un tampon(buffer) qui permet de réduire le nombre d’accès auxpériphériques (disque...).

■ Pour pouvoir manipuler un fichier, un programme a besoind’un certain nombre d’informations : l’adresse du tampon,position dans le fichier, mode d’accès (lecture ou écriture) ...

■ Ces informations sont rassemblées dans une structure dontle type, FILE * , est défini dans stdio.h . Un objet de typeFILE * est un stream (flot).

■ Avant de lire ou d’écrire dans un fichier, on l’ouvre par lacommande fich=fopen("nom-de-fichier","r") .Cette fonction dialogueavec 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 fonctionfclose(fich) .

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 58/81

Fichiers

■ on peut ouvrir un fichier sous plusieurs modes: lecture ("r" ), écriture au début ("w" ),écriture à la fin ("a" ). fopen retourne 0 en cas d’echec.

■ Exemple:FILE * fich;

fich=fopen("./monFichier.txt");

if (!fich) fprintf(stderr,"Erreur d’ouverture : %s\n",". /monFichier.txt");

■ Un objet de type FILE est quelquefois appelé un déscripteur de fichier, c’est un entierdésignant quel est le fichier manipulé.

■ 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 stderrafin que ces messages apparaissent à l’écran même lorsque la sortie standard estredirigée.

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 59/81

Autres fonction de lecture/ecriture

■ Entrée/sorties de caractères◆ int fgetc(FILE * flot);◆ int fputc(int caractere, FILE * flot)

■ Entrée/sorties de chaînes de caractères◆ char * fgets(char * chaine, int taille, FILE * flot);◆ int fputs(const char * chaine, FILE * flot)

■ Entrée/sorties binaires◆ size_t fread(void * pointeur, size_t taille, size_t nombre,

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.

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 60/81

fgetc, fputc: exemple#include <stdio.h>

#include <stdlib.h>

#define ENTREE "entree.txt"

#define SORTIE "sortie.txt"

int main(void)

{FILE * f_in, * f_out;

int c;

if ((f_in = fopen(ENTREE,"r")) == NULL)

{

fprintf(stderr, "\nErreur: Impossible de lire le fichier % s\n",ENTREE);

return(EXIT_FAILURE);

}

if ((f_out = fopen(SORTIE,"w")) == NULL)

{

fprintf(stderr, "\nErreur: Impossible d’ecrire dans le fi chier %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);

}

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 61/81

Arguments de la fonction main

■ La fonction main doit être présente si le programme estutilisé directement (pas comme une librairie), par exemple:appelé depuis le shell.

■ En général, la fonction main retourne un code d’erreur detype int .

■ Lorsque l’on compile avec la commande gcc monProg.c-o monProg , l’exécution de la command monProg dans unshell appelle la fonction main

■ Si on lance la commande monProg avec des arguments (ex:monProg fichier1.txt , il est possible de récupérer dansla fonction main la valeur de ces arguments sous forme dechaînes de caractères: on utilise les arguments standard dela fonction main : int argc (argument count), char

* argv[] (argument values) (on peut aussi récuperer desvariables d’environnement grâce à envp )

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 62/81

Exemple de fonction main

■ Multiplication de deux entier: gcc mult.c -o multshell> mult 8 32Le produit de 8 par 32 vaut: 256

#include <stdio.h>

#include <stdlib.h>

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

{

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);

}

introduction

Les bases du C

Les fonctions

Les entrées-sorties

● Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 63/81

Convention d’écriture en C

■ Il existe très peu de contraintes dans l’écriture d’unprogramme C. Toutefois ne prendre aucune précautionaboutirait à des programmes illisibles.

■ On n’écrit qu’une seule instruction par ligne : le point virguled’une instruction ou d’une déclaration est toujours le derniercaractère de la ligne.

■ Les instructions sont disposées de telle façon que lastructure 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 lesinstructions d’un même bloc soient alignées. Le mieux estd’utiliser le mode C d’emacs ou de vi .

■ On commente abondament le code

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 64/81

Plan

■ Pointeurs de fonctions■ Les erreurs courantes en C (source

http://nicolasj.developpez.com/articles/erreurs/par exemple)

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 65/81

Utilité des pointeurs de fonction

■ Mécanismes dynamiques◆ plug-in◆ Modifier une fonctionnalité sans arrêter le programme◆ ajouter de nouvelles fonctionnalités

■ Exemple: fonction de décodage de trame niveau 2:dépendant de l’interface connectée (ethernet, wifi, etc.)

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 66/81

Un premier exemple

#include <stdio.h>

#include <stdlib.h>

//declaration de fonction

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);

}

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 67/81

Comprendre les déclarations

■ Déclaration d’une variable: int * q[3]◆ [] plus prioritaire que * , donc:

int * q[3] ⇔ int ( * (q[3]))◆ 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 crochetsaprès un symbole indique que le symbole est un tableau).

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 68/81

Déclaration d’un pointeur de fonction

■ Déclaration d’un pointeur de fonction:int ( * foncPtr)(int a)◆ l’expression ( * foncPtr)(int a) est de type int◆ 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 lafonction é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)

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 69/81

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

■ En C, une fonction est automatiquement castée en pointeurde fonction (et inversement):foncPtr=&fonct1 ⇔ foncPtr=fonct1( * foncPtr)(10); ⇔ (foncPtr)(10)

■ Tout comme pour les tableaux:tab ⇔ &tab

■ Pour les fonctions et les tableaux qui ne sont pas desL-values (on les appelle quelquefois des labels) lecompilateur identifie a et &a

■ On peut donc écrire:int ( * foncPtr)(int a);

foncPtr=fonct1;foncPtr(10);

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 70/81

On peut donc ecrire:

#include <stdio.h>

#include <stdlib.h>

//declaration de fonction

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);

}

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 71/81

Un autre exemple

//comparaison de deux entiers

int croissant(int i, int j)

{

if (i<=j) return 0;

else return 1;

}

int decroissant(int i, int j)

{

if (i<=j) return 1;

else return 0;

}

int main(void)

{

int i,t[6]={1,5,2,3,6,4};

trie(t, 6, croissant);

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

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

fprintf(stdout,"\n");

trie(t, 6, decroissant);

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

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

fprintf(stdout,"\n");

return 0;

}

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 72/81

... la fonction tri

void trie(int tableau[], int taille, int (fcomp)(int, int) )

{

int i,j,min;

//tri par permuation avec fcomp comme fonction de comparais on

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 ;

}

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 73/81

Passage de fonction par référence

■ Comme pour une variable normale, on peut modifier unpointeur de fonction en le passant en paramêtre parréférénce.

■ Pour avoir une fonction qui modifie un pointeur de fonction(i.e. qui modifie la qui fonction appelée lorsque le pointeurest invoqué), il faut que son paramêtre soit un pointeur surun pointeur de fonction.

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 74/81

Passage de fonction par référencechangeOrdre(int ( ** fcomp1)(int, int), int ( * fcomp2)(int, int))

{

* fcomp1=fcomp2;

}

int main(void)

{

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++)

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

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 75/81

Les erreurs courantes en C

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 76/81

Confusion entre == et =

■ À ne pas faire:if (size = 0) ....

■ Détection: l’option -Wall du compilateur avertit leprogrammeur (warning )

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 77/81

Confusion entre opérateurs logiques et binaires

■ Le ET logique (&&) qui retourne 0 ou 1 (en s’arrêtant aupremier argument s’il est faux)

■ Le ET binaire (&) évalue ses deux opérandes et effectue leET bit à bit entre ses deux opérandes.

■ Le OU logique (|| ) qui retourne 0 ou 1 (en s’arrêtant aupremier argument s’il est vrai)

■ Le OU binaire (| ) évalue ses deux opérandes et effectue leOU bit à bit entre ses deux opérandes.

■ Impossible à détecter à la compilation.

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 78/81

Problèmes de macros

■ On n’écrit pas#define MAX 10;◆ A[MAX] devient A[10;]

■ 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éfinitionde MAX).

■ On écrit#define MAX 10

■ En cas de doute, on peut utiliser gcc -E pour vérifierl’expansion correcte des macros.

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 79/81

Fonctions retournant un caractère getc ...

char c;while ( (c = getchar ()) != EOF)...■ 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 peutparfaitement être égal à 128, dans ce cas on dépasse lacapacité de stockage d’un char et l’on se retrouve avec unrésultat égal à -128 : la condition du while sera toujoursfausse, le programme boucle indéfiniment!

■ Il faut écrire:int cInt;char c;while ( (cInt = getchar ()) != EOF)

{c=(char)cInt;

...

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 80/81

Erreurs avec if et for

■ point-virgule mal placéif (a < b) ;

a = b;for (i=0; i<N; i++);

printf("%d", i);■ Le mauvais else

if (a < b)if (b < c) then b = c;

elseb = a;

■ Ce qu’il fallait faire:if (a < b)

{ if (b < c) then b = c; }else

b = a;

introduction

Les bases du C

Les fonctions

Les entrées-sorties

Introduction

Pointeur de fonctions

Erreurs courante en C

- p. 81/81

Et les plus courantes...

■ Mauvaise indentation■ Pas de makefile (ou pas de cible clean dans le makefile)■ exemple de fichier configuration vi:

syntax on " coloration syntaxiqueset autoindent " identationset cindent " pour Cset nopasteset ts=4 " tabulation a 4 caracteresset sw=4

■ Sous vi:◆ == pour indenter la ligne courante,◆ =Gpour identer tout le fichier: