• Aucun résultat trouvé

[PDF] Cours de programmation avancée avec exemples | Cours langage c

N/A
N/A
Protected

Academic year: 2021

Partager "[PDF] Cours de programmation avancée avec exemples | Cours langage c"

Copied!
94
0
0

Texte intégral

(1)

´

Ecole Nationale Sup´

erieure

de Techniques Avanc´

ees

Programmation en C

Pierre-Alain Fouque et David Pointcheval

E-mail : Pierre-Alain.Fouque@ens.fr Web : http://www.di.ens.fr/~fouque/

(2)
(3)

Table des mati`

eres

1 Introduction 11

1.1 L’ordinateur . . . 11

1.2 Programmer en C . . . 12

1.2.1 G´en´eralit´es . . . 12

1.2.2 Un ´editeur de texte : emacs . . . 12

1.2.3 Analyse du programme . . . 15

1.2.4 Un compilateur C : gcc . . . 16

1.3 Quelques g´en´eralit´es sur la syntaxe du langage C . . . 17

1.3.1 Mise en page et indentation . . . 17

1.3.2 Les identificateurs . . . 17

1.3.3 Les instructions . . . 17

1.3.4 Organisation d’un programme C . . . 18

2 Les types 21 2.1 Les types . . . 21

2.2 Les types de base . . . 22

2.2.1 Les types entiers (int, short int, long int et long long int) . 22 2.2.2 Les types flottants (float, double et long double) . . . 22

2.2.3 Le type caract`ere (char) . . . 23

2.3 Les types structur´es . . . 23

2.3.1 Les tableaux . . . 23

2.3.2 Les tableaux `a plusieurs dimensions . . . 24

2.3.3 Les structures . . . 24

2.4 Les pointeurs . . . 24

2.5 Nouveaux types . . . 25

3 Les variables et les constantes 27 3.1 D´eclaration des variables . . . 27

3.1.1 D´eclaration des types simples . . . 28

3.1.2 D´eclaration des tableaux et pointeurs . . . 28

3.1.3 D´eclaration des objets complexes . . . 29

3.2 Initialisation des variables . . . 30

3.3 Constantes . . . 30

3.3.1 Types simples . . . 30

3.3.2 Types complexes . . . 31

3.4 Dur´ee de vie et visibilit´e des variables . . . 31 1

(4)

4 Les entr´ees-sorties 35

4.1 L’affichage avec printf . . . 35

4.1.1 Simple affichage . . . 35

4.1.2 Formattage des sorties . . . 36

4.2 La saisie avec scanf . . . 37

5 Les op´erateurs et les expressions 39 5.1 Les op´erateurs . . . 39

5.1.1 Les op´erateurs arithm´etiques . . . 40

5.1.2 Op´erateur de conversion de type (“ cast ”) . . . 42

5.1.3 Op´erateur de taille . . . 42

5.1.4 Op´erateurs logiques . . . 43

5.1.5 Op´erateurs de masquage . . . 43

5.1.6 Op´erateurs de relations . . . 43

5.1.7 Op´erateur d’affectation . . . 43

5.1.8 Op´erateurs abr´eg´es . . . 44

5.2 Les expressions . . . 44

6 Les structures de contrˆole 45 6.1 Instruction . . . 45

6.2 Les boucles . . . 45

6.2.1 Les boucles while . . . 46

6.2.2 Les boucles for . . . 46

6.2.3 Les boucles do while . . . 48

6.3 Les conditions . . . 49 6.3.1 Condition if . . . 49 6.3.2 Condition switch . . . 50 6.4 Sauts Inconditionnels . . . 50 6.4.1 break . . . 50 6.4.2 continue . . . 50 6.4.3 return . . . 50 6.4.4 goto . . . 51 7 Programme Structur´e 53 7.1 Les fonctions . . . 53

7.1.1 D´eclaration d’une fonction . . . 54

7.1.2 Corps de la fonction . . . 54

7.1.3 Retour de la r´eponse . . . 54

7.1.4 Arguments d’une fonction . . . 55

7.1.5 Fonction main . . . 56 7.2 R´ecursivit´e . . . 56 7.3 Les modules . . . 58 7.3.1 Structure . . . 58 7.3.2 Compilation . . . 59 7.4 Le pr´eprocesseur . . . 61 7.4.1 Inclusions et d´efinitions . . . 61 7.4.2 Compilation conditionnelle . . . 62

(5)

TABLE DES MATI `ERES 3

7.4.3 Le pr´eprocesseur gcc . . . 62

8 Les pointeurs, les tableaux et les structures 65 8.1 Pointeurs . . . 65

8.1.1 D´efinition . . . 65

8.1.2 Utilisation . . . 66

8.1.3 Passage par adresse . . . 66

8.2 Tableaux . . . 67

8.3 Allocation dynamique de m´emoire . . . 67

8.4 Les structures . . . 68

9 Les structures dynamiques 71 9.1 Structure de liste . . . 71

9.2 Impl´ementation des listes chaˆın´ees . . . 72

9.3 Extensions . . . 72

9.3.1 Listes doublement chaˆın´ees . . . 72

9.3.2 Arbres . . . 73

10 L’environnement sous UNIX 75 10.1 Une construction sur mesure : make . . . 76

10.1.1 Fichier de Configuration : Makefile . . . 76

10.1.2 Wildcards et D´ependances . . . 77

10.1.3 Constantes et Variables . . . 77

10.1.4 Cibles Fictives . . . 78

10.1.5 Invocation de la Commande make . . . 78

10.2 Une gestion des versions : cvs . . . 80

10.2.1 Cr´eation d’un projet . . . 80

10.2.2 Fichier d’information . . . 80

10.2.3 Modifications de la structure . . . 80

10.2.4 Int´egration des modifications . . . 81

10.2.5 Gestion des versions . . . 81

10.2.6 Commentaires . . . 81

10.3 Le d´ebogueur : gdb . . . 82

10.3.1 Lancement du d´ebogueur . . . 82

10.3.2 Commandes de base . . . 82

11 Quelques compl´ements 85 11.1 Les chaˆınes de caract`eres . . . 85

11.1.1 Structure d’une chaˆıne de caract`eres . . . 85

11.1.2 Quelques commandes sur les chaˆınes de caract`eres . . . 85

11.2 Gestion des fichiers . . . 88

11.2.1 Type fichier . . . 88

11.2.2 Cr´eation d’un fichier . . . 88

11.2.3 Lecture/´Ecriture . . . 89

11.2.4 Fin de fichier . . . 89

11.2.5 Clˆoture . . . 89

11.3 C 99 . . . 89

(6)
(7)

Liste des Programmes

1 Introduction 11

1 Hello World (hello.c) . . . 13

2 Programme g´en´erique (generique.c) . . . 19

2 Les types 21 3 Tableaux (tableaux.c) . . . 24

4 Structure (structure.c) . . . 24

5 Typedef (typedef.c) . . . 26

3 Les variables et les constantes 27 6 Variables (variables.c) . . . 33

7 Variables – annexe (options.c) . . . 33

4 Les entr´ees-sorties 35 8 Entr´ees/Sorties (io.c) . . . 36

5 Les op´erateurs et les expressions 39 9 Op´erateurs arithm´etiques (arithmetique.c) . . . 40

6 Les structures de contrˆole 45 10 PGCD (pgcd.c) . . . 46 11 Carr´es (carres.c) . . . 47 12 Binaire (binaire.c) . . . 48 13 Parit´e (parite.c) . . . 49 14 Valeur (valeur.c) . . . 51 7 Programme Structur´e 53 15 Incr´ementation (incrementation.c) . . . 55

16 Factorielle (fact.c) . . . 57

17 Fibonacci (fibo.c) . . . 58

18 D´eclaration des types et fonctions (complexe.h) . . . 59

19 D´efinition des fonctions (complexe.c) . . . 60

20 Module principal (complexe-main.c) . . . 60

8 Les pointeurs, les tableaux et les structures 65 21 Auto-Incr´ementation (auto-incrementation.c) . . . 66

22 Suite de Fibonacci – tableau (fibo-tableau.c) . . . 69 5

(8)

9 Les structures dynamiques 71

23 Listes chaˆın´ees (liste.c) . . . 74

10 L’environnement sous UNIX 75 24 Exemple de fichier Makefile (Makefile1) . . . 77

25 Makefile : version compacte (Makefile2) . . . 78

26 Makefile : classique C (Makefile3) . . . 79

27 D´ebordement (segmentation.c) . . . 83

11 Quelques compl´ements 85 28 Palindrome (palindrome.c) . . . 86

29 Tableau vs. Pointeur (tblvsptr.c) . . . 87

30 Tableau vs. Pointeur (tblvsptr1.c) . . . 88

31 Gestion des fichiers (copie.c) . . . 91

(9)

Table des figures

1 Introduction 11

1.1 Organisation d’un ordinateur – Programmation en C . . . 12

1.2 Les ´etapes de la programmation . . . 13

1.3 Raccourcis-clavier sous emacs . . . 14

1.4 Options du compilateur gcc . . . 16

2 Les types 21 2.1 Types entiers sous GCC/Linux . . . 22

2.2 Types flottants sous GCC/Linux . . . 23

3 Les variables et les constantes 27 3.1 D´eclaration des tableaux . . . 29

3.2 D´eclaration des structures . . . 29

4 Les entr´ees-sorties 35 4.1 Affichage des variables avec printf . . . 37

4.2 Saisie avec scanf . . . 38

5 Les op´erateurs et les expressions 39 5.1 Op´erateurs unaires . . . 41

5.2 Op´erateurs binaires . . . 41

5.3 Cast automatique . . . 42

5.4 Op´erateurs abr´eg´es . . . 44

6 Les structures de contrˆole 45 7 Programme Structur´e 53 8 Les pointeurs, les tableaux et les structures 65 8.1 Tableau d’entiers . . . 67

(10)

9 Les structures dynamiques 71 9.1 Liste chaˆın´ee . . . 71 9.2 Liste doublement chaˆın´ee . . . 72 9.3 Arbres binaires . . . 73

10 L’environnement sous UNIX 75

(11)

Avant-Propos

Ce document regroupe l’essentiel pour g´erer un (gros) projet en C sous un environne-ment de type UNIX. Mais avant tout, `a quoi sert un langage de programmation, tel que le langage C, `a l’heure o`u les ordinateurs ob´eissent `a la voix de leur maˆıtre ?

Un ordinateur pr´esente une capacit´e de calcul ´enorme. En effet, les machines actuelles atteignent ou d´epassent all`egrement le milliard d’instructions `a la seconde, permettant ainsi d’effectuer des tˆaches r´ep´etitives ou a priori longues et fastidieuses, ais´ement et rapidement.

Cependant, le langage naturel de l’ordinateur (dit langage machine) est difficilement compr´ehensible par l’homme. D’un autre cˆot´e, le langage naturel de l’homme est souvent ambigu, plein de sous-entendus, et donc difficile `a interpr´eter par une machine. Le langage C, comme tout langage de programmation, est un moyen de communication avec l’ordi-nateur, plus abordable. En effet, un interpr`ete, le compilateur, va se charger de traduire votre programme C (dit fichier source) en langage machine (votre ex´ecutable).

Il ne faut donc pas perdre de vue que votre programme servira `a commander . . .un ordinateur, donc sans imagination ni bonne volont´e. Les ordres devront alors ˆetre clairs, nets et pr´ecis, et surtout sans ambigu¨ıt´e.

Ainsi, certaines r`egles doivent-elles ˆetre respect´ees. Ce document tente de recenser les r`egles essentielles, mais aussi les outils mis `a votre disposition pour vous aider `a mener `a bien un projet important.

Remarque : ce cours ne se pr´etend pas ˆetre un document exhaustif en la mati`ere, mais souhaite apporter, `a un programmeur d´ebutant, les bases de la programmation en C, et plus sp´ecifiquement avec gcc sous Linux. Ainsi, la fonction man est d’une aide pr´ecieuse. En effet, la page 3 du “ man ” contient la description de toutes les fonctions C :

> man 3 printf

donne le prototype de toutes les fonctions li´ees au formattage de sortie.

De plus, ce document ne suit pas le cours magistral, mais tente plutˆot de regrouper sous un mˆeme chapitre les objets de mˆeme type, en se concentrant sur l’essentiel. Aussi, certaines omissions sont volontaires pour ´eviter les confusions, ainsi que l’utilisation d’as-tuces tr`es sp´ecifiques au langage C. En effet, le langage C permet beaucoup de libert´e, en comparaison au Pascal par exemple. Ce document est un peu plus strict, afin de permettre un passage plus ais´e, ult´erieurement, `a un autre langage (tel le langage JAVA).

Pour toute information :

E-mail : Pierre-Alain.Fouque@ens.fr Web : http://www.di.ens.fr/~fouque/

Cours : http://www.di.ens.fr/~fouque/enseignement/ensta/

(12)
(13)

Chapitre 1

Introduction

Sommaire

1.1 L’ordinateur . . . 11 1.2 Programmer en C . . . 12 1.2.1 G´en´eralit´es . . . 12

1.2.2 Un ´editeur de texte : emacs . . . 12

1.2.3 Analyse du programme . . . 15

1.2.3.1 Les fonctions . . . 15

1.2.3.2 Les commentaires . . . 15

1.2.3.3 Le pr´eprocesseur . . . 16

1.2.4 Un compilateur C : gcc . . . 16

1.3 Quelques g´en´eralit´es sur la syntaxe du langage C . . . 17

1.3.1 Mise en page et indentation . . . 17

1.3.2 Les identificateurs . . . 17

1.3.3 Les instructions . . . 17

1.3.4 Organisation d’un programme C . . . 18

Comme nous venons de le voir, un langage de programmation sert de moyen de com-munication avec un ordinateur, qui ne comprend que le langage machine, par le biais d’un compilateur. Nous allons donc, dans un premier temps voir les parties essentielles d’un ordinateur. Ensuite, pour entrer progressivement dans le vif du sujet, nous essaierons un premier petit programme, afin de fixer les diverses ´etapes de l’´edition et de la compilation.

1.1

L’ordinateur

Un ordinateur est constitu´e d’un processeur (CPU, pour Central Processor Unit) reli´e aux diff´erents composants : la m´emoire centrale (ou m´emoire vive) et la m´emoire de masse (disque dur), ainsi que les p´eriph´eriques d’entr´ee-sortie, le clavier et l’´ecran (voir figure 1.1).

La m´emoire de masse sert `a stocker des informations `a long terme (mˆeme lorsque l’ordinateur n’est plus sous tension), tandis que la m´emoire vive stocke les informations

(14)

Mémoire

Disque Dur sauvegarde

variables toto édition liens + compilation saisie exécutable CPU

Mon beau programme en C tapé sur le clavier, affiché à l’écran !... toto.c

toto

Fig. 1.1 – Organisation d’un ordinateur – Programmation en C

n´ecessaires `a la bonne ex´ecution d’une tˆache ponctuelle : le programme (la liste des ins-tructions `a ex´ecuter), les variables, etc. Les informations stock´ees en m´emoire vive seront perdues `a l’extinction de l’ordinateur.

L’utilisateur dialogue avec l’ordinateur par l’interm´ediaire du clavier (entr´ee standard) et de l’´ecran (sortie standard).

1.2

Programmer en C

1.2.1

en´

eralit´

es

L’utilisateur tape son programme en langage C, avec un ´editeur de texte, et sauvegarde le fichier source sur le disque dur. Afin de le rendre compr´ehensible par l’ordinateur, il le compile en langage machine, avec un compilateur C, puis ´edite les liens, produisant ainsi une version ex´ecutable.

Le programme ex´ecutable peut alors ˆetre envoy´e au processeur : l’ex´ecutable est charg´e en m´emoire centrale. Le processeur ex´ecute alors l’ensemble des instructions, utilisant la m´emoire centrale pour stocker ses calculs temporaires.

Pour comprendre toutes ces ´etapes, d´ecrites plus loin plus en d´etail, consid´erons notre premier programme, le classique “ Hello World ! ! ” (voir programme 1). Il faut tout d’abord le saisir au clavier, le compiler (pr´eprocesseur, assembleur puis optimiseur de code), ´editer les liens, puis l’ex´ecuter (voir figure 1.2).

1.2.2

Un ´

editeur de texte : emacs

La premi`ere ´etape consiste `a saisir et `a sauvegarder le programme source hello.c. Pour cela, nous utiliserons l’´editeur de texte bien connu emacs : `a l’invite du shell, on tape

(15)

1.2. PROGRAMMER EN C 13

hello.c

/* Mon premier programme en C */ #include <stdio.h> int main () { printf("Hello World !!\n"); return 0; }

Programme 1: Hello World (hello.c)

tata.c titi.c toto.c fichiers

source

hello.o

hello hello.c

tata.o titi.o toto.o

a.out fichiers objet fichier exécutable Saisie Compilation

Édition des liens

Fig. 1.2 – Les ´etapes de la programmation

> emacs hello.c &

Le “ & ” en fin de ligne permettant de r´ecup´erer la main dans le shell apr`es avoir lanc´e l’´editeur, afin de pouvoir compiler, sans quitter l’´edition en cours, qui sera sans doute encore n´ecessaire pour la correction des erreurs rep´er´ees par le compilateur (ne vous affolez pas, une compilation marche rarement du premier coup !).

Les inconditionnels de vi ou vim, kate, ou eclipse ou de tout autre ´editeur pourront garder leurs habitudes. Cependant, emacs comme d’autres ´editeurs, a de nombreux avan-tages lors de la programmation : il poss`ede un mode C qui “ indente ” au fur et `a mesure de la saisie. Cela clarifie la lecture, mais aussi permet de d´etecter les erreurs classiques que nous verrons plus loin (oubli d’accolades, de parenth`eses, de points-virgules, etc).

De plus, emacs est un ´editeur tr`es puissant et tr`es pratique. Il peut manipuler plusieurs fichiers `a la fois dans diff´erents “ buffers ”, sans lancer plusieurs emacs en parall`ele (voir le menu d´eroulant buffer pour la liste des fichiers ouverts). Enfin, il offre une interface conviviale au d´ebogueur (voir la section 10.3). Les commandes essentielles peuvent ˆetre trouv´ees dans les menus d´eroulants, mais des raccourcis-clavier existent (voir figure 1.3) qui permettent de limiter l’usage de la souris.

(16)

Fichier

Ctrl-x Ctrl-f ouvrir un fichier

Ctrl-x Ctrl-s sauver le fichier sous le nom courant

Ctrl-x Ctrl-w sauver le fichier sous un nouveau nom

Buffer

Ctrl-x Ctrl-b afficher la liste des buffers ouverts

Ctrl-x b changer de buffer courant

Ctrl-x k fermer un buffer

Ctrl-x 2 couper la fenˆetre en 2, verticalement

Ctrl-x 3 couper la fenˆetre en 2, horizontalement

Ctrl-x 1 une seule fenˆetre

Ctrl-x Ctrl-w sauver le fichier sous un nouveau nom

D´eplacement

Ctrl-a d´ebut de ligne

Ctrl-e fin de ligne

