Coursc IG3
Coursc IG3
POLYTECH'MONTPELLIER
IG1
Anne Laurent
[email protected]
1
Présentation du cours
● 10,5 heures de cours
● 21 heures de TD/TP
● Soit :
– 7 cours
– TD/TP : séances de 1,5h (TD et TP) puis 3h TP
● Contrôle des connaissances :
– Partiel (2/3 de la note finale)
– Projet (1/3 de la note finale)
2
Bibliographie
● Kernighan et Ritchie, Le langage C, 2nd
édition, Masson, 1997.
● Garetta, C : Langage, bibliothèque,
applications, Interéditions
● Sedgewick, Algorithmes en langage C,
Interéditions.
● Sites Web : INT Evry
● ...
3
Historique
● Initialement écrit pour supporter le système
UNIX par Dennis Ritchie et Brian Kernighan.
Début des années 70. (Bell)
● Plus de 90% du noyau UNIX écrit en C
● Utilitaires systèmes écrits en C (shell)
● Normalisation en 1989 par l'ANSI (American
National Standard Institute) → C ANSI
● Le C n'est pas lié à UNIX
● Successeur orienté objet : C++
4
I. Présentation générale de C
● Langage de haut niveau ...
● ... mais proche de la machine :
– Permet l'accès aux données manipulées par
l'ordinateur (bits, octets, adresses)
● Programmation modulaire. Compilation
séparée (plusieurs fichiers sources plusieurs
fichiers objet)
● Langage faiblement typé
5
Structure générale d'un
programme C
● Un programme C est formé :
– d'un ensemble de fonctions dans lequel doit
figurer une fonction main. Équivalent ADA d'une
fonction C : procédure ou fonction
– éventuellement d'un ensemble de variables
globales
– éventuellement de directives au préprocesseur C
● Fonctions écrites par le programmeur ou
issues de bibliothèques
● Unité de compilation : fichier source
6
Compilation : Obtention d'un
exécutable
● En deux étapes :
● gcc -Wall -ansi -c prog.c
● gcc -o prog prog.o
● En une étape :
● gcc -Wall -ansi -o prog prog.c
● -Wall : option de compilation pour avoir les warnings du
compilateur
● -ansi pour compiler en C ANSI
● -c ne lance que la compilation mais pas l'édition de liens
● -o : si vous n'utilisez pas cette option, l'exécutable se
7 nomme a.out
Modularité
● Programme C : constitué de différents
fichiers sources destinés à être compilés de
manière séparée et à subir une édition de
lien commune
● Trois parties :
– Fichiers entêtes (suffixe .h)
– Fichiers de définitions de fonctions C (suffixe .c)
– Le fichier .c contenant le début du programme :
fonction main
8
Fonction
● Interface :
– Type et nom de la fonction
– Types et noms des paramètres
● Bloc (corps de la fonction) :
– Accolade ouvrante
– Définitions des variables locales
– Instructions
– Accolade fermante
● Instruction :
– bloc ou expression suivie d'un « ; » ou instruction de
9 contrôle (test, boucle ...)
II. Types et variables
● Rôles de la définition d'une variable :
– Définition du domaine de valeur de cette variable
– Définition des opérations possibles sur cette
variable
– Association du nom de variable à une adresse
mémoire
– Initialisation à une valeur compatible avec le
domaine de valeurs
● Déclaration :
– type nom
10
Types de base
● void : type vide
● int : type entier.
– Taille : long/short int
– Signe : unsigned/signed int
– int = signed int
● char : entier sur 8 bits. de -128 à 127. table ASCII
● Float : flottants
– Simple précision : float
– Double précision : double
11 – Très grande précision : long double
Taille des types
● Espace occupé en mémoire : dépend de la
machine
● char : 1 octet
● short int : 1 mot mémoire. 16 bits
● long int : 2 mots mémoire. 32 bits
● float : 1 mot mémoire
● double : 2 mots mémoire
12
Portée des variables
● Variables déclarées dans un bloc :
– Créées à l'entrée du bloc
– Visibles dans le bloc et les sous-blocs imbriqués
– Détruites à la sortie du bloc
● Variables déclarées au début du fichier (à
l'extérieur d'un bloc) :
Locales
– Créées au début du programme
globales
– Visibles partout
– Détruites à la fin du programme
13
Validité des variables
● 4 classes de variables :
– AUTOMATIC (par défaut)
– EXTERN
– STATIC
– REGISTER
14
Détail
● AUTOMATIC : variable déclarée à l'intérieur d'une fonction.
Durée de vie = durée de vie de la fonction
● EXTERN : variables globales à toutes les fonctions. Précise les
variables définies dans un autre fichier et utilisées dans ce fichier
source. Pas d'allocation de mémoire.
● STATIC :
– variable locale à une fonction MAIS qui existe quand même
quand la fonction n'est pas appelée
– variable globale MAIS mais pas utilisable dans un autre fichier
● REGISTER : avertir le compilateur que la variable sera très
utilisée. Si possible, la variable sera placée dans un registre
processeur.
15
Constantes symboliques
● Pour donner une nom à une constante on peut
utiliser la directive #define traitée par le
préprocesseur C
● #define Nom texte_remplacement
● #define VRAI 1
● #define FAUX 0 Pas de ;
● Pas de booléen en C !
● Pas de vérification syntaxique
● Convention : noms des constantes en majuscules
16
III. Opérateurs et expressions
● Affectation : opération normale
● Opérateurs unaires
● Opérateurs binaires
● Opérateurs ternaires
● Expression : suite syntaxiquement correcte
d'opérandes et d'opérateurs
● Une expression ramène toujours une valeur
(même non utilisée)
17
Opérateurs unaires
• & opérateur d'adresse. Retourne l'adresse de la variable suivant le &
• * opérateur d'indirection sur une adresse. Permet d'accéder à une
variable à partir d'une adresse.
• -- opérateur de décrémentation. var-- versus --var
• ++ opérateur d'incrémentation. var++ versus ++var
• Sizeof opérateur donnant la taille en octets
• ! not logique (inversion d'une condition)
• - moins unaire (inversion du signe)
int i, j=0;
• ~ complément à un
Fausse si =0. vrai sinon.
i = j++ ;
!0 vaut 1 !9 vaut 0 i = ++j ;
18
Opérateurs binaires
d'affectation
● Arithmétique +=, -=, *=, /=, %=
● Masquage &=, |=, ^=
● Décalage >>=, <<=
● Exemples :
– i += 10 ; i = i + 10 ;
– i += j + 25 ; i = i + j + 25 ;
– i <<= 4 ; i = i << 4 ; décale i à gauche de 4
positions
19
Opérateur ternaire
● Met en jeu trois expressions (exp1, exp2,
exp3)
● exp1?exp2:exp3
● On commence par évaluer exp1
– Si sa valeur n'est pas nulle (condition vraie)
– Alors la valeur retournée est celle de exp2
– Sinon c'est celle de exp3
● Exemple :
– z = (a>b)?a:b ;
20
Précédence des opérateurs
8. Egalités == !=
1. Parenthésage
9. Et bit à bit &
2. Opérateurs unaires
10. ou exculsif bit à bit ^
3. Changements de types
11. Ou bit à bit |
4. Multiplicatifs * / %
12. Et logique &&
5. Additifs + -
13. Ou logique ||
6. Décalages << >>
14. Condition
7. Comparaisons < <= > >=
15. Opérateurs binaires d'affectation
16. Succession
21
Exercice
22
Correction 1
#include <stdio.h>
int main(void)
{
int i;
char res;
printf(''Saisissez un nombre entier : '');
scanf(''%d'',&i);
res=(i%2 == 0)?'P':'I' ;
printf(''Le nombre %d est %c'', i, res);
return (1);
}
23
Correction 2
#include <stdio.h>
int main(void)
{
int i;
26
Instructions conditionnelles : if
● Syntaxes du if :
– if (expression) instruction
– if (expression) instruction1 else instruction2
● Exemple :
– if (i % 2 == 0) printf(''pair '') else printf(''impair'');
● Imbrication des if. LeUtiliser
elsedesva avec
blocs : le if le plus
proche non terminé (sans
if (cond1){else)
Pas de ;
if (cond2)
une seule
if (i == 1) inst1 inst1
instruction entre la
else if (i == 2) inst2 }
condition et le else
else if (i==3) inst3 else
27 ... inst2 ;
EXERCICE
● Quelle différence entre
if(c1) if(c2) i1; else i2;
● Et
if (c1) {if (c2) i1;} else i2;
30
Boucle WHILE
● while (exp) inst
while (exp)
Sans accolades si une seule instruction :
{ while (i<j) i = 2 * i ;
...
}
32
Boucle FOR
● Trois expressions exp1, exp2, exp3
● for (exp1;exp2;exp3) inst
● Exemple :
for (i = 0 ; i < 10 ; i++)
exp1 : début
printf(''%d\n'',i);
● exp2infinie
Absence des expressions : boucle : fin
for(;;) inst exp3 :
exécution à
chaque
33
itération
Exercice
Exprimez la construction
avec un while
34
for (exp1;exp2;exp3) inst
Équivaut strictement à
exp1;
while (exp2){
inst
exp3 ;
}
35
Break et continue
● Pour les instructions for, while, do et switch :
– break provoque l'abandon de la structure et le
passage à l'instruction écrite immédiatement derrière
● Pour les instructions for, while et do :
– Continue provoque l'abandon de l'itération courante
et le cas échéant le passage de l'itération suivante
● Boucles imbriquées : c'est la boucle la plus
profonde qui est concernée par break et
continue
36
Exemple
● Avec la construction for
● Utilisation de break pour éviter des boucles
infinies :
for (;;){
printf(''donnez un nombre (0 pour sortir) : '');
scanf(''%d'',&n);
if (n == 0)
break;
...
}
37
EXERCICE
Ecrire un programme n
qui calcule le plus grand terme
de la série i=1i3 qui est inférieur à 1000.
38
V. Types dérivés des types de base :
Structures, Pointeurs et tableaux
● Tableaux
● Structures
● Enumérations
● Pointeurs
39
Tableaux
● Cas simple :
– type_de_base nom [nb_elements_optionnel] ;
– Exemple : unsigned long table[10];
● Premier élément : indice 0
● Sur l'exemple précédent :
– table[0], table[1], ..., table[9]
● Expression optionnelle : de type entier et constante (le
compilateur doit pouvoir évaluer la taille du tableau en
mémoire)
40
Tableaux à plusieurs
dimensions
● Dimensions entre crochets
● Syntaxe :
– type nom_tab [dim1][dim2]...[dimn]
● Exemple :
– int tab[5][10];
● Accès aux composantes :
– printf(''%d\n'', tab[0][1]);
41
Attention
42
Chaînes de caractères
● Tableau de caractères
● Dernier caractère : code nul \0
● Constante délimitée par les ''
● char mess[ ]="bonjour";
● Tableau de 8 caractères (\0 dans mess[7])
43
Fonctions de manipulation des
chaînes de caractères
· int strlen(chaîne) donne la longueur de la chaîne (\0 non
compris)
· char *strcpy(char *destination,char *source) recopie la source
dans la destination, rend un pointeur sur la destination
· char *strncpy(char *destination,char *source,int longmax)
idem strcpy mais s'arrête au \0 ou longmax (qui doit comprendre
le \0)
· char *strcat(char *destination,char *source) recopie la source
à la suite de la destination, rend un pointeur sur la destination
· char *strncat(char *destination,char *source,int longmax)
idem
· int strcmp(char *str1,char*str2) rend 0 si str1= =str2, <0 si
44 str1<str2, >0 si str1>str2. Idem strncmp
Structures
● Constituants (champs) de types différents
● Champs désignés par un identificateur
● Syntaxe :
– struct nom_type {déclaration des champs} ;
struct <identificateur>{
<type><liste_identificateurs>;
...
<type><liste_identificateurs>;
};
– struct nom_type {déclaration des champs} liste_variables ;
45
● Accès à une composante : nom_variable.nom_champ
Définition de types
● Mot-clé typedef
● Syntaxe générale :
– typedef type nouveau_type
● Définition d'un nouveau nom et non d'un
nouveau type
● Utilisé pour la lisibilité du code
● Exemple :
– typedef struct {int jour, mois, annee} date;
46
Exemples
● Structure personne
struct personne{
char nom[20];
int age;
};
● Déclaration
– struct personne p1, p2 ;
● Accès aux champs :
– p1.age = 30;
– printf(''%s a %d ans\n'',p1.nom,p1.age) ;
47
Enumérations
● Liste finie de nombre d'entiers
● Syntaxe de déclaration :
– enum nom_enum {liste_enum};
● Exemple :
– enum jour_semaine{lundi, mardi, .., dimanche};
– lundi vaut 0, mardi 1, etc.
– lundi + 2 représente la même valeur que mercredi
● On peut préciser explicitement les valeurs :
– enum echap {LIGNE='\n',TAB='\t'};
● Ou que certaines puis les autres sont déduites par
48 incrémentation
Pointeurs : rappels
● Mémoire visualisée comme un tableau d'octets
● Variable : série de cases consécutives (nombre de cases
selon le type de la variable)
● Pointeur : adresse d'un groupe de cases mémoire
#include <stdio.h>
#include <stdlib.h>
int main(void){
int x, i;
float r;
short int j,k;
char str[24];
x=3;
strcpy(str,''Hello'');
x=x+1;
return (0);
49
}
Pointeurs en C
● Manipulation des adresses des objets
● Opérateur & sur un objet de type quelconque : fournit
l'adresse de cet objet en mémoire
● Opérateur * : accès à la valeur stockée dans une case
mémoire dont on connaît l'adresse
● Déclaration d'un pointeur sur un objet de type <type> :
<type> *p;
● Pointeur NULL : le pointeur n'est pas initialisé et ne
contient pas d'adresse utilisable
● Type void : pointeur de n'importe quel type MAIS
50 l'opérateur * ne peut pas s'appliquer. void *ptr;
Pointeurs et tableaux
51
Tableaux de caractères et
chaînes de caractères
● Chaîne de caractères : espace mémoire
avec des caractères dont le dernier est '\0'
● Si '\0' absent alors tableau de caractères et
non chaîne de caractères
– fonctions de manipulation de chaînes ne
marcheront pas convenablement
● char tab[]=”xx”; ≠ char *point=”xx”;
● Lecture sur l'entrée standard :
char tab[100];
scanf(”%s”,tab);
52
Tableaux de pointeurs
● Pointeurs de pointeurs
● <type> *pt[n];
● Essentiellement utilisés comme tableaux de
chaînes de caractères
– Tableaux de 10 chaînes de caractères :
char *ch[10];
● Pointeur sur une chaîne : pointeur sur un
pointeur de caractères.
● char *ch[10]; et char **ch;
53
Tableaux de pointeurs et
tableaux multidimensionnels
● Tableaux multidimensionnels préférables aux
tableaux de pointeurs
● Sauf chaînes de caractères :
– Tableau multidimensionnel de type char : tableau de
chaînes de longueur fixe
● char tab1[][14] = {”longue chaine”,”ch1”,”ch2”} ;
longue chaine\0 ch1\0 ch2\0
– Tableau de pointeurs char : possibilité de chaînes de
longueur différentes
● char *tab2[] = {”longue chaine”,”ch1”,”ch2”} ;
longue chaine\0
ch1\0
54 ch2\0
Structures chaînées
● Liste chaînée :
struct liste{
struct liste{ int val;
int val; struct liste
struct liste *suite; suite;
} }
55
Opérations sur les pointeurs
● pi et qi deux pointeurs
● Si pi pointe sur la variable x alors *pi
équivaut à x
● Affectation entre pointeurs. qi = pi; avec qi
et pi de même type : qi pointe aussi sur x
● Calculs d'adresse par incrémentation :
pi++ incrémente l'adresse du nombre
d'octets correspondant au type de pi
(augmentation de 4 pour les entiers)
56
Instructions malloc et calloc
● Allocation mémoire
● void * malloc(size_t size); réserve un espace mémoire
de size octets et renvoie l'adresse du début de la
zone. Renvoie NULL si impossible de réserver cet
espace
● void * calloc(size_t size); même opération avec
initialisation des octets à la valeur 0
● Conversion de type avant d'affecter le résultat à un
pointeur typé
● Utilisation de sizeof pour obtenir la taille en octets d'un
57 type
Exemple
#include <stdio.h>
#include <stdlib.h> Pour malloc, free, calloc
void main(void){
int *p, i, n;
scanf(“%d”, &n);
p=(int *) malloc(n * sizeof(int));
for (i=0;i<n;i++) p[i] = i ;
printf(“p[0]=%d,p[1]=%d,...\n”,p[0],p[1]);
}
Intérêt de l'allocation dynamique
58 Conversion de type
malloc et tableaux de pointeurs
● Espace mémoire non alloué par la déclaration
d'un tableau de pointeurs
char *ch[10];
ch=(char **)malloc(10*sizeof(char *));
● Attention à ne pas provoquer de segmentation fault
int *t[10];
int *t[10]; int i;
60
Instruction realloc
61
Exercices
62
VI. FONCTIONS
● Rappels :
– définie par son entête, suivie d'un bloc d'instructions
– entête : type_retourné nom_fonction(liste_arguments)
(pas de ;)
– La liste d'arguments est typée :
float toto(int a, float b) {bloc}
● Récursivité : une fonction peut s'appeler elle-même
63
Passage de paramètres
● Par valeur :
– Évaluation de la valeur puis recopie sur la pile.
– Les modifications ne sont pas transmises à
l'appelant
● Par adresse :
– Paramètre = pointeur
– Attention : un nom de tableau est traité comme
l'adresse du premier élément
– Si un tableau est passé en paramètre, la fonction
peut accéder et modifier tout le tableau
64
Exemple : Qu'affiche ce programme ?
#include <stdio.h>
void echanger(int a, int b){
int temp=a;
a=b;
b=temp;
printf(“%d, %d\n”, a, b);
}
int main(void){
int nb1,nb2;
scanf(“%d %d”,&nb1, &nb2);
echanger(nb1,nb2);
printf(“%d, %d\n”, nb1, nb2);
return (0) ;
65 }
Passage par référence
● Moyen de modifier une variable de la
fonction appelante
● Indication de l'adresse mémoire où sont
stockées les valeurs des variables
void echanger(int *px, int *py)
{ Appel de la fonction :
int temp=*px; int a,b;
*px=*py; echanger(&a,&b);
*py=temp;
}
66
Tableau en paramètre
● Pas nécessaire d'indiquer le nombre
d'éléments
– void f(int tab[ ]);
● Équivalent à
– void f(int *tab);
67
La fonction main
● Transmission d'arguments au programme :
int main(int argc,char *argv[])
● argc : nombre d'arguments
● argv : tableau des arguments
● argv[0] : nom de l'exécutable
● atoi : conversion des paramètres vers le
type int
68
EXERCICE
69
Correction : fonction factorielle
● Fonction itérative :
int factorielle(int i)
{
int result;
for(result=1;i>1;i--) result*=i;
return(result);
}
● Fonction récursive :
int factorielle(int i)
{
if (i>1)
return(i*factorielle(i-1));
else return(1);
}
70
Correction : main
#include <stdio.h>
#include <stdlib.h>
int factorielle(int i){...}
int main(int argc, char *argv[ ]){
int fact ;
if (argc != 2){
printf(“Usage : %s nombre\n”,argv[0]);
return (-1);
}
fact = factorielle(atoi(argv[1]));
printf(“Factorielle de %d : %d\n”,atoi(argv[1]),fact);
return(0);
71 }
VII. Entrées/Sorties
● Réalisées par des fonctions de la
bibliothèque standard stdio.h
● Formatage des données et mémorisation
des données dans une mémoire tampon
● Flots de données (data streams) : suites
d'octets
● Flots textes : suite de caractères ASCII
structurée en lignes terminées par '\n'
● Flots binaires : données enregistrées sans
72 conversion au format ASCII
Flots standards
● 3 flots standards : stdin, stdout, stderr
● Connectés par défaut au lancement du
programme à l'écran pour les sorties, au
clavier pour les entrées
● Peuvent être explicitement redirigés vers un
fichier ou un périphérique
● Dans un programme, flot déclaré de type
FILE*
73
Fichiers
● 2 types de fonctions de manipulation de
fichiers
● Fonctions de niveau 1 :
– très proches du SE.
– accès direct aux informations non bufferisées.
– manipulation sous forme binaire sans formatage.
● Fonctions de niveau 2 :
– basées sur les fonctions de niveau 1.
– E/S bufferisées.
74 – manipulation binaire ou formatée.
Opérations sur les fichiers
(niveau 2)
● Déclaration d'un pointeur de fichier : FILE *mon_fich;
● Ouverture : FILE * fopen(char *nom, char *mode);
– Ouvre le fichier nom. Rend un pointeur sur le flot
correspondant ou NULL si échec
– Valeur mode :
● “r”, “w”, “a”, “r+”, “w+”, “a+”
● mode binaire : ajouter b au mode (“r+b”)
● Fermeture : fclose(FILE *f);
● Contrôle du tampon : int fflush(FILE *f);
●
Fin de fichier : int feof(FILE *f);
75
Opérations sur les fichiers :
lecture et écriture textuelles
● fscanf(FILE *f, const char *format, liste_adresses);
● fprintf(FILE *f, const char *format, liste_expressions);
●
int fgetc(FILE * f); getchar()fgetc(stdin);
●
int fputc(int c, FILE * f); putchar(c)fputc(c, stdin);
● char *fgets(char *ch, int lgmax, FILE *f);
● gets(char *ch);
● int fputs(char *ch, FILE *f);
● int puts(char *ch);
76
Mode binaire
● Lecture et écriture :
– size_t fwrite(const void *ptr, size_t t, size_t nobj, FILE *f);
– size_t fread(void *ptr, size_t t, size_t nobj, FILE *f);
● Positionnement :
– int fseek(FILE *f, long offset, int mode);
– Mode : 0 par rapport au début du fichier, 1 par rapport
à la position courante, 2 par rapport à la fin du fichier
– long ftell(FILE *f);
– int rewind(FILE *f);
77
EXERCICE 1
78
CORRIGE
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *in;
char c;
if (argc != 2){
printf(”nbre de parametres incorrect\n”); return(1);
}
if ((in=fopen(arg[1],”r”))= =NULL){
printf(”fichier inexistant\n”); return (2);
}
return(0);
}
79
EXERCICE 2
80
CORRIGE
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *f;
int ok, c, i;
if (argc != 2){
printf(”nbre de parametres incorrect\n”); return(1);
}
f=fopen(argv[1],”rt”); c=fgetc(f);
while(c!=EOF){
putchar(c) ; c=fgetc(f);
}
ok = fclose(f); return(0);
81 }
EXERCICE 3
82
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *in, *out;
char c;
if (argc != 3){
printf(”nbre de parametres incorrect\n”); return 1;
CORRIGE 1
}
if ((in=fopen(arg[1],”r”))= =NULL){
printf(”fichier inexistant\n”);return 1;
}
if ((out=fopen(arg[2],”w”))= =NULL){
printf(”impossible de creer le fichier\n”);return 1;
}
while((c=fgetc(in))!=EOF) fputc(c,out);
return(0);
83 }
84
CORRIGE 2
EXERCICE 4
85
86
VIII. Introduction à la
compilation séparée
● Pour les programmes dépassant une certaine taille
● Regroupement des fonctions dans différents fichiers
● Un fichier source contenant la fonction main
● Appel de fonctions déclarées dans d'autres fichiers si
déclaration préalable
● Variables et fonctions EXTERN : informer le
compilateur que les définitions sont présentes dans
d'autres fichiers. pas d'allocation de mémoire
(définition vs. déclaration)
87
Gestion des différents fichiers
● Plusieurs fichiers sources .c
● Regroupement des déclarations dans une
bibliothèque de fonctions (library), fichier
d'en-tête .h (header)
● #include “entete.h”
● Compilation : gcc -o exec f1.c f2.c ...
● Mais inutile de tout recompiler
Compilation séparée
88
Rappels
● Deux étapes : compilation et édition de liens
● Compilation : transforme un programme C
en langage machine (sans se soucier des
appels de procédures)
● Edition de liens : Vérification des appels de
procédures et laison des appels de
procédures à leur déclaration
● Option -c : le compilateur n'effectue pas
l'édition de liens
89
FICHIERS FICHIERS EXECTUBALE
SOURCES OBJETS
f1.c f1.o
f2.c f2.o
exec
f3.c f3.o
f4.c f4.o
93
Exemple de Makefile
#voici un fichier makefile exemple
CFLAGS = -ansi
exec : f1.o f2.o f3.o
gcc $ (CFLAGS) -o exec f1.o f2.o f3.o
princ.c
surf.c
#include “pi.h”
#include “pi.h” int main(){
float surface(float r){ float ray ;
return(PI * r * r); printf(“rayon?\n”);
} scanf(“%f”,&ray);
printf(“%f %f\n”,
surface(ray),
circ.c circonference(ray));
return 0;
}
#include “pi.h”
float circonference(float r){
return(PI * 2 * r);
}
96
Compilation
gcc -c surf.c
gcc -c circ.c
gcc -c princ.c
gcc -o princ princ.o surf.o circ.o
makefile
dépendances
CC=gcc
commandes
princ : princ.o surf.o circ.o
<TAB>$(CC) -o princ princ.o surf.o circ.o
.o : surf.o circ.o pi.h
<TAB> $(CC) -c surf.o surf.c
<TAB> $(CC) -c circ.o circ.c
97
IX. En vrac ...
98
scanf : Saisie de plusieurs
valeurs
● scanf("%d %d", &x, &y);
● Que se passe-t-il si on saisit 1 2 ?
● Et 1 (entrée) 2 ?
● Et 1, 2 ?
● Quels résultats de saisie avec :
– scanf("%d%d", &x, &y);
– scanf("%d, %d", &x,&y);
– scanf("%d , %d", &x,&y);
99 – scanf("%d\n%d", &x,&y);
Résultats de saisie
●
scanf("%d %d", &x, &y);
●
1 2 Entrée : 1 afffecté à x, et 2 affecté à y.
●
1, 2 Entrée : 1 affecté à x mais rien affecté à y
●
scanf("%d, %d", &x,&y);
●
1 2 Entrée : 1 affecté à x mais 2 non affecté à y
●
1,2 Entrée : OK
●
1, 2 OK aussi (scanf ignore les espaces, tabulations et retours
charriot après les délimiteurs)
●
scanf("%d\n%d", &x,&y);
●
Pas de délimiteur après le dernier format !
100
Exemple
avec scanf("%d, %d", &x,&y);
gcc -o t t.c
#include <stdio.h>
116 [email protected]:laurent % t1
14
int main() { 117 [email protected]:laurent % t
12
int a,b; 14
118 [email protected]:laurent % t
scanf("%d, %d",&a,&b); 1,2
printf("%d %d\n",a,b); 12
119 [email protected]:laurent % t
return 0; 1, 2
} 12
120 [email protected]:laurent % t
1 ,2
101 14
atoi
● Que renvoient
– atoi(“23”);
– atoi(“29abc”);
– atoi(“a”);
– atoi(“2.3”);
#include <stdio.h>
int main() {
printf("%d %d %d %d\n",atoi("23"),atoi("29abc"),atoi("a"),atoi("2.3"));
return 0;
}
23 29 0 2
102
●
itoa (non ANSI C !!!) sprintf
Exemple
#include <stdio.h>
#include <stdlib.h>
int main() {
char str1[ ] = "124z3yu87";
char str2[ ] = "-3.4"; str1: 124
char *str3 = "e24"; str2: -3
printf("str1: %d\n", atoi(str1)); str3: 0
printf("str2: %d\n", atoi(str2));
printf("str3: %d\n", atoi(str3));
return 0;
}
103
sprintf
● 3 arguments
● Convertit le nombre_source en chaîne de
caractères dans dest
● Retourne le nombre de caractères dans la
chaîne dest
● sprintf(dest, format, nombre_source);
char *
104
Exemple
#include <stdio.h>
int main() {
char str[10]; /* PREVOYEZ ASSEZ GRAND ! */
int i; 15 in octal is 17
i = sprintf(str, "%o", 15);
sprintf returns: 2
printf("15 in octal is %s\n", str);
printf("sprintf returns: %d\n\n", i); 15 in decimal is 15
i = sprintf(str, "%d", 15); sprintf returns: 2
printf("15 in decimal is %s\n", str);
printf("sprintf returns: %d\n\n", i);
15 in hex is f
i = sprintf(str, "%x", 15); sprintf returns: 1
printf("15 in hex is %s\n", str);
printf("sprintf returns: %d\n\n", i);
i = sprintf(str, "%f", 15.05);
15.05 as a string is
printf("15.05 as a string is %s\n", str); 15.050000
printf("sprintf returns: %d\n\n", i); sprintf returns: 9
return 0;
}
105
sscanf
● Conversion d'une chaîne de caractères en
différents formats
● 3 arguments
● Retourne le nombre d'objets convertis
● sscanf(a_convertir, "%d", &nbre_dest);
Chaîne à convertir
Adresse mémoire pour
format mettre le résultat
106
Exemple
#include <stdio.h>
int main() {
char* ints = "20, 40, 60"; char* floats = "10.4, 24.66";
char* hex = "FF, F"; n: 20
int i; int n; float f; int h; char* s; sscanff returns: 1
i = sscanf(ints, "%d", &n);
printf("n: %d\n", n); printf("sscanff returns: %d\n\n", i); f: 10.400000
sscanff returns: 1
i = sscanf(floats, "%f", &f);
printf("f: %f\n", f); printf("sscanff returns: %d\n\n", i);
h: 255
i = sscanf(hex, "%x", &h);
printf("h: %d\n", h); printf("sscanff returns: %d\n\n", i); sscanff returns: 1
return 0;
107 }
Exemple
#include <stdio.h>
int main() {
111
#include <stdio.h>
#include <stdlib.h>
int main(void){
char s1[20]; char s2[20];
int comp ;
printf("chaine 1 ?\n");
scanf ("%s",&s1);
printf("chaine 2 ?\n");
scanf("%s",&s2);
comp = strcmp(s1,s2);
if (comp < 0)
printf("%s < %s",s1,s2);
else
if (comp > 0)
printf("%s > %s",s1,s2);
else printf("%s == %s",s1,s2);
printf(“\n”);
return 0;
112 }
malloc et free
● Allocation dynamique de mémoire pendant
l'exécution
● stdlib.h
● Complétez le programme pour permettre de
réserver un espace mémoire suffisant pour la
saisie des notes des étudiants en langage C.
113
#include <stdio.h>
#include <stdlib.h> /* pour malloc et free */
int main() {
int n;
int *ptr;
int i;
...
}
114
#include <stdio.h>
#include <stdlib.h> /* pour malloc et free */
int main() {
int n;
int *ptr;
int i;
if(ptr!=NULL) {
for(i=0 ; i<n ; i++) {
printf(“note de l\'etudiant %d ?\n”,i+1);
scanf(“%d”,(ptr+i));
}
printf(“\n”);
free(ptr); /* liberation de la memoire allouee */
return 0;
}
else {
printf("\nEchec allocation – pas assez de memoire.\n");
return 1;
}
115 }
Debuggage
● Gdb. Option -g à la compilation
● gcc -o prog prog.c -Wall -ansi -g gdb prog
● break main break 12 points d'arrêt
● run
● next : on passe à la suite sans entrer dans le
code des fonctions
● step : on passe à la suite en entrant dans le code
des fonctions
● display i : affichage de la valeur de la variable i
116
Exemple
117
(gdb) help
List of classes of commands: