Académique Documents
Professionnel Documents
Culture Documents
et Langage C
Linformatique
Phelma/PET
1re anne : les objectifs
Matriser le dveloppement de logiciels
Apprendre la Programmation structure
Connaitre quelques Structures de donnes et Algorithmes
3
Le matriel
350 K de matriel rseau
Rseau entirement redondant
Cur de rseau et quipements principaux onduls
800 PCs : 1M de serveurs et PCs
1 Petaoctet de stockage
Stockage accessible depuis tous les postes clients
12 Serveurs :
Messagerie
Web
Authentification centralis (Ldap, radius)
Base de donnes
NFS (partage de disque)
Monitoring 24/24 7/7 des serveurs et quipements rseaux
4
Les ressources par
etudiants
5
Les sites utiles
http://tdinfo-pet.phelma.grenoble-inp.fr
Infos sur les TDs dinformatique (sujet, docs, etc)
Help@phelma.grenoble-inp.fr
Pour tout problme li linformatique
7
Un explorateur de fichiers:
8
Lancer un explorateur
internet :
9
Un explorateur internet :
10
Le mail
11
Le mail
12
Lancer un terminal
13
Le shell
Le shell est linterprteur de vos commandes.
14
Systme de fichiers
Le systme de fichiers est une arborescence de dossiers o vous
stockez tous vos fichiers et dossiers
Le dossier racine est le dossier root : /
Dans chaque dossier on peut crer dautres dossiers ou des fichiers
Les dossiers sont protgs contre les autres utilisateurs
15
Unix : commandes
man : permet de comprendre le fonctionnement dune commande
Donne accs galement aux informations des fonctions C standard. Appuyer sur q pour
quitter man
pwd : Permet de savoir dans quel rpertoire on se situe
(pas dargument)
cd : Permet de se dplacer dans un autre rpertoire
(ex : de tdinfo, cd ~/../tdinfo/user1
ls : Permet de lister le contenu dun rpertoire
(ex., ls, ls l, ls la, pour les options voir le man)
mkdir : permet de crer un rpertoire
(ex., mkdir td0, mkdir ~/tdinfo)
rmdir : permet de supprimer un rpertoire (il doit tre vide)
(ex., rmdir td0, rmdir /users/phelma/phelma2008/users1/tdinfo/td0)
cp : permet de copier un ou plusieurs fichiers
(ex., cp file1.txt ../../test, cp ../tdinfo/td0/file1.txt .)
mv : permet de dplacer ou renommer un ou plusieurs fichiers
(ex., mv file1.txt file1Old.txt, mv file1.txt ../../tdinfo/td1)
rm : permet deffacer un ou plusieurs fichiers ou rpertoires
(ex., rm file1.txt, rm r dir1, rm rf dir1)
quota : permet de connatre son utilisation despace disque 16
Unix : tester cette liste
pwd
ls l
cd tdinfo
mkdir td0
ls -l
cd td0
ls -l
cp /users/prog1a/C/librairie/td0.c td0.c
ls -l
less td0.c
cd ..
pwd
ls -l
rmdir td0
cd td0
ls -l
rm *
ls -l
cd ..
rmdir td0
17
Rpertoires
Chaque utilisateur dispose dun espace de travail ou home directory
Grce des protocoles de partage de fichiers rseaux, ce rpertoire est
accessible de tous les postes clients.
Par dfaut la connexion on tombe dans sa home dir
Pour retourner dans sa home dir, on peut utiliser la commande : cd ~
Tout rpertoire ou fichier peut tre dsign par rapport sa home dir :
~/tdinfo/td0
~/../users1/projet/td0
Tout rpertoire ou fichier peut tre dsign par rapport la racine: cest le
chemin absolu
/users/phelma/phelma2011/monlogin/tdinfo/td0
Tout rpertoire ou fichier peut tre dsign par rapport lendroit o lon
est : cest le chemin relatif
/users/phelma/phelma2011/monlogin/tdinfo/td0
18
Chemin relatif
Exemples :
Si on est dans le rpertoire absolu : /users/phelma/phelma2008/user1
Pour dsigner le rpertoire : /users/phelma/phelma2008/user1/tdinfo/td0
19
Comment crer un
programme
Un programme
indique la machine ce quelle doit faire
succession doctets (8 bits) qui sont des commandes
reconnues par le processeur
Il faut
Un cahier des charges
Analyse du problme
Codage en langage informatique : Matlab, Java, C, assembleur
Traduction en langage binaire : compilation et edition des liens
20
Exemple
Cahier des charges
Faire un programme qui calcule linverse dun nombre
21
Exemple
22
Exemple
Executer le programme
bash-3.00$ ./prog1
Entrer un nombre au clavier
3
Linverse de 3 est : 0.333333
23
Un diteur de texte
Un editeur est un programme qui sert taper, modifier, sauver du
texte dans un fichier
24
Un diteur de texte : gedit
Espace o vous
tapez votre
programme
25
Un diteur de texte : gedit
26
pouilly:~/Documents/ens/1AERG/2008/ex desvignes$ od -A n -t x
p1
Pourquoi compiler
feedface 00000012 00000000 00000002
0000000b 00000530 00000085 00000001
00000038 5f5f5041 47455a45 524f0000
00000000 00000000 00001000 00000000
00000000 00000000 00000000 00000000
00000004 00000001 0000018c 5f5f5445
58540000 00000000 00000000 00001000
00002000 00000000 00002000 00000007
Voici le code binaire de laddition de deux 00000005 00000005 00000000 5f5f7465
78740000 00000000 00000000 5f5f5445
nombres. 58540000 00000000 00000000 000023ac
00000988 000013ac 00000002 00000000
Cest un programme qui met 5 dans i, 8 dans j 00000000 80000400 00000000 00000000
et i+j dans k. 5f5f7069 6373796d 626f6c5f 73747562
5f5f5445 58540000 00000000 00000000
Taille du programme binaire : 16904 octets 00002d34 00000000 00001d34 00000002
Facile, non !!!! 00000000
00000024
00000000
5f5f7379
80000008
6d626f6c
00000000
5f737475
62000000 5f5f5445 58540000 00000000
00000000 00002d34 00000000 00001d34
On utilise des langages plus proches de nous 00000002 00000000 00000000 80000008
00000000 00000014 5f5f7069 6373796d
626f6c73 74756231 5f5f5445 58540000
00000000 00000000 00002d40 00000160
00001d40 00000005 00000000 00000000
80000408 00000000 00000020 5f5f6373
7472696e 67000000 00000000 5f5f5445
58540000 00000000 00000000 00002ea0
00000130 00001ea0 00000002 00000000
00000000 00000002 00000000 00000000
00000001 0000018c 5f5f4441 54410000
00000000 00000000 00003000 00001000
00002000 00001000 00000007 00000003
00000005 00000000 5f5f6461 74610000
00000000 00000000 5f5f4441 54410000
00000000 00000000 00003000 00000014
00002000 00000002 00000000 00000000
27
Assembleur
.section __TEXT,__text,regular,pure_instructions
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.machine ppc
.text
.align 2
.globl _main
_main:
stmw r30,-8(r1)
stwu r1,-64(r1)
mr r30,r1
li r0,5 // Mettre 5 dans le registre r0
stw r0,32(r30) // stocker r0 dans i (adresse r30+32)
li r0,8 // Mettre 8 dans le registre r0
stw r0,28(r30) // stocker r0 dans j (adresse r30+28)
lwz r2,32(r30) // Charger i (adresse r30+32) dans r2
lwz r0,28(r30) // Charger j (adresse r30+28) dans r0
add r0,r2,r0 // Additionner r0 et r2 dans r0
stw r0,24(r30) // stocker r0 dans k (adresse r30+24)
lwz r1,0(r1)
lmw r30,-8(r1)
blr
.subsections_via_symbols
28
En C
#include <stdio.h>
main()
{ int i,j,k;
i=5;
j=8;
k = i+j;
}
Question 1: Quest ce que vous prfrez crire ?
29
La chaine de compilation
Dans la pratique, un programme peut etre constitu de plusieurs millions de
lignes de code et de plusieurs centaines de fichiers
Comment construit-on un programme dans ce cas ?
Exemple : un programme ralisant le produit de (i+2) par la racine carr de
j.
La somme i+2 est ralise par une fonction f, qui est crite dans le fichier
f1.c
La racine carr de j est ralise par une fonction g, qui est crite dans le
fichier f2.c
Le programme principal, qui calcule f(i)*g(j) se trouve dans le fichier p1.c
On veut construire le programme qui affiche le rsultat.
30
La chane de compilation
p1.c f1.c f2.c
main() {int i,j,k; int f(int a) {int x; int g(int a) { int y;
i=5; j=8; x=a+2; y= sqrt(a);
k=f(i)*g(j); return x; return y;
printf("%d",k); } }
}
Etape 1 :Traduction du C
gcc -c p1.c gcc -c f1.c gcc -c f2.c en langage machine
binaire par Preprocesseur
+Compilation
p1.o f1.o f2.o
_main... _f... _g...
libC.a
gcc -o monprog p1.o f1.o f2.o -lm _printf
32
Dveloppement logiciel
Cahier des charges
Cycle
Saisie du code l'aide d'un diteur (gnration des fichiers .c et .h)
Compilation :
correction des erreurs de syntaxe
Excution, tests unitaires et dbogage :
correction des erreurs de logique en modifiant le code
Tests de validation
33
A vous de jouer
34
Programme, E/S, variables
Structures de controle
Structure dun programme
Le programme excute les instructions squentiellement, les unes apres les autres en commenant
la fonction main
Une instruction est un ordre/commande que le processeur sait executer : par exemple, faire une
addition, aller un autre endroit dans le programme, etc
On commence par dclarer quels sont les variables et les types de donnes utiles: on peut
manipuler des entiers, des rels, etc
37
Exemple
38
Lessentiel
Pour manipuler des nombres, il faut pouvoir les stocker dans des
variables.
39
Types de nombre
Entier
char : Octet : 1 octet compris entre -128 et +127
int : Entier (1 mot machine)
short : entier Court
long : entier Long
long long : entier Long
unsigned int : entier Non Signe
unsigned long : entier Long Non Signe
short int <= int <= long int
Rels
float : Rel flottant Simple Prcision (4 octets) :
double : Rel flottant Double Prcision (8 octets)
long double : Rel flottant quadruple Prcision (16 octets)
PAS de booleens
FAUX = 0 VRAI = NON ZERO
40
Notion de variable
Adresse Mmoire
Objet informatique permettant de conserver et de
modifier sa valeur 0
Un type : entier, rel, etc
1
Un nom
2
Une adresse : o est elle ? un entier qui est le numro
de la case mmoire o elle se trouve
Sa dure de vie (ou porte) : de lendroit o elle est
dclare la fin du bloc : } &a= 0xbffff26c a=5
Exemple : var1.c
La variable a est cre ladresse 3221221990 en
dcimal, soit 0xbffff26c en hexadcimal
#include <stdio.h>
main() { Cration de a
int a;
a=5;
&a: adresse de a
printf("Bonjour\n");
printf("La valeur de a est %d\n",a);
printf("Ladresse de a est %p\n",&a);
Destruction de a
} 41
Entres/Sorties
Entres/sorties
Oprations permettant la communication
entre le programme et l'extrieur
Unit centrale : egocentrique
Sortie
Exportation d'une valeur vers l'extrieur
(criture) travers un priphrique de
sortie : cran, rseau , fichier, port srie
ou parallle, pipe..
Entre
introduction d'une valeur l'intrieur du
Unit centrale
programme (lecture) travers un
priphrique d'entre : clavier, rseau,
fichier, port srie ou parallle, pipe..
43
Comment afficher : printf
On utilise des fonctions dj crites : il faut inclure un fichier d'entte au
dbut du fichier
#include <stdio.h> Aller la
ligne
Afficher un message :
printf("Mon message\n");
Afficher un nombre :
printf("Mon entier i : %d\n", i );
Un message optionel
%d : le symbole % Le nombre
indique que la lettre afficher
suivante est le type du
nombre afficher 44
printf : exemple
Syntaxe : Affichage d un type de base
int printf(const char * format, variable1, variable2, ...);
45
printf : exemples
Exemple : affiche0.c
#include <stdio.h>
main() { double x; int a;
x = 3.1415927;
a=6;
/* Afficher un message */
printf("Bonjour.\n");
/* Afficher un reel avec 6 chiffres dont 2 apres la virgule */
printf("Pi vaut %6.2lf\n",x);
/* Afficher plusieurs nombres entier ou reels */
46
printf : le pige
Erreur sur le type des
nombres afficher
Exemple : affiche0a.c
a est un entier, le
#include <stdio.h>
format demand (%lf)
main() { double x; int a;
est celui des rels
x = 3.1415927;
idem pour x
a=6;
==>
/* Afficher un message */
le programme est
printf("Bonjour.\n");
syntaxiquement correct,
printf("Le nombre a : %lf \n", a);
la compilation est correcte,
printf("Le nombre x : %d \n", x);
mais lexecution du
}
programme, lAFFICHAGE sera
incohrent
47
Lire au clavier: scanf
On utilise des fonctions dj crites : il faut inclure un fichier d'entte au
dbut du fichier
#include "stdio.h" ATTENTION au
symbole &
48
scanf : exemple
Syntaxe : lecture d un type de base
int scanf(const char * format, adresse_variable1, ...);
format : %[*][largeur] [.precision] [modif type] type_carac
Exemple : lecture0.c
#include <stdio.h>
main() { double x; int a;
/* Afficher un message pour demander les nombres a lutilisateur*/
printf("Entrer un nombre reel \n");
/* Il faut taper un reel au clavier */
scanf("%lf", &x);
/* Afficher un reel avec 6 chiffres dont 2 apres la virgule */
printf("La variable x vaut : %6.2lf\n",x);
printf("Entrer un nombre entier \n");
/* Il faut taper un entier au clavier */
scanf("%d", &a);
/* Afficher un entier */
printf("La variable a vaut : %d\n",a);
}
49
scanf : lire plusieurs
nombres en une fois
Exemple : lecture1.c
#include <stdio.h>
main() { double x,y; int a;
/* Afficher un message pour demander les nombres a lutilisateur*/
printf("Entrer un nombre entier puis 2 reel\n");
/* lire un nombre entier puis 2 reels */
51
Exos:
54
Conditionnelle : if
Une instruction conditionnelle simple
permet de raliser une ou plusieurs
actions selon un test sur une expression
Syntaxe
if ( expression ) instruction1;
[ else instruction2; ]
Signification
SI expression est vraie ( != 0 ) , instruction1 est excute
sinon instruction2 est excute
#include <stdio.h>
main() { int a,b;
printf("Entrer 2 entiers\n");
scanf("%d %d",&a,&b);
if (a>b)
printf("a:%d est plus grand que b%d\n",a,b);
else
printf("b:%d est plus grand que a%d\n",b,a);
printf( "Fin du programme\n");
}
56
Exemple
57
Exemple 2
Exemple : if2.c : on calcule en plus la diffrence absolue entre les 2 nombres
Les clauses if et else comportent plusieurs instructions DANS un bloc
#include <math.h>
#include <stdio.h>
main() { int a,b,c;
printf("Entrer 2 entiers\n"); scanf("%d %d",&a,&b);
if (a>b) {
c=a-b; Plusieurs instructions :
printf("a:%d est plus grand que b:%d\n",a,b); il faut un bloc entre { }
}
else {
c=b-a;
printf("b:%d est plus grand que a:%d\n",b,a);
}
printf("la racine carree de la difference absolue vaut %lf\n",sqrt(c));
}
58
Un pige
Exemple : if3.c : on teste si 2 nombres sont gaux
Attention :
loprateur = affecte la valeur de droite dans la variable de gauche
loprateur == teste si les 2 expressions sont gales
59
Structure conditionnelle
multiple
Une instruction conditionnelle multiple
permet de raliser une ou plusieurs
actions selon un ou plusieurs tests
squentiels sur une expression
positionner d'abord les cas les plus
courants (raliss le plus rapidement)
Syntaxe
switch ( expression ) {
case constante1 : instructionS1;
case constante2 : instructionS2;
..
[ default : instructionS; ]
}
/* Fin du switch */
60
Menu
Exemple 2 : switch2.c
main() { char i; int cout;
printf ( "Au menu : \n") ;
printf ( "\t 1 : Vin rouge\n ") ;
printf ( "\t 2 : Vin blanc \n ") ;
printf ( "\t 3 : Biere \n ") ;
printf ( "\t 4 : Eau\n ") ;
printf ( "\t 5 : Rien \n ") ;
printf ( "Tapez votre choix ") ;
i= getchar(); /* Lecture clavier de la reponse = scanf("%c",&i);*/
printf("Vous avez choisi :");
switch ( i) {
case 1' : printf("un rouge"); cout=100; break;
case 2' : printf("un blanc"); cout=60; break; Quitte le cas 1 et
case 3' : printf("une biere"); cout=80; break; passe la fin du
case 4' : printf("de leau"); cout=10; break; switch
case 5' : printf("pas soif"); cout=0; break;
default : printf("Choix non valide"); cout=0; break;
}
printf(" pour un cout de %d\n",cout);
} 61
Structure rptitive
Une instruction rptitive est une construction permettant de rpter en
squence une ou plusieurs actions selon un test d'arrt donn.
2 instructions
tant que test_vrai rpter instructions;
On vrifie dabord quon a le droit de faire les instructions, et on execute instructions
tant que le test est vrai.
62
Structure rptitive : do ..
while
Faire au moins une fois qqchose
Syntaxe
do {instructions;} while (expression);
instruction est excute tant que lexpression est vraie ( != 0 ) ,
64
Structure rptitive : for
Boucle FOR Que font ces deux exemples ?
instruction rptitive la plus courante
Exemple1 : for1.c
localise les parties en les dissociant du
main() {
reste du code :
initialisation (expr1),
int i;
test d'arrt de la boucle (expr2) for (i=0; i < 100; i++)
passage l'itration suivante (expr3) printf("%d ",i);
ne ncessite pas de connatre l'avance printf("\n");
le nombre d itrations }
Syntaxe
for(exp1; exp2; exp3;) instruction;
Exemple2 : for2.c
main() { int i; char c=a;
Identique puts("taper votre texte, finir par q");
expr1; for (i=0; c!=q'; i++) {
while ( expr2 ) { /* Lecture dun caractre */
instruction; c=getchar();
(expr3);
printf("caractere lu : %c\n",c);
}
}
printf("La valeur de i est %d\n",i);
65
}
Rupture de squence
Instruction continue
Passe litration suivante dune boucle
Instruction break
Quitte une boucle ou un switch
Instruction exit ( n )
Sortie d'un programme et retour au systme d'exploitation. La valeur de retour est n
66
Exo
69
Nombres entiers
1 octet : 8 bits
unsigned char : Nombres non signs : 0.. 255=28-1
char : Nombres signs : bit 7 = bit de signe : -128=-27..127=27-1
2 octets : 16 bits
unsigned short : Nombres non signs : 0.. 65535=216-1
short : Nombres signs : bit 15 = bit de signe : -32768=-215..32767=215-1
4 octets : 32 bits
unsigned long : Nombres non signs : 0.. 4294967296=232-1
long : Nombres signs : bit 31 = bit de signe
: -21474836488=-231..21474836487=231-1
8 octets : 64 bits
unsigned long long : Nombres non signs : 0.. 18446744073709551615 =264-1
long : Nombres signs : bit 63 = bit de signe
: -9223372036854775808=-263.. 9223372036854775808 =263-1
72
Calcul flottant : exemple
Exemple : /* Fichier cunu2.c*/
Ajouter un reel 1 pour visualiser lerreur de calcul
#include <stdio.h>
main() { float x,y;
printf("Entrer le nombre reel a ajouter a 1 "); scanf("%f",&x);
y = 1/ ( (1+x) - 1);
printf("Valeur de x:%.15f et de 1+x:%.15f\n",x,1+x);
printf("Valeur de 1+x-1:%.15f et de y:%.15f\n",(1+x)-1,y);
}
Valeur de y exacte 10-5 pres
Troncature car x
est trop petit Valeur de y inexacte 73
Calcul flottant : exemple
Cumul des erreurs et non associativit
74
Reprsentation des
Caractres : code skis
75
Code ascii
units
Dizaines
76
Caractres : code ascii
char : 1 octet main() { char x;
x =65;
La valeur stocke est toujours 8 bits printf(decimal:%d ,x);printf(char %c \n,x);
binaire putchar(x); puts();
Seule la manire dont le
programmeur regarde cet octet x = x + 2;
printf(decimal: %d ,x);printf(char %c \n,x);
modifie la perception dont nous la
voyon
x = A;
printf(decimal: %d ,x);printf(char %c \n,x);
puts("Entrer un caractre");
x = getchar(); /* ou scanf((%c,&x);*/
printf(decimal: %d ,x);printf(char %c \n,x);
putchar(x); puts();
}
.
Adresse de x : oxbffff24f 67
65
65
101
77
Oprateurs
Oprateurs Associativit
() [] -> . gauche droite
! ~ ++ -- + - * & (type) sizeof droite gauche
* / %(modulo) gauche droite
+- gauche droite
<< >> : dcalage de bits gauche droite
< <= > >= gauche droite
== != gauche droite
& : ET bit bit gauche droite
^ : Et exclusif bit bit gauche droite
| : OU bit bit gauche droite
&& : ET logique gauche droite
|| : OU logique gauche droite
?: droite gauche
= += -= *= /= %= ^= |= <<= >>= droite gauche
, gauche droite
78
Tableaux
Tableaux
Adresse 0
Tableaux
Collection de variables de mme type, ranges continment
en mmoire
Dclaration : spcifier
le type des lments
le nom du tableau tab tab[0]: 0 &tab[0]
le nombre des lments
Exemples : tab[1]: 2 &tab[1]
float c[100]; /* tableau de 100 rels */
tab[2]: 4 &tab[2]
int tab[10]; /* tableau de 10 entiers*/
Exemple : tab1.c
main() { int i; tab[9]: 18 &tab[9]
int tab[10]; /* Tableau de 10 entiers */
float c[20]; /* Tableau de 20 rels */
for (i=0; i<10; i++) tab[i]= 2*i;
/*Mettre 0,2,4,6..dans les elements*/
for (i=0; i<10; i++) printf("%d ",tab[i]);
/* afficher les lments de t */
} 80
Tableaux
81
Tableaux 2
Adresse
0
Remarques
Nombre dlments constant, non modifiable
Le nom du tableau est son adresse (ie lendroit o il se trouve &tab[-2]
en mmoire
82
Tableaux 3
Adresse 0
Exemple 2 : tab2.c
main() { int i; int tab[10];
for (i=0; i<10; i++) tab[i]= 2*i;
puts("Voici les elements : ");
0xbffff37c &tab[-2]
/* afficher les lments de t */
for (i=0; i<5; i++) printf("%d ",tab[i]);
puts(""); puts("Voici les adresses : "); 0xbffff384 0 &tab[0]
/* afficher les adresses */ 2 &tab[1]
0xbffff388
for (i=0; i<5; i++) printf("%p ",tab+i);
puts(""); 0xbffff38c 4 &tab[2]
tab[-2]= 18952;
printf("%d ",tab[900]);
} 18 &tab[9]
0xbffff3a8
0xc0000194 &tab[900]
83
Tableaux 4
Attention : AUCUNE opration globale sur un tableau
les oprations et les E/S doivent se faire lment par lment
En particulier
T1==T2 ne teste pas lgalit de 2 tableaux
T1=T2 ne recopie pas les lments de T1 dans T2
Exemples : tab3.c
main() {int i; double t1[10], t2[10];
/* t1 et t2 sont 2 tableaux de 10 rels */
for (i=0; i<10; i++) {t1[i]=2*i; t2[i]=log(100*i+1); }
printf("Emplacement de t1:%p de t2:%p\n",t1,t2);
printf("Emplacement de t1[1]:%p de t2[1]:%p\n",t1+1,t2+1);
printf("Valeur de t1[0]:%lf de t2[0]:%lf\n",t1[0],t2[0]);
if (t1==t2) printf("t1 et t2 sont au meme endroit\n");
else printf("t1 et t2 ne sont pas au meme endroit\n");
for (i=0; i<10; i++) t2[i]= t1[i];
/*Copie de t2 dans t1: on peut remplacer cette ligne par:
memcpy(t2,t1,sizeof(t1));
Mais on ne peut pas utiliser t1=t2; */
for (i=0; i<10; i++) printf(Valeur de t2[%d] : %lf\n,i,t1[i]);
} 84
Tableaux 5
Adresse
0
0xbffff328 0 &t2[0]
0xbffff330 2
4.6 &t2[1]
4
5.3 &t2[2]
0xbffff370 18
6.8 &t2[9]
0xbffff378 0 &t1[0]
0xbffff380 2 &t1[1]
4 &t1[2]
0xbffff3c0 18 &t1[9]
85
Tableaux 6
Les fonctions travaillant sur les zones mmoires : comme un tableau est
une zone mmoire continue, on peut utiliser ces fonctions avec les tableaux
#include <string.h>
int memcmp (const void *s1, const void *s2, size_t n);
compare les n premiers octets des zones mmoire s1 et s2.
Faire un programme qui cre 3 tableaux de 10 rels, ajoute les 2 premiers tableaux dans le
troisime et affiche ce dernier tableau
Faire un programme qui recherche la valeur la plus petite dun tableau et qui laffiche
Faire un programme qui fait la somme de tous les lments dun tableau
Fonctions
Fonctions
Fonctions
Une fonction est une unit de traitement dans un programme
Une fonction prend en entre des donnes et renvoie des rsultats aprs avoir ralis
diffrentes actions
89
Utiliser une fonction
Dclarer le prototype
Le prototype dune fonction indique comment doit tre utilise une fonction. Il comporte le nom, la
liste des paramtres et la valeur de retour suivi dun ";"
L 'appel ou lexecution de la fonction se fait avec les paramtres effectifs par
nom_fonction(paramtres);
Exemple
90
Ecrire une fonction
Une fonction est constitue de
Son nom
Sa liste de paramtres sils existent
Son type de valeur de retour
Des instructions indiquant ce quelle doit faire
La valeur de retour
Est unique et scalaire : par exemple, une fonction ne peut pas renvoyer 2 rels
est renvoye laide de linstruction " return " : on quitte la fonction IMMEDIATEMENT, on
revient la fonction qui a appele
0xbffff3b4 20 b
int max(int a, int b) {
if (a>b) return a;
else return b;
0xbffff3d8 10 i
}
0xbffff3dc 20 j
main() {int i,j,k; i=10; j=20; k=0;
20
0 k
printf("i:%d j:%d\n",i,j);
k=max(i,j);
printf("i:%d j:%d \n",i,j,);
}
92
Passage par valeur
Lorsquune fonction est appele, elle travaille avec une copie des paramtres effectifs
: une fonction ne peut jamais modifier les paramtres quon lui donne
i (a est une copie de i) ne peut etre modifi
Exemples : f3.c : fonction qui calcule le produit de 2 nombres
void mult1(int a, int b) {
printf("Valeur de a:%d et b:%d au debut de la fonction\n",a,b);
printf("Adresse de a:%p et b:%d au debut de la fonction\n",&a,&b);
a = a * b;
printf("Valeur de a:%d et b:%d en fin de fonction\n",a,b);
}/* Erreur, car a ne sera pas modifi */
Exemples : f4.c
int mult2(int a, int b) { int c;
c = a * b;
return c;
}
95
Variable locales
Lors de lappel mult2(i,j) : Les parametres sont copis sur Adresse 0
la pile (zone mmoire particulire) en commencant par le
plus droite, soit j en premier.
On execute alors mult
a et b sont des copies de k et l
la variable c est cre sur la pile 0xbffff3b0 10 a
La fonction mult utilise alors a et b b
la variable c est dtruite lorsque la fonction se termine 0xbffff3b4 20
a et b sont dtruites quand la fonction se termine
On revient ensuite la fonction appelante (ici main)
1852
200
i et j ne sont pas modifies c de mult2
99
Exos
Faire une fonction qui renvoie le produit de 3 nombres rels passs en paramtres
Faire une fonction qui calcule la factorielle dun nombre pass en un paramtre
Pointeurs
Pointeurs
Pointeurs
Variable contenant ladresse dun autre objet (variable ou fonction)
Adresse : numro dune case mmoire
ATTENTION : un pointeur doit toujours tre initialis avant dtre utilis = Il doit contenir
une adresse lgale :
soit celle dun objet existant
soit celle obtenu par une demande dallocation dynamique
soit NULL, qui est la valeur 0. Il est interdit de lire et crire l'adresse 0
103
Oprations sur pointeurs
Affectation : donner une valeur au pointeur, celle dune adresse lgitime.
p1=&i; /* &i : l'adresse de i */
Comparaison :
== et != : p1==p2; p1 et p2 regardent ils la meme adresse ?
<, >, <=, >= : par exemple, p1<p2 sur un meme tableau, p1 est il avant p2
Arithmtique
Adresse + entier ==> adresse : p1 +1 est ladresse de llment suivant p1
Adresse - Adresse ==> entier : p2 -p1 est donc le nombre dlments entre les adresses contenues dans
p2 et p1. Valide uniquement si p1 et p2 sont de meme type.
ATTENTION : les pointeurs tant typs, les oprations se font en nombre dlments et
non en nombre doctets
104
Adresse et tableaux
Nom du tableau : adresse du tableau
Consquences
Llment t[i] s crit aussi *(t+i)
Ladresse de t[i] scrit &t[i] ou bien (t+i)
105
Adresses et tableaux
Adresse 0
Exemple : p3.c
main() { int tab[10]; int i;
for (i=0; i<10; i++) tab[i]= 2*i;
puts("Voici lelement dindice 2 : ");
printf("%d %d",tab[2],*(tab+2));
puts(""); puts("Voici les adresses : ");
for (i=0; i<5; i++) 0xbffff364 0 &tab[0]
printf("%p %p",tab+i, &tab[i]); 0xbffff368 2 &tab[1]
}
0xbffff36c 4 &tab[2]
2 manires diffrentes d'ecrire l'adresse de t[i]
0xbffff388 18 &tab[9]
106
Parcourir un tableau avec
un pointeur
Adresse 0
Exemple : p4.c
main() {int* p=NULL; int i; int tab[5];
for (i=0; i<5; i++) tab[i]=2*i+1; 0xbffff384 1
tab[0]=234 &tab[0]
p=tab; 3 &tab[1]
0xbffff388 tab[1]=234
while (p<tab+5) {
printf(" Pointeur: %p ",,p); 0xbffff38c tab[2]=234
5 &tab[2]
printf(" Valeur %d",*p); 7
tab[3]=234 &tab[3]
0xbffff390
*p=234;
0xbffff394 tab[4]=234
9 &tab[4]
printf("Valeur modifiee %d\n",*p);
p++; 0xbffff398 i= 5 &i
} &p
0xbffff39c 0xbffff394
0xbffff384
0xbffff388
p=
0xbffff38c
0xbffff390
0
107
Les chaines de caractres
Les chanes de caractres
En C, les chanes de caractres ne sont pas un type particulier
mais sont :
Des tableaux de char, exemple : char t[256];
Termins par \0. Adresse
0
109
Les chanes de caractres
Exemple : chaine1.c : cre et lit 2 chaines au clavier avec 2 methodes
main() { int i;
char s1[256], s2[256];
puts("Entrer une chaine");
110
Les chanes de caractres
Les chanes de caractres sont des tableaux
112
Chanes de caractres
Comparaison de 2 chanes Formation/extraction dans des chaines
int strcmp (char* chain1, char* chain2) de caractres
int sprintf(char* s, char* format, valeurs)
Retourne : int sscanf(char* s, char* format, adresses)
un entier ngatif si chain1 infrieure
chain2 main() { char t1[256], t2[256];
0 si chain1 identique chain2 int i; float x; double y;
un entier positif si chain1 suprieure
chain2
sprintf(t1,"Valeurs %d et %f et %lf", i,x,y);
ordre lexicographique. puts(t1);
int strcasecmp (char* chain1, char* chain2) strcpy(t1,"1000 10.3 truc 3.14259");
sscanf(t1,"%d %f %s %lf ",&i,&x,t2,&y);
majuscules et minuscules indiffrentes
113
Chanes de caractres
Longueur d'une chane
unsigned strlen ( char* chaine)
114
Chanes de caractres
Dcoupage dune chaine en mots
Char* strtok(char* str, char* separateur)
Dcoupe la chaine str en mots.
Les sparateurs sont dfinis par les caractres de la chaine separateur.
#include <stdio.h>
#include <string.h>
main() { char t1[256], t2[256];
char* p; int i =0;
/* Les separateurs sont espace, virgule, point et point virgule et d'interrogation */
strcpy(t2, " ;.,.");
strcpy(t1,"Voici une chaine. Vide? Non");
/*Iniitalisation du decoupage */
p=strtok(t1, " ;.,.");
while (p!=NULL) {
printf("mot numero %d : %s \n",i,p);
i++;
/* On cherche le mot suivant */
p= strtok(NULL, " ;.,.");
}
}
115
Exos
Ex1 : faire un programme qui calcule la somme des lments d'un tableau
en utilisant uniquement des indices pointeurs (et pas entiers)
Ex2 : faire un programme qui copie un tableau de N entiers (N=10) dans un
autre tableau en utilisant uniquement des indices pointeurs
Ex3 : faire un programme qui lit les lments d'un tableau au clavier en
utilisant uniquement des indices pointeurs (et pas entiers)
Ex4: faire un programme qui lit une chaine de caractres au clavier, puis
calcule la longueur de la chaine (le dernier caractre est \0)
116
Paramtres de fonctions
En C, passage des variables par valeur
Il y a recopie de l'objet effectif (de x et y ci dessous) sur la pile
La fonction travaille sur une copie des objets effectifs (a et b sont des copies de x et de y)
Si la fonction modifie le paramtre formel (a et b), c'est en fait la copie de l'objet effectif qui est modifie
L'objet initial n'est pas modifi (x et y ne change pas)
Exemple : swap1.c
void swap(int a, int b) { int c;
printf( "Debut de swap a:%d ; b:%d . Adresses de a:%p et b:%p\n",a,b,&a,&b);
c=a; a=b; b=c; /* On echange a et b en utilisant c */
printf( "Fin de swap a:%d ; b:%d . Adresses de a:%p et b:%p\n",a,b,&a,&b);
}
main() { int x,y;
x=1; y=2;
printf("Avant swap x:%d de y:%d et des adresses de x:%p et y:%p\n",x,y,&x,&y);
swap(x,y);
printf("Apres swap : x:%d et y:%d . Adresses de x:%p et y:%p\n",x,y,&x,&y);
}
117
Paramtres de fonctions
Adresse 0
Que valent x et y ?
0xbffff3d8 2 y
0xbffff3dc 1 x
118
Passage par adresse
Comment une fonction peut modifier un paramtre ?
En passant son adresse
Ladresse nest pas modifie
Mais le contenu (obtenu par loprateur *) peut tre modifi
pa et pb sont des adresses de
Exemple : swap2.c variables existantes changer.
Ici, ce seront les adresses de x et y.
void swap2(int* pa, int* pb) { int c; Donc,*pa est la meme chose que x
printf("Debut de swap2: pa:%p ; pb:%p ", pa,pb);
printf("Contenu de pa :%d et pb:%d\n",*pa,*pb);
printf("Adresse de pa :%p et pb:%p\n",&pa,&pb);
c=*pa; *pa=*pb; *pb=c; /* On echange a et b en utilisant c */
printf("Fin de swap2: pa:%p ; pb:%p ", pa,pb);
printf("Contenu de pa :%d et pb:%d\n",*pa,*pb);
}
main() { int x,y;
x=1; y=2;
printf("Avant swap2 x:%d de y:%d et des adresses de x:%p et y:%p\n",x,y,&x,&y);
swap2(&x,&y);
printf("Apres swap2 : x:%d et y:%d . Adresses de x:%p et y:%p\n",x,y,&x,&y);
}
On passe les adresses de x et y
119
Passage par adresse
Adresse 0
0xbffff35c 0
1 c
0xbffff3dc 1
2 x
120
En pratique
Comment sait on quune fonction doit modifier ses paramtres ?
Dfinissez et crivez correctement le rle de la fonction
Exemple 1: la fonction change les valeurs de 2 entiers
==> la fonction a 2 paramtres et elle doit modifier la valeur de ces 2 paramtres
==> ces 2 paramtres doivent tre passs par adresse
Si vous avez crit une fonction avec des paramtres passs par valeur, par
exemple le paramtre a, et que vous souhaitez la transformer pour passer le
paramtre a par adresse
Il suffit de
remplacer dans la fonction a par *a, en prenant garde la priorit des oprateurs
A lappel de la fonction, remplacer la valeur du paramtre par son adresse laide de
loprateur &.
121
Exos
Ex1 : faire une fonction qui prend un double en paramtre et met ce
paramtre la valeur 3.14159. Faire le programme principal qui appelle
cette fonction.
Ex2 : faire une fonction qui prend 2 entiers en paramtres, ajoute un au
premier et soustrait un au second. Faire le programme qui appelle cette
fonction
Ex3 : Ecrire une fonction swap2 qui effectue un echange de 2 variables
Ex4: Ecrire une fonction swap3 qui effectue une permutation circulaire de
trois variables en utilisant la fonction swap2
Ex5 : faire une fonction qui recopie une chaine de caractres dans une autre
chaine.
Ex6 : Donner le prototype de la fonction qui rsoudrait lquation du second
degr dans R
122
Structures
Structures, dfinition de
types
Crer ses propres types
Pourquoi ?
Clarifier l'criture dun programme
Exemple :
jaime pas les int*
je veux indiquer clairement quune variable est un octet et pas un caractre
Dfinir un nouveau type : instruction typedef
124
Crer ses propres types
typedef unsigned char OCTET;
typedef int* POINTEUR;
125
Les structures
Regroupement dinformations de types identiques
ou diffrents struct complex {
Relatif une mme entit abstraite. double im,re;
permet de manipuler sous un mme nom plusieurs };
lments d'informations
struct complex a1;
Exemple :
Un point : une structure comportant les deux
coordonnes X et Y du point
Nom du
Un complexe : les parties relle et imaginaire du
type
complexe.
un etat civil : une structure regroupant le nom, Nom de la
prnom, nSS, age.... variable
Dclaration de type
a1 a1.re
struct ident1 {
type nom_du_champ; a1.im
....
} /* fin de structure */
Dfinition de variable :
struct nomdestructure identif_var; 126
Structures (2)
Un lment chimique avec les informations de type diffrent:
X x.nom
struct element_atomique {
char nom[20] ;
char symbole[4] ;
int nummeroatomique;
double masseatomique;
double densite ;
double fusion ; /* Temperature de fusion en */ x.symbole
double vap; /* Temperature de vaporisation en */
double rayon; /* rayon atomique en A */
x.numeroat
double rayon_cov; /* rayon de covalence en A */
char rayonionique[24] ; /* Rayon ionique */ x.masseato
} x;
x.densit
Le type sappelle
struct element_atomique
127
Structure (3)
Accs un champ
Pour une variable structure :oprateur .
Pour une structure pointe : oprateur ->
0xbffff38c a2.x 0 a2
Oprations sur les structures : aucune sauf
Affectation de structures meme type a2.y -
1
Passage et retour de structures par valeur dans les fonctions 0xbffff394 0xbffff398 pa1
Les lments de la structure sont des variables part
0xbffff398 a1.x 1
0
entire : ils ont une adresse
a1.y - a1
130
Champ de bits
Dcouper les octets en tranche de bits
Gestion des bits sur un octet ou un mot
machine Fichier : champbit.c
utilis en particulier en SE, les tables de #include <stdio.h>
drapeaux (flag), etc...
main() {
chaque groupe de bits a un rle diffrent
struct{unsigned char
alignement et champ cheval sur des mots:
dpend des compilateurs (options)
i:2,j:1,k:4,l:1;} x; /* X est sur
un octet */
Acces aux adresses des champs interdit
Syntaxe :
struct { x.i=2; x.j=1; x.k=10; x.l=0;
type ident:nombre de bits du champ; } /* x=10110100 en binaire ou b4 en hexa
*/
i i j k k k k l
printf("Acces aux champs i=%d j=%d
k=%d l=%d\n",x.i,x.j,x.k,x.l);
struct{unsigned char i:2,j:1,k:4,l:1} x;
x.i {0..3}, x.j {0..1}, printf("acces a l'octet complet : %d
%x \n",x,x);
x.k {0..15}, x.l {0..1}
x=127;
}
131
Union
Unions : accs une mme zone Exemple : union.c : Un short et un
mmoire selon des types diffrents tableau de 2 octet et 2 octet
Exemple : voir un entier 16 bits comme main() { int i;
2x8 bits union REG {
unsigned short ax;
unsigned char t[2];
union ident { struct {unsigned char ah,al; } x; };
type1 identificateur1; union REG r;
type2 identificateur2; };
r.ax= 0x5621;
printf("AX: %x\n",r.ax);
gestion par le programmeur printf("t[0]:%x t[1]:%x\n",r.t[0],r.t[1]);
printf("AH:%x AL:%x\n",r.x.ah,r.x.al);
taille de l'union : taille du plus grand type
r.t[0]= r.t[1]=0;
printf("AX: %x\n",r.ax);
r.t[0] printf("t[0]:%x t[1]:%x\n",r.t[0],r.t[1]);
r.x.al printf("AH: %x AL: %x\n",r.x.ah,r.x.al);
r.x r.x.al=1; r.x.ah=1;
r
printf("AX: %x\n",r.ax);
r.t[1] r.x.al=0x0f; r.x.ah=0xf0;
r.x.al printf("AX: %x\n",r.ax);
}
132
Structure (Exos)
Dfinir une structure reprsentant une matire (Math, physique). Une matire est dfinie par son
nom (mathematique), son coeffficient, son volume horaire et son code (bijection entre une
matire et son code)
Dfinir une structure reprsentant une note, qui contient une valeur et le code correspondant une
matire
Comment dfinir une variable qui est un tableau de notes, une variable qui est le tableau des
matires disponibles.
Faire une fonction qui affiche les noms des matires et la note correspondante partir du tableau de
notes dun lve et du tableau des matires
Faire une fonction qui calcule la moyenne des notes dun lve partir dun tableau de notes et du
tableau des matires
133
Fichiers et Entres / Sortie
Fichiers, Flots
Qu'est ce qu'un fichier : un ensemble d'informations stocks sur un support permanent
(disque dur, cl usb, bande ...)
fichiers sources en C, document word, programmes, DLL, etc...
A quoi servent les fichiers ?
Conserver des rsultats et des donnes
stocker les programmes
Appliquer un traitement toutes les donnes dun fichier
Eviter de taper toutes les donnes utiles un programme
Etc
136
Texte (n1.txt) ou binaire
(n1.bin)
138
Dfinition, ouverture,
fermeture de flots
Inclure le fichier dentete
#include <stdio.h>
Dfinition d'une variable f de type FILE* : Descripteur de flot
FILE* f;
Ouverture de fichier
FILE * fopen(char * nomdefichier, char *moded_ouverture)
cration des zones mmoire et initialisation des variables ncessaire
mode ouverture = "r","w","a", "r+","w+","a+" suivi de "t"ou"b"
r : lecture seule
w: ecriture. Ouverture en dbut de fichier ou cration "Efface" l'ancien contenu
a: ajout en fin de fichier ou cration
r+: lecture/ecriture d'un fichier existant
w+: Cration en lecture/ecriture : Efface" l'ancien contenu
a+ : ouverture en lecture/ecriture , positionnement en fin de fichier ou cration
t : fichier texte
b : fichier binaire (Attention aux caractres de contrle comme la fin de fichier si b n'est pas prcis)
Fermeture dun flot
int fclose(FILE* leflotafermer)
139
Dfinition, ouverture,
fermeture
#include <stdio.h>
#include <errno.h> /* pour utiliser la fonction perror */
140
Lecture de fichiers texte
int fscanf(FILE *f, char* control, adresse des arg) ;
142
Exemple
Lecture des nombres dans un fichier et ecriture des valeurs+1 dans un autre fichier
#include <stdio.h>
main() { FILE* f1; FILE* f2; double x;
/* Ouverture des deux fichiers en lecture ou ecriture */
if ( (f1=fopen("n1.txt","r")) ==NULL) return (1);
if ( (f2=fopen("n2.txt","w")) ==NULL) return (1);
while ( fscanf(f1,"%lf",&x) == 1)
/* tant que la lecture d'un nombre reel x est reussie dans n1.txt */
fprintf(f2,"%lf\n",x+1);
/* Ecriture de x+1 dans le nouveau fichier n2.txt */
fclose(f1); fclose(f2);
}
143
Fichiers binaires (1)
Fichier binaire : copie de la reprsentation mmoire de la variable dans un fichier
Tous les objets de mme type ont la mme taille
1 int = 4 octets, 1 double = 8 octets, ....
Accs direct un lment possible
Tous les objets du fichier ayant la meme taille,
on sait calculer la position du i ime objet par rapport au dbut du fichier
Dpend de la machine et du SE
Big Indian/ Little Indian pour les entiers
Norme IEEE pour les flottants (Cray)
Fichiers de donnes binaires non compatibles
Pas de marque de fin de lignes/ fichiers
145
Fichiers binaires (3)
Exemple : lecture de n1.bin (5 entiers) et ecriture de x+1 dans n2.bin
main() { FILE* f1, *f2; int i; On lit les 5 entiers en 1 seule opration,
int t[5];
mais il faut que t puisse contenir ces 5 entiers
f1=fopen("n1.bin","rb");
f2=fopen("n2.bin","wb");
if (fread(t,sizeof(*t),5,f1) <5) /* Lecture des 5 entiers */
printf("Impossible de lire 5 entiers");
else { for (i=0;i<5;i++) t[i]=t[i]+1; /* on ecrit aussi t[i]++; */
if (fwrite(t,sizeof(*t),5,f2) <5) /* ecriture des 5 entiers */
printf("Impossible d'ecrire 5 entiers");
} On ecrit les 5 entiers en 1 seule opration
fclose(f1); fclose(f2);
}
146
Fichiers binaires (4)
Positionnement dans un fichier binaire
int fseek(FILE *fp, int offset, int from);
Positionne la prochaine lecture/ecriture offset octets de
from (0:debut, 2:fin ou 1:position actuelle) du fichier
Debut du
Exemple : fichier5.c fichier
main() { FILE* fp; int a; int t[5];
/* Lecture ET ecriture */ 1
fp=fopen("Fichier_a_lire","r+b");
fseek(fp,2*sizeof(*t),0); 127
/* On se positionne sur le
65536
16785
3ime rel dans le file*/
a=16785; 123456789
if (fwrite(&a,sizeof(*t),1,fp) <1)
65537
printf("Impossible d'ecrire");
/* On revient au debut du fichier */
fseek(fp,0,0);
/* Lecture et affichage des nombres */
while (fread(&a,sizeof(a),1,fp) ==1)
printf("%d ",a);
puts("");
} 147
Fichiers Exos
Ecrire un programme qui affiche lecran le contenu du fichier texte f.c
Ecrire un programme qui compte les lignes dun fichier texte dont on lit le nom au
clavier
Ecrire un programme qui compte les entiers stocks dans un fichier binaire ne
contenant que des entiers
Ecrire un programme qui affiche lecran le contenu dun fichier binaire. Ce fichier
contient des lments comprenant un entier, un rel double prcision et une chane
de 32 caractres.
Ecrire un programme qui affiche lecran le contenu du ime lement du fichier
binaire prcdent.
Ecrire un programme qui remplace le contenu du ime lement du fichier binaire
prcdent par llment contenant 0,0.0,
Ecrire un programme qui transforme tous les octets dun fichier texte donnees.txt
en leur ajoutant une valeur constante a.
-
148
Allocation dynamique
Allocation dynamique ?
Exemple : le format dimage PPM contient le magic number P5 sur la premire ligne, puis
le nombre de lignes et de colonnes de limage, puis toutes les donnes de limage
Comment crer une matrice dont la taille est lue et connue quand on execute le
programme et inconnue quand on crit le code C ?
150
Allocation dynamique ?
Que faire quand on ne connat pas la dimension dun tableau que lon doit utiliser
lorsque lon crit le programme
Solution 1 : crer le plus grand tableau possible, et utiliser la partie dont on a besoin quand on
excute le programme
Le tableau est cr la compilation, il a toujours la meme taille
Solution 2 ; crer le tableau lorsque lon connat sa taille, cest dire pendant lexcution du
programme : cest lallocation dynamique
Le tableau a juste la bonne taille, cette taille est diffrente selon les excutions
151
Exemple
Exemple : alloc0.c
main() { int i=0, dim=0; Cration dun tableau de dim rels
double* t1=NULL; double* p=NULL;
Attention : cest le type de t1 (double*)
printf("Donner la dimension voulue ");
qui dtermine la nature des lments,
scanf("%d",&dim);
et non la fonction calloc
t1=calloc(dim, sizeof(*t1));
On peut maintenant utiliser
for (i=0; i<dim; i++) t1[i]=2*i+1; indiffremment les notations
for (i=0; i<dim; i++) printf("%lf ",*(t1+i)); t[i] et *(t+i) et meme *p
for (p=t1; p<t1+dim; p++) printf("%lf ",*p);
Le tableau est devenu inutile :
free(t1);
on libre la mmoire alloue
152
Exemple
Exemple : alloc0.c Adresse 0
main() { int i=0, dim=0;
double* t=NULL;
printf("Donner la dimension voulue ");
scanf("%d",&dim);
printf("t:%p et adresse t1%p\n",t,&t);
t=calloc(dim, sizeof(*t)); 0x100160 0
1 &t[0]
printf("t:%p et adresse t1%p\n",t,&t);
0x100168 0
3 &t[1]
for (i=0; i<dim; i++) t[i]=2*i+1;
for (i=0; i<dim; i++) printf("%lf ",t[i]);
free(t);
}
0xbffff3d4 0x100160
0 &t
0xbffff3d8 0
2 &dim
0xbffff3dc 0 &i
153
Mmoire et allocation
Intrt de lallocation dynamique
Dimension inconnue lors de la conception du
Text : code du
programme programme
Donnes de grande taille
Donnes de taille variables : tableaux, listes, Data: variables
globales
initialises
155
Matrices
Tableau multi dimensions Adresse
0
157
Tableau multi dimensions
Adresse
0
Comment le compilateur traduit t[i][j] dun tableau int t[2][3];
on dmarre au dbut du tableau (ladresse du premier lment) : cest
t
on saute i lignes (chaque ligne contient 3 lments), on a alors
ladresse de la ligne i : cest t+3*i 0xbffff3c0 0 &t[0][0]
on saute les j premiers lments de cette ligne : on a ladresse de
llment dindice i et j : cest t+3*i +j 0xbffff3c4 1 &t[0][1]
On utilise loprateur dindirection * 0xbffff3c8 2 &t[0][2]
Soit *( (int* )t+3*i+j) et cest t[i][j]
0xbffff3cc 1 &t[1][0]
Conclusion : on a besoin de connatre le nombre de colonnes
pour trouver un lment du tableau 0xbffff3d0 0
2 &t[1][1]
0xbffff3d4 3 &t[1][2]
Quaffiche le programme suivant
main() { int i,j; int t[2][3];
for (i=0; i<2; i++) for (j=0; j<3; j++) t[i][j]=i+j;
printf("\nAdresse du tableau %p \n",t);
printf("\nAdresse des lignes du tableau \n");
for (i=0; i<2; i++) printf("%p %p",&t[i], t+i);
printf("\nAdresse des elements du tableau \n");
for (i=0; i<2; i++) for(j=0;j<3;j++) printf("%p ",&t[i][j]);
158
}
Fonction et tableau nD
Les paramtres de fonctions qui sont des tableaux de N dimensions doivent prciser
N-1 dimensions dans le prototype et lentte de fonction
Exemple Prciser le nombre de lignes nest pas utile
#include <stdio.h> Prciser le nombre de colonnes est INDISPENSABLE
#define N_COL 5 Et cest une constante
init_tab(mon_tab,3);
init_tab(tab2,3); INTERDIT pour tab2
for (ligne=0; ligne<3; ligne++) { qui a NB_COL+1 colonnes
for (colonne=0; colonne<N_COL; colonne++)
printf("%d ",mon_tab[ligne][colonne]);
printf("\n");
}
}
159
Tableau nD
Ces tableaux sont peu utiliss, car , pour des matrices 2D par exemple
160
Matrice 2D dynamique
T[0][0]
T:adresse
de tableau T[0]:adress T[0][1]
e ligne 0
...
T[1]:adress
e ligne1 T[0][m-1]
... T[1][0]
T[i]:adresse T[1][1]
ligne i
..
Construction dynamique dune matrice d'entiers de n .
lignes et m colonnes ..
T[n-1][m-1]
161
Matrice 2D dynamique
T[0][0]
T:adresse
Comment se retrouve un lment t[i][j] de tableau T[0]:adress T[0][1]
e ligne 0
t[i] ou bien *(t+i) contient ladresse de la ligne i ...
T[1]:adress
t[i]+j ou bien (*(t+i)+j) contient donc ladresse T[0][m-1]
e ligne1
de llment dindice i,j
*(t[i]+j) ou bien *(*(t+i)+j) est donc llment
...
t[i][j] T[1][0]
T[i][j]
..
T[n-1][m-1]
162
Matrice 2D
Exemple : alloc4.c
void aff(int **m, int nl, int nc) {
#include <stdio.h>
int i,j;
int ** alloue(int n, int m) { int i,j;
for (i=0; i<nl; i++){
int **p ;
for (j=0;j<nc;j++)
printf("%d " ,m[i][j]);
p=calloc(n,sizeof(*p));
puts("");
if (p==NULL) return NULL;
}
else
}
for (i=0 ; i<n ; i++) {
main() { int a,b,i,j ;
p[i]=calloc(m,sizeof (**p));
int** mat ;
if (p[i]== NULL) return NULL;
puts ("dimension ? ");
}
scanf("%d %d",&a,&b );
return p;
mat= alloue(a,b);
}
for (i=0; i<a; i++)
for (j=0;j<b;j++)
void destructeur(int **p, int n, int m){ mat[i][j]=i+j;
int i; aff(mat,a,b);
for (i=0; i<n; i++) free(p[i]); destructeur(mat,a,b);
free(p); }
}
163
Matrice 2D : plus fort
Toutes les lignes sont alloues en une fois et sont donc
contigues T:adresse de T[0]:adresse
T[0][0]
Il faut calculer les adresses des lignes tableau ligne 0
164
Des lignes de taille
diffrentes
Comment rcuprer les arguments de la ligne de commande UNIX
Le premier paramtre de main (argc) est le nombre de mot, le suivant (argv) est le tableau de ces
mots
Attention :ce sont des chanes de caractres : conversion faire si vous avez des nombres
Main na que 2 versions : sans paramtres ou avec 2 paramtres
Sur le mme principe, on peut faire des matrices avec des lignes de longueur variable
165
Exercices
Comment dclarer un tableau comportant 3 dimensions (128, 256, 256)
Faire une fonction allouant dynamiquement ce tableau
Faire un programme principal utilisant cette fonction
On suppose avoir un fichier texte contenant les titres des livres de la bibliothque de lcole,
raison dun titre par ligne. Il y a 250000 livres, la longueur maximale dun titre est 256octets, la
longueur moyenne 32 octets.
Comment dclarer un tableau t1 (non allou dynamiquement) pouvant contenir ces titres ?
Comment dclarer un tableau t2 (qui sera allou dynamiquement) pouvant contenir ces titres
?
Comparer les tailles qui seront utilises par ces deux versions de tableau.
Faire une fonction ralisant la lecture des titres dans le tableau t2 Cette fonction retournera le
tableau t1.
La fonction fgets(tableau, 256, f1) permet de lire une ligne du fichier f1, et de la stocker
dans le tableau deja cr.
La fonction strcpy(s1,s2) permet la copie de s2 dans s1.
On suppose avoir une fonction int nblivres(char* fichier) qui donne le nombre de livres
contenus dans le fichier.
166