D´ebut d´ebut du fichier

Fin fin du fichier

´

Edition

Ctrl-<SPC> marquer un d´ebut de bloc

Ctrl-w couper du d´ebut du bloc jusqu’`a la position actuelle

Alt-w copier du d´ebut du bloc jusqu’`a la position actuelle

Ctrl-y coller le bloc copi´e ou coup´e

Ctrl- annuler la derni`ere commande

(puis les pr´ec´edentes, etc) Divers

Ctrl-g annuler toute commande en cours

tout dialogue dans le mini-buffer Ctrl-x Ctrl-c fermer tous les buffers et quitter

(17)

1.2. PROGRAMMER EN C 15

1.2.3

Analyse du programme

Avant de “ lancer ” la compilation, analysons bri`evement ces quelques lignes. Tout d’abord, hello.c est le nom du fichier source. Un programme est une liste de fonctions.

Le programme en question n’en contient qu’une seule, appel´ee main, en raison de sa

simplicit´e. Mais d`es qu’un programme se complique, il ne faut pas h´esiter `a multiplier les fonctions.

1.2.3.1 Les fonctions

int main() est l’en-tˆete de la fonction, dont le corps est d´ecrit entre les accolades qui suivent. Comme l’indique son nom, la fonction main est la fonction principale, la seule `a ˆetre appel´ee lors de l’ex´ecution du programme. C’est donc `a elle de distribuer les tˆaches, si de multiples tˆaches doivent ˆetre effectu´ees. Il ne s’agit pas pour autant de surcharger le corps de cette fonction. En effet, il est conseill´e d’´ecrire des fonctions sp´ecifiques pour chaque tˆache et sous-tˆache, ces fonctions pouvant alors ˆetre appel´ees les unes par les autres, et par la fonction main en particulier, voire s’appeler elles-mˆemes lors de fonctions dites “ r´ecursives ”. Nous verrons cela plus en d´etail dans le chapitre 7.

Ce programme ´etant tr`es simple, nous n’avons pas multipli´e les fonctions, mais il faut garder `a l’esprit que plus les fonctions seront simples et courtes, plus elles auront de chance d’ˆetre correctes.

L’en-tˆete d’une fonction (ou “ prototype ”) d´ecrit ses caract´eristiques, vues de l’ext´erieur :

– entre parenth`eses, on liste les arguments que la fonction prend en entr´ee, avec leur type. La fonction main ne prend aucun argument, d’o`u les parenth`eses vides “ () ”; – `a la gauche de l’en-tˆete, est pr´ecis´e le type de sortie de la fonction. Pour la fonction main, il s’agit d’un entier retourn´e au shell appelant, correspondant au code d’erreur (0, lorsque tout s’est bien pass´e, une autre valeur signifie une erreur).

Le corps d’une fonction d´ecrit le mode op´eratoire, ce que doit faire la fonction. Pour ce qui est de la fonction main ´etudi´ee, le corps est en effet ´el´ementaire :

– la ligne “ printf("Hello World !!\n"); ” affiche `a l’´ecran la chaˆıne de caract`eres entre guillemets. Le \n correspond `a un saut de ligne.

– finalement, la ligne “ return 0; ” conclut la fonction, retournant l’entier de sortie de la fonction, le code d’erreur 0 signifiant que tout s’est bien pass´e.

1.2.3.2 Les commentaires

Un programme ´ecrit un jour sera peut-ˆetre relu ou utilis´e ensuite par quelqu’un d’autre, ou par vous-mˆeme dans quelques ann´ees. Sans commentaires sur le pourquoi et le comment de ceci et de cela, la lecture sera ardue. Ainsi est-il conseill´e d’ajouter des commentaires dans vos programmes. Ils ne surchargeront pas l’ex´ecutable ni ne ralentiront son ex´ecution : les commentaires sont supprim´es `a la compilation.

La ligne “ /* Mon premier programme en C */ ”, comme tout texte entre /* et */ est un commentaire.

(18)

1.2.3.3 Le pr´eprocesseur

La ligne “ #include <stdio.h> ” est interpr´et´ee par le pr´eprocesseur. Il ins`ere alors le fichier stdio.h `a cet emplacement avant d’envoyer le programme au compilateur.

Ce fichier contient les en-tˆetes des fonctions usuelles pour les entr´ees-sorties (STanDard Input-Output), telle que printf.

De nombreuses directives peuvent ˆetre ainsi donn´ees au pr´eprocesseur, telles que des insertions conditionnelles, des macros, etc. Toutes ces directives apparaissent imp´ erative-ment en d´ebut de ligne (donc une seule par ligne), en commen¸cant par un #.

1.2.4

Un compilateur C : gcc

Afin de traduire le programme C en langage machine, on fait appel `a un compilateur. Nous utiliserons gcc (pour GNU C Compiler). Un tel compilateur effectue en fait plusieurs tˆaches successives :

– le pr´eprocesseur, qui, comme on l’a d´ej`a vu ci-dessus, interpr`ete quelques commandes ´el´ementaires pour compl´eter et mettre en forme le fichier source ;

– le compilateur, en tant que tel, qui traduit le fichier source en code assembleur, un langage tr`es proche du langage machine ;

– l’optimiseur de code, qui remplace certaines s´equences d’instructions par d’autres plus efficaces, d´eroule certaines boucles, supprime certains sauts, etc. L’optimisation est tr`es sp´ecifique aux caract´eristiques du processeur ;

– l’assembleur, qui traduit le code assembleur en langage machine. On obtient alors le fichier objet ;

– l’´editeur de liens, qui interface les diff´erents fichiers objets entre eux, mais ´egalement avec les biblioth`eques usuelles fournies avec la distribution classique du C.

En g´en´eral, toutes ces op´erations sont effectu´ees en une seule ´etape, transparente pour l’utilisateur (avec gcc hello.c). On obtient alors un ex´ecutable d´enomm´e a.out, que l’on peut ex´ecuter depuis le shell :

> gcc hello.c > a.out

-E lance le pr´eprocesseur (mais n’effectue aucune compilation)

> gcc -E hello.c retourne le r´esultat sur la sortie standard

-S cr´eation du fichier assembleur (avant l’´edition des liens)

> gcc -S hello.c produit hello.s

-c cr´eation du module objet (avant l’´edition des liens)

> gcc -c hello.c produit hello.o

-O2/-O3 optimisation du code

-o <output> permet de sp´ecifier le nom du fichier cr´e´e

-v mode verbose qui explique tout ce qu’il fait

-Wall compilation “ exigeante ”, informant des erreurs b´enignes

Fig. 1.4 – Options du compilateur gcc

Diverses options peuvent ˆetre utilis´ees lors de la compilation (voir figure 1.4), notam-ment pour contrˆoler les phases de la compilation que l’on veut effectuer. Les plus utiles

(19)

1.3. QUELQUES G ´EN ´ERALIT ´ES SUR LA SYNTAXE DU LANGAGE C 17

´etant “ -c ” lors d’un projet faisant intervenir plusieurs modules qui n´ecessitent des com-pilations s´epar´ees, et “ -o ” qui permet de pr´eciser le nom du fichier ex´ecutable (d´enomm´e par d´efaut a.out). L’option “ -Wall ” est ´egalement tr`es utile car elle demande au compi-lateur d’informer l’utilisateur de toute anomalie dans le source. Il s’agit souvent d’erreurs d’inadvertences, non fatales `a la compilation, mais qui rendent l’ex´ecution parfois incor-recte.

1.3

Quelques g´

en´

eralit´

es sur la syntaxe du langage C

1.3.1

Mise en page et indentation

Un programme C peut ˆetre ´ecrit tr`es librement, `a l’exception des directives envoy´ees au pr´eprocesseur qui commencent n´ecessairement par un # et en d´ebut de ligne (et donc une seule directive par ligne). `A part cela, les sauts de lignes et les espaces multiples ne sont pas significatifs pour le compilateur.

Reste maintenant `a ´ecrire un programme qui aide `a la compr´ehension, et notamment au d´eboguage. Pour cela, l’´editeur de texte emacs est d’un pr´ecieux recours. En effet, il aide `a indenter correctement (et peut mˆeme colorer les diff´erentes mots selon leur carac-t´eristique). Si cela n’est pas automatique, taper

Alt-x c-mode (pour passer dans un environnement C)

Alt-x global-font-lock-mode (pour passer en mode color´e)

Il est alors fortement conseill´e de respecter les r`egles d’indentation : d´ecaler d’un cran (ex : trois espaces) vers la droite tout bloc inclus dans un pr´ec´edent. On peut ainsi mieux rep´erer qui d´epend de quoi, et si tous les blocs ouverts ont bien ´et´e ferm´es.

1.3.2

Les identificateurs

Les noms de variables, de constantes ou de fonctions sont compos´es de caract`eres au choix parmi les lettres a-z et A-Z, et les chiffres 0-9, avec la possibilit´e d’utiliser le symbole _ (par exemple, pour remplacer l’espace).

Cependant, ces noms ne peuvent pas commencer par un chiffre. De plus, les minus-cules/majuscules sont diff´erenci´ees par la plupart des compilateurs.

1.3.3

Les instructions

Les instructions peuvent ˆetre de deux types :

– les instructions simples, toujours termin´ees par un “ ; ”, tel que printf("Hello World !!\n");

– les instructions compos´ees, qui sont des listes d’instructions simples encadr´ees par des accolades, tel que

{

printf("Hello World !!\n"); printf("Bonjour !!\n"); }

Remarque : toutes les instructions simples se terminent par un point-virgule. Son oubli est l’erreur la plus courante !

(20)

1.3.4

Organisation d’un programme C

Un programme C est alors un assemblage de fonctions, elles-mˆemes listes de blocs

d’instructions. Ainsi, un programme C aura toujours l’aspect pr´esent´e sur le programme 2. C’est-`a-dire, outre les commentaires et les directives pour le pr´eprocesseur qui peuvent ˆ

etre ins´er´es `a tout moment, on commence par d´eclarer les variables globales (qui devront ˆ

etre connues par tous les ´el´ements du programme). Ensuite, on d´efinit toutes les fonctions, en particulier la fonction main.

Chaque fonction est d´efinie par son en-tˆete, puis un corps. Le corps d’une fonction commence, comme le programme, par d´eclarer toutes les variables n´ecessaires `a la fonction, qui ne seront connues qu’`a l’int´erieur de la fonction (variables locales). On initialise ensuite ces variables, puis on liste les instructions que la fonction doit effectuer.

La fonction main, avec l’en-tˆete int main (int argc, char *argv[]) sera plus cou-rante que le version abr´eg´ee du programme 1. En effet, elle permet de saisir des valeurs

sur la ligne de commande au moment de l’ex´ecution du programme :

> gcc prog.c -o prog > prog 14 25

Ainsi, les chaˆınes de caract`eres "prog", "14" et "25" sont plac´ees dans le tableau argv, dans les cases de 0 `a la valeur de argc − 1. Tout ceci ´etant effectu´e par le shell, vous disposez donc de ces variables pr´e-remplies.

Ensuite, il suffit de placer le "14" (contenu dans argv[1]) en tant qu’entier (la conver-sion s’effectue avec la commande atoi, pour “ ASCII to Integer ”) dans la variable a. On fait de mˆeme avec le "25" dans la variable b.

Enfin, on appelle la fonction ma_fonction sur ces variables. Grˆace `a ce petit pro-gramme, il est tr`es facile de se familiariser avec les notions de base du langage C.

Nous allons pouvoir maintenant rentrer un peu plus dans les d´etails, en voyant no-tamment les diff´erents types que le langage C sait manipuler, puis ensuite les commandes simples et structur´ees qui sont `a votre disposition pour ´elaborer un programme capable de faire des calculs laborieux `a notre place.

(21)

1.3. QUELQUES G ´EN ´ERALIT ´ES SUR LA SYNTAXE DU LANGAGE C 19

generique.c

/* Commentaires `a tout endroit */

/* Directives pour le pr´eprocesseur

en-t^ete de fichier, mais ´egalement `a tout endroit */

#include <stdlib.h> #include <stdio.h>

/* D´eclaration des variables globales */

int ma_variable;

/* Des fonctions avec en-t^ete et corps */

/* en-t^ete de la fonction */

int ma_fonction(int x, int y)

/* corps de la fonction */

{

/* D´eclaration des variables locales `a la fonction */

int z;

/* Liste d’instructions */

z = x + y;

/* Renvoi de la valeur de retour de la fonction */

return z; } float ma_deuxieme_fonction() { float x=0; /* ... */ return x; }

/* La fonction obligatoire: main */

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

/* D´eclaration des variables locales `a la fonction */

int a,b,c;

/* Initialisation des variables */

a = atoi(argv[1]); b = atoi(argv[2]); c = ma_fonction(a,b); printf("%d + %d = %d \n",a,b,c); return 0; }

(22)
(23)

Chapitre 2

Les types

Sommaire

2.1 Les types . . . 21 2.2 Les types de base . . . 22 2.2.1 Les types entiers (int, short int, long int et long long int) 22 2.2.2 Les types flottants (float, double et long double) . . . 22 2.2.3 Le type caract`ere (char) . . . 23 2.3 Les types structur´es . . . 23 2.3.1 Les tableaux . . . 23 2.3.2 Les tableaux `a plusieurs dimensions . . . 24 2.3.3 Les structures . . . 24 2.4 Les pointeurs . . . 24 2.5 Nouveaux types . . . 25

Nous avons d´ej`a aper¸cu le type int dans le programme 1, et entre-aper¸cu le type float et les tableaux dans le programme 2, mais le langage C connaˆıt de nombreux autres types tr`es utiles. Les plus simples ´etant les entiers, les r´eels et les caract`eres. Le langage C permet ´egalement de manipuler des types structur´es, tels que les tableaux (ensembles d’objets de mˆeme type) ou les structures (ensembles d’objets de types divers).

2.1

Les types

Un ordinateur stocke toutes les donn´ees sous le mˆeme format, une s´erie de bits, dans des octets (blocs de 8 bits) localis´es par une adresse m´emoire. Ainsi, un entier, une lettre ou un r´eel doivent-ils subir un codage sp´ecifique avant d’ˆetre stock´es.

De plus, connaˆıtre les bits contenus dans un octet `a une adresse donn´ee ne suffit pas `

a connaˆıtre la valeur “ r´eellement ” stock´ee. En effet, cette valeur d´ependra du type de l’objet que l’on a stock´e : par exemple, le caract`ere ’A’ et l’entier 65 sont tous deux cod´es de la mˆeme mani`ere, le type de l’objet permet de d´eterminer le codage et donc le contenu r´eel.

Le langage C sait coder un certain nombre de types usuels, nous allons les ´etudier dans ce chapitre.

(24)

2.2

Les types de base

Commen¸cons donc par les types les plus simples et les plus utiles, `a savoir les entiers, les flottants et les caract`eres.

2.2.1

Les types entiers (int, short int, long int et long long

int)

Les entiers sont cod´es `a l’aide de la repr´esentation des nombres entiers relatifs : un bit est r´eserv´e pour coder le signe, les autres bits codent la valeur absolue du nombre. Le langage C peut g´erer plusieurs tailles diff´erentes d’entiers :

– short int ou simplement short – long int ou simplement long

– long long int ou simplement long long – int (l’entier par d´efaut)

Cependant, ces tailles ne sont pas standardis´ees, seuls des seuils minimums sont impo-s´es. C’est-`a-dire que ces tailles d´ependent de la machine, du syst`eme d’exploitation et du compilateur. Avec gcc sous Linux sur un PC, le type short code des entiers sur 16 bits, tandis que les types int et long codent des entiers sur 32 bits et enfin le type long long code des entiers sur 64 bits. Ces tailles peuvent ˆetre trouv´ees dans le fichier limits.h, ou obtenues par l’interm´ediaire de l’instruction C sizeof(<type>).

`

A titre indicatif, avec 16 bits, on peut repr´esenter des entiers entre -32 768 et 32 767, avec 32 bits, on couvre les valeurs de -2 147 483 648 `a 2 147 483 647, puis avec 64 bits, les valeurs s’´etendent de -9 223 372 036 854 775 808 `a 9 223 372 036 854 775 807.

Remarque : ces trois types admettent le qualificatif unsigned. Dans ce cas, il n’y a

plus de bit pour repr´esenter le signe, et seuls les nombres positifs sont cod´es. On gagne alors un bit : avec 16 bits, on peut repr´esenter des entiers non-sign´es entre 0 et 65 535, avec 32 bits, on couvre les valeurs de 0 `a 4 294 967 295, puis sur 64 bits, les valeurs s’´etendent de 0 `a 18 446 744 073 709 551 615.

Cependant, l’emploi de ce qualificatif doit ˆetre limit´e `a des situations particuli`eres.

Type Espace short [-32 768, 32 767] int/long [-2 147 483 648, 2 147 483 647] long long [-9 223 372 036 854 775 808, 9 223 372 036 854 775 807] unsigned short [0, 65 535] unsigned int/long [0, 4 294 967 295]

unsigned long long [0, 18 446 744 073 709 551 615]

Fig. 2.1 – Types entiers sous GCC/Linux

2.2.2

Les types flottants (float, double et long double)

Les types flottants codent les nombres r´eels de mani`ere approch´ee avec la notation “ scientifique ”, une mantisse et l’exposant en base 2 (ex. 234 × 245).

(25)

2.3. LES TYPES STRUCTUR ´ES 23

Le C propose trois tailles pour repr´esenter ces flottants, avec une mantisse et un exposant de tailles variables :

– float

– double, le flottant en double pr´ecision

– long double, un type r´ecent qui propose une pr´ecision quadruple.

Comme pour les entiers, les tailles et pr´ecisions des flottants ne sont pas standardis´ees, mais peuvent ˆetre trouv´ees dans le fichier float.h. Avec gcc sous Linux sur un PC, nous avons :

– pour les float, une mantisse sur 24 bits et un exposant sur 8 bits, proposant une pr´ecision de l’ordre de 10−7;

– pour les double, une mantisse sur 53 bits et un exposant sur 11 bits, proposant une pr´ecision de l’ordre de 2 × 10−16;

– pour les long double, une mantisse sur 64 bits et un exposant sur 16 bits, proposant une pr´ecision de l’ordre de 10−19.

Type Mantisse Pr´ecision Min Max

float 24 10−7 10−38 3 · 1038

double 53 2 · 10−16 2 · 10−308 10308

long double 64 10−19 10−4931 104932

Fig. 2.2 – Types flottants sous GCC/Linux

2.2.3

Le type caract`

ere (char)

Les caract`eres sont essentiels, notamment pour ´ecrire du texte, manipuler des lettres, etc. En C, ils sont repr´esent´es comme des entiers, sur un octet (entre 0 et 255) en utilisant la table de conversion ASCII. Cependant, cette table de conversion est transparente pour l’utilisateur, en notant le caract`ere entre apostrophes “ ’ ’ ”. Ainsi, la notation ’A’ d´esignera le caract`ere “ A ”.

2.3

Les types structur´

es

Un type semble manquer dans la liste ci-dessus, il s’agit des chaˆınes de caract`eres, c’est-`a-dire les mots ou les phrases. En fait, elles sont repr´esent´ees comme des tableaux de caract`eres. De nombreuses commandes standard permettent de manipuler ces tableaux particuliers de caract`eres (voir la section 11.1).

2.3.1

Les tableaux

Les tableaux permettent de stocker une grande quantit´e d’objets de mˆeme type. Ainsi, les instructions du programme 3 d´eclarent des tableaux de 10 entiers, de 10 flottants ou de 10 caract`eres (chaˆıne de caract`eres). Les cases se d´enommeront alors tab_i[0] jusqu’`a tab_i[9] (pour le tableau d’entiers).

(26)

tableaux.c

int tab_i[10]; float tab_f[10]; char tab_c[10];

Programme 3: Tableaux (tableaux.c)

2.3.2

Les tableaux `

a plusieurs dimensions

Il est possible de d´efinir des tableaux `a plusieurs dimensions. Il s’agit en fait d’un tableau de tableaux :

int tab[10][5];

est un tableau de 10 tableaux de 5 entiers chacuns. Ainsi, tab[0] d´esigne le premier tableau, et tab[0][0] la premi`ere case de ce premier tableau.

2.3.3

Les structures

Les structures, quant `a elles, permettent de stocker plusieurs objets de types divers. On d´efinit une structure comme pr´esent´e dans le programme 4.

structure.c

struct ma_structure { int nombre;

float valeur; };

Programme 4: Structure (structure.c)

Le type struct ma_structure regroupe alors deux champs, un entier et un flottant. Un objet st de type struct ma_structure contient ces deux valeurs dans ses deux

champs d´enomm´es st.nombre et st.valeur.

L’exemple d’une structure pour manipuler des complexes est donn´e dans la section 7.3.

2.4

Les pointeurs

Ce type un peu particulier pourrait ´egalement ˆetre class´e dans les types de base, mais les pointeurs ne semblent sans doute pas naturels, ni essentiels, au premier coup d’œil, et

(27)

2.5. NOUVEAUX TYPES 25

pourtant nous y consacrerons tout un chapitre (voir chapitre 8).

En effet, comme nous l’avons vu pr´ec´edemment, tout objet est stock´e en m´emoire. Son contenu est donc caract´eris´e par l’adresse m´emoire de ce stockage et du type de l’objet. Un pointeur contient cette adresse. Sa taille est donc la taille n´ecessaire pour coder une adresse m´emoire (en g´en´eral 32 bits). Un pointeur est de plus, en g´en´eral, associ´e `a un type d’objet, pour pouvoir manipuler l’objet correctement (ce que l’on verra plus loin). Ainsi, un pointeur sur un objet obj de type int contient l’adresse o`u est stock´e l’objet obj. Son type est not´e “ int * ”.

2.5

Nouveaux types

Les tableaux ou les structures permettent de faire des tableaux de tableaux de struc-tures de tableaux, etc. On obtient alors des types avec des noms “ `a dormir dehors ”! ! La

commande typedef permet de d´efinir des synonymes pour des noms de types. Ainsi,

par exemple, la structure d´efinie ci-dessus est de type struct ma_structure. Si on

veut d´efinir un tableau de taille 20 d’une telle structure, son type sera alors struct ma_structure[20], etc. On peut alors simplifier ce nom final, s’il doit ˆetre beaucoup utilis´e. Par exemple, dans le programme 5, on renomme le nouveau type de tableau de 20 structures en tabs. Puis, un tel tableau d´enomm´e T est ais´ement d´eclar´e.

On peut aussi souhaiter aussitˆot renommer le nouveau type r´esultant de l’instruction

struct new_structure. Le programme 5 d´efinit ce nouveau type sous le nom point2D.

On peut mˆeme se passer du nom temporaire, comme le montre la d´efinition du type

(28)

typedef.c

typedef struct new_structure { float abscisse; float ordonnee; } point2D; typedef struct { float abscisse; float ordonnee; float hauteur; } point3D; struct ma_structure { int nombre; float valeur; };

typedef struct ma_structure[20] tabs; point2D p2;

point3D p3; tabs T;

(29)

Chapitre 3

Les variables et les constantes

Sommaire

3.1 D´eclaration des variables . . . 27 3.1.1 D´eclaration des types simples . . . 28 3.1.2 D´eclaration des tableaux et pointeurs . . . 28 3.1.3 D´eclaration des objets complexes . . . 29 3.2 Initialisation des variables . . . 30 3.3 Constantes . . . 30 3.3.1 Types simples . . . 30 3.3.1.1 Constantes de type entier . . . 30 3.3.1.2 Constantes de type flottant . . . 30 3.3.1.3 Constantes de type caract`ere . . . 31 3.3.2 Types complexes . . . 31 3.4 Dur´ee de vie et visibilit´e des variables . . . 31

Un programme informatique sert `a travailler sur des valeurs, tel que faire des calculs sur des entiers ou des flottants. Ces valeurs doivent alors ˆetre stock´ees en m´emoire. On utilise alors des variables si elles doivent varier. En revanche, ces variables sont en g´en´eral initialis´ees par des valeurs constantes.

Les variables doivent ˆetre d´eclar´ees, pour sp´ecifier le type de la variable en question. Cette d´eclaration attribut de plus un emplacement m´emoire `a la variable, qui lui est r´eserv´e pendant toute sa dur´ee de vie, d´esign´e par le pointeur de la variable. Il faut ensuite initialiser la variable. En effet, lors de la d´eclaration, un emplacement m´emoire est attribu´e `a la variable, sans toucher au contenu, qui peut donc valoir n’importe quoi. Pour cela, nous aurons alors `a faire aux constantes, dont la syntaxe est sp´ecifique au type.

3.1

eclaration des variables

La d´eclaration d’une variable consiste donc, dans un premier temps, `a pr´eciser au compilateur le type de la variable que l’on va utiliser, et donc le mode de codage qu’il va devoir effectuer pour le stockage. Ensuite, en fonction du type de la variable, il va r´eserver une place m´emoire plus ou moins importante (selon qu’il s’agit d’un short ou d’un long).

(30)

3.1.1

eclaration des types simples

Ces d´eclarations s’effectuent simplement en donnant le type de la variable suivi du nom de la variable en question :

int i; float x; double y; char c;

Nous avons alors d´eclar´e une variable enti`ere de type int d´enomm´ee i, ainsi que deux variables flottantes, une de type float d´enomm´ee x et une de type double d´enomm´ee y, et enfin une variable de type char d´enomm´ee c.

Lorsque l’on souhaite d´eclarer plusieurs variables du mˆeme type, on peut regrouper la d´eclaration sur une seule ligne :

int i,j,k; float x,y;

3.1.2

eclaration des tableaux et pointeurs

Formellement, les tableaux et les pointeurs ne sont pas identiques, mais nous n’insiste-rons pas sur les diff´erences. Pour un tableau ou un pointeur, la d´eclaration est alors aussi simple, sachant que la taille du tableau doit ˆetre une constante, et non une variable :

float *pfloat; int tab[10]; char st[];

Ainsi, nous venons de d´eclarer un pointeur pfloat sur un float, ainsi qu’un tableau tab de 10 entiers. Ces deux d´eclarations ont du mˆeme coup r´eserv´e l’espace m´emoire n´ecessaire pour stocker le pointeur pfloat ainsi que le tableau tab et ses dix cases.

En revanche, la d´eclaration du tableau de caract`eres st n’a pas r´eserv´e de m´emoire pour ses cases, puisque la longueur est inconnue. Seule la zone m´emoire pour stocker l’adresse du futur tableau est r´eserv´ee, ainsi st n’est rien d’autre qu’un pointeur, qui ne pointe sur rien. Lorsque la zone m´emoire aura ´et´e r´eserv´ee (grˆace `a la commande malloc que nous ´etudierons dans le chapitre 8 d´edi´e aux pointeurs), nous pourrons alors d´efinir cette valeur. Cette m´ethode est la seule pour manipuler des tableaux dont la taille n’est pas une constante connue au moment de la compilation.

En revanche, tab est un pointeur de type int qui pointe sur le d´ebut de l’espace

m´emoire r´eserv´e pour les 10 cases du tableau (voir la figure 3.1). La premi`ere case du tableau est donc `a cette adresse, la deuxi`eme case, `a cette adresse incr´ement´ee de la taille d’un entier (ce que l’on connaˆıt, puisque le pointeur est typ´e en tant que pointeur sur un int), etc.

(31)

3.1. D ´ECLARATION DES VARIABLES 29 t t[0] t[1] t[2] t[3] t int t[4];

?

int t[]; = int *t;

Fig. 3.1 – D´eclaration des tableaux

3.1.3

eclaration des objets complexes

Finalement, pour tout type, tel que le type “ tableau de structures ” tabs d´efini `a la fin du chapitre pr´ec´edent, on d´eclare une variable comme la variable T du programme 5. La taille d’un tel objet ´etant bien d´efinie, un tableau de 20 cases contenant chacune un entier et un flottant, la m´emoire est ´egalement r´eserv´ee. Ainsi T est un pointeur vers une zone m´emoire qui contient 20 cases cons´ecutives d’objets de type struct ma_structure.

En revanche, consid´erons le type et la d´eclaration suivante :

typedef struct { int length; int value[]; } bigInteger; bigInteger bI;

La variable bI est bien d´eclar´ee comme ´etant de type bigInteger. Elle contient donc un champ de type entier, bI.length, et un champ de type tableau d’entiers, sans longueur. Pour ce dernier, il s’agit donc d’un pointeur sans destination pr´ecise (voir la figure 3.2). Il faudra donc l’initialiser ult´erieurement, lorsqu’un espace m´emoire aura ´et´e r´eserv´e (grˆace `

a la commande malloc que nous verrons plus loin dans le chapitre 8 d´edi´e aux pointeurs).

bI.length bI.value bigInteger bI;

?

entier pointeur

(32)

3.2

Initialisation des variables

La d´eclaration des variables se contente de signaler le type de la variable et de r´eserver, le cas ´ech´eant, de la m´emoire. Dans ce dernier cas, la r´eservation de m´emoire ne modifie pas son contenu pr´ec´edent. Ainsi, la variable prend la valeur associ´ee au contenu de la m´emoire : ¸ca peut ˆetre n’importe quoi. Il faut donc toujours initialiser une variable avant de l’utiliser. Ainsi,

int i; i = 0;

d´eclare une variable enti`ere i, puis l’initialise `a 0. La d´eclaration et l’initialisation peuvent ˆ

etre faites en une seule ´etape au lieu de deux :

int i = 0;

En fait, l’initialisation consiste `a affecter une valeur constante `a la variable. La syntaxe des constantes est d´ecrite dans la section suivante.

3.3

Constantes

3.3.1

Types simples

Les constantes pour les types simples ont une syntaxe particuli`ere, ´etant donn´e qu’il existe plusieurs types d’entiers et de flottants, puis qu’il existe ´egalement plusieurs nota-tions.

3.3.1.1 Constantes de type entier

Les entiers sont construits `a partir des chiffres (et des lettres pour une notation en hexad´ecimale). On ajoute alors ´eventuellement un suffixe “ l ” ou “ L ” pour d´esigner une constante de type long et/ou le suffixe “ u ” ou “ U ” pour d´esigner le qualificatif unsigned. Aucun pr´efixe signale que le nombre est exprim´e en base 10, tandis que les pr´efixes 0 et 0x pr´ecisent respectivement une notation en octale ou en hexad´ecimale.

Ainsi, 0377 d´esigne l’entier 255, 0xF d´esigne l’entier 15. En revanche, 120L d´esigne l’entier 120 de type long.

3.3.1.2 Constantes de type flottant

Les flottants peuvent bien sˆur ˆetre d´esign´es par des nombres `a virgule (enfin, avec un point “ . ”!). On ajoute ´eventuellement un suffixe “ f ” ou “ F ” pour d´esigner une constante de type float ou le suffixe “ l ” ou “ L ” pour d´esigner le type long double. On peut ´egalement utiliser la notation scientifique 123E+3 ou -142E-4.

(33)

3.4. DUR ´EE DE VIE ET VISIBILIT ´E DES VARIABLES 31

3.3.1.3 Constantes de type caract`ere

Les caract`eres sont simplement d´esign´es entre apostrophes. Ainsi, la constante ’a’ d´esigne le caract`ere a minuscule. On peut ´egalement noter ces lettres par leur code ASCII en utilisant les notations octales ou hexad´ecimales, pr´ec´ed´ees d’un backslash. Ceci permet de noter les caract`eres non affichables. Certains caract`eres admettent des abbr´eviations :

’\101’ et ’\x41’ d´esignent le caract`ere A, de code ASCII 65, (´egalement ’A’) ’\0’ et ’\x0’ d´esignent le caract`ere nul

(d´elimite la fin des chaˆınes de caract`eres) ’\12’ et ’\xA’ d´esignent le saut de ligne (´egalement ’\n’) ’\13’ et ’\xB’ d´esignent le retour chariot (´egalement ’\r’)

3.3.2

Types complexes

Pour les types complexes (tableaux et structures), on initialise chaque case ou champ ind´ependamment, un par un. On peut ´egalement en initialiser plusieurs `a la fois :

int inttab[5] tableau de 5 entiers contenant les

= { 2, 5, -2, 0, 10 }; valeurs 2, 5, -2, 0 et 10

float floattab[4] tableau de 4 flottants contenant les

= { 2.0, 5e-3, -2e10, 10.04 }; valeurs 2.0, 5 × 10−3, −2 × 1010 et 10.04

char mot[5] = "essai"; tableau de 5 caract`eres ’e’, ’s’, ’s’, ’a’, ’i’

int tab[10] tableau de 10 entiers dont les 4 premi`eres

= { 2, 5, -2, 10 }; cases sont initialis´ees `a 2, 5, -2 et 10

char *mot = "essai"; pointeur sur un caract`ere,

initialis´e `a l’adresse de la chaˆıne "essai" char chaine[10] = "mot"; tableau de 10 caract`eres, les premi`eres cases

sont initialis´ees `a ’m’, ’o’, ’t’ et ’\0’

struct carte { d´efinition du type struct carte

char[] nom; d´eclaration d’une variable prem

int age; initialisation avec prem.nom="durand"

} prem = { "durand", 10 }; et prem.age=10

3.4

Dur´

ee de vie et visibilit´

e des variables

Les variables ont une dur´ee de vie plus ou moins longue, ainsi qu’une visibilit´e variable. Voir les programmes 6 et 7 pour un exemple d’application. Les fichiers variables.c et options.c sont deux modules de compilation diff´erents, le fichier variables.c ´etant l’unit´e principale, puisqu’elle contient la fonction main. On les compile d’un seul coup de la fa¸con suivante :

>gcc options.c variables.c -o variables >variables 4

(34)

– globale — les variables d´efinies en dehors de toute fonction sont dites globales. Elles sont vues/accessibles par toutes les fonctions (au moins du module). Elles ont une dur´ee de vie ´egale au temps d’ex´ecution du programme. Telles les variables b et c d´efinies en tˆete du fichier variables.c.

– locale — les variables d´efinies dans une fonction ou dans un bloc sont a priori visibles et existantes dans le seul bloc en question. Telles les variables b et d d´eclar´ees en tˆete de la fonction main. Elles n’existeront que dans cette fonction. Si une telle variable a un nom identique `a une variable globale, la variable globale ne sera pas visible ni accessible dans cette zone, mais seule la variable locale. Telle la variable locale b d´efinie en tˆete de la fonction main qui “ masque ” la variable globale du

mˆeme nom.

– extern — il s’agit d’un qualificatif qui permet d’utiliser dans une unit´e de com-pilation une variable ou un type d´efinis dans un autre module. Ainsi, la variable a d´efinie dans l’unit´e options.c est annonc´ee comme utile dans l’unit´e principale variables.c.

– static — il s’agit d’un qualificatif qui modifie la visibilit´e de la variable. Une variable globale static ne pourra pas ˆetre utilis´ee par une autre unit´e de compilation (voir le qualificatif extern). Une variable locale stactic aura une dur´ee de vie ´egale `

a l’ex´ecution du programme mais ne sera visible que dans le bloc (ou la fonction) dans lequel elle a ´et´e d´efinie.

– register — ce qualificatif informe le compilateur que la variable sera tr`es utilis´ee, et lui demande de la mettre, si possible, dans un registre du processeur.

Ces deux derniers qualificatifs sont d’un usage limit´e. Notamment l’utilisation des re-gistres. En effet, le nombre de registres est tr`es faible, et il vaut mieux faire confiance au compilateur, et notamment `a l’optimiseur de code, pour les optimisations de ce genre.

(35)

3.4. DUR ´EE DE VIE ET VISIBILIT ´E DES VARIABLES 33 variables.c #include <stdlib.h> #include <stdio.h> extern int a; int b = 0; int c;

int main (int argc, char *argv[]) { int b; int d; b = atoi(argv[1]); c = a+b; d = a*b; printf("%d + %d = %d \n",a,b,c); printf("%d * %d = %d \n",a,b,d); return 0; }

Programme 6: Variables (variables.c)

options.c

int a=10;

(36)
(37)

Chapitre 4

Les entr´

ees-sorties

Sommaire

4.1 L’affichage avec printf . . . 35 4.1.1 Simple affichage . . . 35 4.1.2 Formattage des sorties . . . 36 4.2 La saisie avec scanf . . . 37

On a vu comment passer des arguments par l’interm´ediaire de la ligne de commande. Ils se trouvent stock´es dans le tableau argv[] de longueur argc, les arguments de la

fonction main : int main(int argc, char *argv[]). Il est ´egalement possible que le

programme pose des questions `a l’utilisateur et lise les donn´ees entr´ees au clavier. Ceci est effectu´e avec la fonction scanf. Nous d´ecrirons donc son usage. Cependant, elle est moins utile que la fonction printf qui permet d’´ecrire des donn´ees `a l’´ecran.

Le programme 8 pr´esente un exemple d’utilisation des fonctions printf et scanf, dont l’ex´ecution donne l’´ecran suivant :

>gcc io.c -o io >io

Entrer deux entiers : 12 76

Entrer deux flottants : 3.54 9.234

12 * 76 = 912

3.54 + 9.23 = 12.77

4.1

L’affichage avec printf

4.1.1

Simple affichage

La fonction printf sert `a afficher des donn´ees `a l’´ecran. Les chaˆınes de caract`eres constantes s’affichent telles que, mais les autres constantes et les variables doivent ˆetre int´egr´ees de fa¸con particuli`ere, sp´ecifique au type et au format d’affichage.

(38)

io.c #include <stdio.h> int main () { int a,b,c; float x,y,z;

printf("Entrer deux entiers : "); scanf("%d %d",&a,&b);

printf("Entrer deux flottants : "); scanf("%f %f",&x,&y); c = a*b; z = x+y; printf("%5d * %5d = %5d \n",a,b,c); printf("%5.2f + %5.2f = %5.2f \n",x,y,z); return 0; }

Programme 8: Entr´ees/Sorties (io.c)

Ainsi, printf("Affichage"); ´ecrit le mot Affichage `a l’´ecran. Pour afficher le contenu d’une variable enti`ere, on sp´ecifie %d (voir le programme 2) pour pr´eciser qu’il s’agit d’un type entier, puis on pr´ecise le nom de la variable `a ins´erer en fin :

printf("La variable i vaut %d",i);

Si on veut afficher la variable en octal ou en hexad´ecimal, on utilise %o et %x respective-ment. Pour les flottants, on utilise %f ou %e selon que l’on souhaite un affichage standard ou en notation exponentielle. Une liste plus compl`ete peut ˆetre trouv´ee figure 4.1 pour afficher les entiers, les flottants et les chaˆınes de caract`eres.

La fonction printf retourne un entier qui peut ˆetre r´ecup´er´e ou non. Cet entier vaut le nombre de caract`eres affich´es (sans le caract`ere de fin de chaˆıne de caract`eres).

4.1.2

Formattage des sorties

Un formattage plus complexe est possible avec cette commande, notamment pour pr´eciser le nombre d’espaces que l’on pr´evoit pour l’affichage d’un entier, pour former des colonnes :

printf("%4d et %5d",i,j);

affiche les variables enti`eres i et j en ins´erant, devant, des espaces de fa¸con `a ce que les espaces plus l’affichage du i (resp. du j) prennent 4 caract`eres (resp. 5 caract`eres).

(39)

4.2. LA SAISIE AVEC SCANF 37

Type et Variable Affichage Format

short i; int j; long k; printf("%hd %d %ld",i,j,k); d´ecimal

short i; int j; long k; printf("%ho %o %lo",i,j,k); octal

short i; int j; long k; printf("%hx %x %lx",i,j,k); hexad´ecimal

float x; double y; printf("%f %lf",x,y); d´ecimal (avec point)

float x; double y; printf("%e %le",x,y); exponentiel

float x; double y; printf("%g %lg",x,y); le plus court des deux

long double z; printf("%Lf",z); d´ecimal (avec point)

long double z; printf("%Le",z); exponentiel

long double z; printf("%Lg",z); le plus court des deux

char c; printf("%c",c); caract`ere

char m[10]; printf("%s",m); chaˆıne de caract`eres

Fig. 4.1 – Affichage des variables avec printf

3 et 9

12 et 235

2353 et 4532

Pour les flottants, il est de mˆeme possible de pr´eciser le nombre de chiffres apr`es la virgule, ainsi que le nombre total de caract`eres (point compris) :

printf("%6.2f %.3Lf",x,y);

affiche la variable flottante x avec 2 chiffres apr`es la virgule, mais en ins´erant des espaces devant afin que le tout fasse 6 caract`eres. Tandis que le variable de type long double y sera simplement affich´ee avec 3 chiffres apr`es la virgule, sans sp´ecification de la longueur totale.

Enfin, il est ´egalement possible de formatter l’affichage des chaˆınes de caract`eres en pr´ecisant la taille globale (le nombre d’espaces `a ins´erer en tˆete) :

printf("%20s",chaine);

affiche la chaˆıne de caract`ere chaine avec des espaces devant afin que le tout fasse 20 caract`eres.

4.2

La saisie avec scanf

La fonction scanf permet de saisir des valeurs tap´ees au clavier pendant l’ex´ecution du programme. La syntaxe est tr`es semblable `a celle de la fonction printf, mais en sens inverse : scanf("valeurs %d et %d",&i,&j); attend, au clavier, une phrase de la forme valeurs 10 et 31 et mettra la valeur 10 dans la variable i et la valeur 31 dans la variable j.

On remarquera que la notation des variables diff`ere de leur utilisation avec printf. En effet, il faut indiquer `a la fonction scanf l’adresse de la variable dans laquelle on veut stocker la valeur scann´ee, d’o`u le & qui acc`ede au pointeur associ´e `a la variable qui suit (voir le chapitre 8 sur les pointeurs).

(40)

Type et Variable Affichage Format

short i; scanf("%hd",&i);

int j; scanf("%d",&j); d´ecimal

long k; scanf("%ld",&k);

short i; scanf("%ho",&i);

int j; scanf("%o",&j); octal

long k; scanf("%lo",&k);

short i; scanf("%hx",&i);

int j; scanf("%x",&j); hexad´ecimal

long k; scanf("%lx",&k);

float x; scanf("%f",&x);

double y; scanf("%lf",&y); d´ecimal (avec point)

long double z; scanf("%Lf",&z); float x; scanf("%e",&x);

double y; scanf("%le",&y); exponentiel

long double z; scanf("%Le",&z);

char c; scanf("%c",&c); caract`ere

char m[10]; scanf("%s",m); chaˆıne de caract`eres

scanf("%s",&m[0]); Fig. 4.2 – Saisie avec scanf

La fonction scanf retourne un entier, qui peut ˆetre r´ecup´er´e ou non : k = scanf("valeurs %d et %d",&i,&j);

la valeur retourn´ee, stock´ee dans k, vaut le nombre de variables scann´ees. En effet, si l’utilisateur tape valeurs 10 est 31, le 10 sera lu, mais ne voyant pas le mot et apparaˆıtre, rien d’autre n’est lu. Ainsi la fonction scanf retourne 1. Si l’utilisateur tape n’importe quoi, la fonction scanf retourne 0. Pour une utilisation normale, telle que la phrase entr´ee ci-dessus, la fonction scanf retournera 2.

(41)

Chapitre 5

Les op´

erateurs et les expressions

Sommaire

5.1 Les op´erateurs . . . 39 5.1.1 Les op´erateurs arithm´etiques . . . 40 5.1.1.1 Op´erateurs standard . . . 40 5.1.1.2 Op´erateurs d’incr´ementation ++ et −− . . . 40 5.1.1.3 Op´erateurs de signe . . . 42 5.1.1.4 Op´erateurs de d´ecalage . . . 42 5.1.2 Op´erateur de conversion de type (“ cast ”) . . . 42 5.1.3 Op´erateur de taille . . . 42 5.1.4 Op´erateurs logiques . . . 43 5.1.5 Op´erateurs de masquage . . . 43 5.1.6 Op´erateurs de relations . . . 43 5.1.7 Op´erateur d’affectation . . . 43 5.1.8 Op´erateurs abr´eg´es . . . 44 5.2 Les expressions . . . 44

Maintenant que l’on connaˆıt les variables, les constantes, comment les d´efinir et les afficher, voyons comment les manipuler, les modifier avec les op´erations standard.

5.1

Les op´

erateurs

Les op´erateurs sont des commandes qui s’appliquent `a des op´erandes, qui sont des constantes, des variables ou des expressions (voir la section suivante).

Les op´erateurs peuvent ˆetre r´epertori´es en fonction du nombre d’op´erandes qu’ils

prennent comme arguments : les op´erateurs unaires, qui ne prennent qu’un argument

(voir figure 5.1), les op´erateurs binaires, qui prennent deux arguments, tels que les op´ e-rateurs arithm´etiques classiques (addition, soustraction, etc). Une liste plus compl`ete est propos´ee figure 5.2. Enfin, l’op´erateur ternaire, qui prend trois arguments. Commen¸cons par ce dernier type, qui ne contient qu’un cas dans le langage C :

test ? expr1 : expr2

(42)

Le premier argument est un test test, en fonction de son ´etat de validit´e, le r´esultat de l’expression expr1 ou de l’expression expr2 est retourn´e : expr1 pour un test vrai, expr2 pour un test faux. Ceci est une version abr´eg´ee des instructions de condition (if et else) que nous verrons dans le chapitre suivant. `A ´eviter pour produire un programme lisible ! Au lieu d’´etudier les autres op´erateurs plus classiques par leur nombre d’op´erandes, regroupons-les par cat´egories de proc´edures.

5.1.1

Les op´

erateurs arithm´

etiques

5.1.1.1 Op´erateurs standard

Les op´erations arithm´etiques se font avec les op´erateurs classiques : +, -, * et /. Si les arguments sont des entiers, les op´erations retournent des entiers. Notamment, la division “ / ” retourne le quotient de la division euclidienne, tandis que “ % ” retourne le reste de

cette division euclidienne.

Sinon, les quatre op´erateurs de base manipulent des flottants.

arithmetique.c int main () { int a,b,c; float x,y,z; a = 5; b = 7; c = b/a; /* alors c = 1 */ c = b%a; /* alors c = 2 */ c = b++; /* alors b = 8 et c = 7 */ c = ++a; /* alors a = 6 et c = 6 */ c = a >> 3; /* alors c = 48 */ c = b << 2; /* alors c = 2 */ x = 3.01; y = 0.02; z = -x*y; /* alors z = -0.0602 */ return 0; }

Programme 9: Op´erateurs arithm´etiques (arithmetique.c)

5.1.1.2 Op´erateurs d’incr´ementation ++ et −−

Il existe des op´erateurs d’incr´ementation et de d´ecr´ementation abbr´eg´es :

i++; et ++i; reviennent `a ´ecrire i = i+1;

(43)

5.1. LES OP ´ERATEURS 41

Cat´egorie Op´erateur Action

arithm´etique −− d´ecr´ementation

++ incr´ementation

− inverser le signe

+ confirmer le signe

type (type) convertit le type de la variable (“ cast ”)

adressage & retourne l’adresse (pointeur) d’un objet

(pointeurs) * retourne le contenu d’une variable

`

a l’adresse indiqu´ee

logique ! NOT logique

masquage ~ NOT bit `a bit

divers sizeof taille de l’objet (ou du type) en octets

Fig. 5.1 – Op´erateurs unaires

Cat´egorie Op´erateur Action

arithm´etique + addition

− soustraction

∗ multiplication

/ division (enti`ere si entre entiers)

% reste de la division euclidienne

d´ecalages << vers la gauche

>> vers la droite

logique && ET logique

|| OU logique

masquage & ET bit `a bit

| OU bit `a bit

^ XOR bit `a bit

relations < inf´erieur strict

<= inf´erieur ou ´egal

> sup´erieur strict

>= sup´erieur ou ´egal

== ´egal

!= diff´erent

divers = affectation

(44)

Cependant, les valeurs retourn´ees par ces op´erations diff`erent :

– j = i++; est une post-incr´ementation de i. C’est-`a-dire que j prend la valeur de i, puis i est incr´ement´e ;

– j = ++i; est une pr´e-incr´ementation de i. C’est-`a-dire que i est incr´ement´e, puis j prend la valeur du i, apr`es incr´ementation.

Il en est de mˆeme pour les i--; et --i; (voir le programme 9).

5.1.1.3 Op´erateurs de signe

Les op´erateurs unaires + et − permettent de confirmer on d’inverser le signe : j = +i ; k = -i ;

5.1.1.4 Op´erateurs de d´ecalage

Les op´erateurs de d´ecalage peuvent ˆetre assimil´es `a des op´erateurs arithm´etiques, bien que leur usage standard soit pour des masquages. Mais, en fait, un d´ecalage de n `a droite revient `a une division par 2n, tandis qu’un d´ecalage `a gauche de n revient `a une multiplication par 2n.

5.1.2

Op´

erateur de conversion de type (“ cast ”)

Si des scalaires de diff´erents types interviennent dans une expression arithm´etique, le type final de l’expression est le type le plus g´en´eral des divers ´el´ements : les types plus stricts sont automatiquement “ cast´es ” dans le type plus g´en´eral (voir la figure 5.3). On

short → int → long → float → double→ long double Fig. 5.3 – Cast automatique

peut ´egalement forcer la conversion de type, en mettant le nouveau type entre parenth`eses devant la variable : int a = 5; int b = 7; float c,d; c = a/b; d = (float) a/b;

Dans le programme ci-dessus, la variable c prend le r´esultat de la division euclidienne (entre entiers), donc 0. Tandis que la variable d prend la r´esultat de la division entre l’entier a converti en float et l’entier b. Ainsi, le r´esultat est un float : 0.714286.

5.1.3

Op´

erateur de taille

Puisque nous somme dans les types, nous avons vu qu’il pouvait ˆetre utile de connaˆıtre la taille d’un objet, pour savoir la place n´ecessaire en m´emoire. Nous verrons encore plus

(45)

5.1. LES OP ´ERATEURS 43

l’utilit´e pour l’allocation dynamique de m´emoire, dans le chapitre sur les pointeurs (voir chapitre 8).

La commande sizeof fournit cette information, en nombre d’octets : sizeof(int) retourne la taille d’un entier, c’est-`a-dire 4 octets pour gcc sous linux. De mˆeme, si a est une variable de type int, sizeof(a) retourne la taille de cette variable, et donc la taille d’un int, soit 4 octets.

5.1.4

Op´

erateurs logiques

Il est possible de manipuler des valeurs bool´eennes, repr´esent´ees par des entiers : le 0 valant faux, tandis que toute valeur non nulle repr´esente le vrai (en g´en´eral, on utilise simplement le 1). Ainsi, les op´erateurs !, && et || repr´esentent respectivement le NOT, ET et OU logiques.

5.1.5

Op´

erateurs de masquage

Il est ´egalement possible de manipuler ind´ependamment chaque bit d’un entier, un `a un, avec des op´erations logiques. Ceci permet notamment de masquer certains bits, mais ´egalement d’en inverser, etc.

Ainsi, les op´erateurs ~, &, | et ^ repr´esentent respectivement le NOT, ET, OU et XOR (OU exclusif) effectu´es bit `a bit.

5.1.6

Op´

erateurs de relations

Pour comparer certaines valeurs, on peut utiliser les relations binaires classiques, d’´ ega-lit´e mais ´egalement d’ordre strict ou non :

– le test d’´egalit´e est effectu´e avec l’op´erateur == tandis que le test de diff´erence est effectu´e avec l’op´erateur !=.

– les comparaisons strictes sont effectu´ees avec les op´erateurs < et >. – les comparaisons larges sont effectu´ees avec les op´erateurs <= et >=.

Chacun de ces tests retourne un bool´een (cod´e sous forme d’entier, comme vu pr´ec´ edem-ment).

5.1.7

Op´

erateur d’affectation

Comme on vient de le voir, le test d’´egalit´e s’effectue avec l’op´erateur binaire ==. En effet, l’op´erateur simple = est l’op´erateur d’affectation et non de test d’´egalit´e. Il affecte la valeur de droite `a la variable de gauche :

int a,b; a = 7; b = a + 9;

Si on souhaite affecter la mˆeme valeur `a plusieurs variable, il est possible de les affecter en cascade : i = j = k =10 ; qui affecte la valeur 10 aux variables i, j et k.

(46)

Remarque : Ne pas confondre les op´erateurs = et ==. C’est une erreur classique, souvent difficile `a d´etecter, car le compilateur ne peut s’en rendre compte, et ne le signale donc pas !

5.1.8

Op´

erateurs abr´

eg´

es

De mˆeme que les op´erateurs d’incr´ementation informent le compilateur que la variable elle-mˆeme doit ˆetre incr´ement´ee, il existe des versions abr´eg´ees de tous les op´erateurs arithm´etiques et de masquage qui informent le compilateur que l’op´eration doit s’effectuer sur la variable elle-mˆeme (voir la figure 5.4).

Cat´egorie Op´erateur Action

arithm´etique a += 5 ; a = a + 5 ; a -= 7 ; a = a - 7 ; a *= 2 ; a = a * 2 ; a /= 3 ; a = a / 3 ; a %= 3 ; a = a % 3 ; d´ecalage a <<= 5; a = a << 5; a >>= 7; a = a >> 7;

masquage a &= 0x10 ; a = a & 0x10 ;

a |= 077 ; a = a | 077 ;

a ^= 0xFF ; a = a ^ 0xFF ;

Fig. 5.4 – Op´erateurs abr´eg´es

5.2

Les expressions

(47)

Chapitre 6

Les structures de contrˆ

ole

Sommaire

6.1 Instruction . . . 45 6.2 Les boucles . . . 45 6.2.1 Les boucles while . . . 46 6.2.2 Les boucles for . . . 46 6.2.3 Les boucles do while . . . 48 6.3 Les conditions . . . 49 6.3.1 Condition if . . . 49 6.3.2 Condition switch . . . 50 6.4 Sauts Inconditionnels . . . 50 6.4.1 break . . . 50 6.4.2 continue . . . 50 6.4.3 return . . . 50 6.4.4 goto . . . 51

Un programme C est une suite s´equentielle d’op´erations. Il est bien sˆur possible de conditionner l’ex´ecution de certaines op´erations au r´esultat de calculs pr´ealables, ou de r´ep´eter un nombre fini (ou infini) de fois un groupe d’op´erations.

6.1

Instruction

Dans la suite, nous utiliserons le terme instruction pour d´esigner soit une instruction simple, termin´ee par un point-virgule, soit un groupe d’instructions simples, encadr´e par des accolades.

6.2

Les boucles

Les boucles permettent de r´ep´eter des instructions un grand nombre de fois. Il existe trois syntaxes diff´erentes en fonction des besoins.

(48)

6.2.1

Les boucles while

La syntaxe g´en´erale du while est

while (<test>) <instruction>

Cela signifie que tant que le test <test> est satisfait, l’instruction <instruction> est ex´ecut´ee. Si le test est “ faux ” d`es le d´ebut, l’instruction n’est jamais ex´ecut´ee. Un exemple classique d’utilisation de la boucle while est le calcul du PGCD avec la m´ethode d’Euclide (voir programme 10).

pgcd.c

#include <stdlib.h> #include <stdio.h>

int main (int argc, char *argv[]) { int a,b,r,x,y; x = a = atoi(argv[1]); y = b = atoi(argv[2]); while (b != 0) { r = a % b; a = b; b = r; } printf("pgcd (%d,%d) = %d\n",x,y,a); return 0; } Programme 10: PGCD (pgcd.c)

6.2.2

Les boucles for

La syntaxe g´en´erale du for est

for (<initialisation>; <test>; <incrementation>) <instruction>

Figure

Fig. 1.1 – Organisation d’un ordinateur – Programmation en C
Fig. 1.2 – Les ´ etapes de la programmation
Fig. 1.3 – Raccourcis-clavier sous emacs
Fig. 2.1 – Types entiers sous GCC/Linux
+7

Références

Documents relatifs

Déterminer x pour que le carré et le triangle équilatéral aient le même

Donner l’ensemble de définition de la fonction

L’étude du signe d’une fonction s’inscrit dans cette optique : à l’aide du signe de ax + b, nous allons être capable de déterminer le signe de la plupart des

b) En utilisant les variations de la fonction carré, trouver un encadrement de x². Dresser le tableau de variation de la fonction f. 1) Déterminer les coordonnées du

Nous pouvons généraliser la démarche qui nous a permis d’introduire dans le chapitre précédent le nombre e... É TUDE DE LA

On peut donc conclure que la proposition est vraie pour tout entier

Si deux points de sa représentation graphique ont la même ordonnée ils sont confondus donc leur abscisse est la même. autre

Remarque : On retrouve les propriétés des puissances. Pour x positif, car la fonction exponentielle est croissante. Donc la fonction g est croissante sur. D'après le théorème