programmation en langage c les...
TRANSCRIPT
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Programmation en langage CLes pointeurs
Alain Chillès – 祁冲
ParisTech Shanghai Jiao Tong上海交大–巴黎高科卓越工程师学院
27 octobre 2015 – 2015年10月27日 – 乙未年九月十六
1
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
2
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Rappel
int i=5;
i 5
Adresse de la variable
Valeur de la variable
3
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Exemple : la fonction scanf
8 i n t n ;9 p r i n t f ( " Donner n : " ) ;
10 s c a n f ( "%d " ,&n ) ;
&n désigne l’adresse de n : il faut connaître l’endroit où ranger lavaleur lue
7 char ch3 [ 6 ] ;8 p r i n t f ( " Taper l a c h a î n e 3 : " ) ;9 s c a n f ( "%s " , ch3 ) ; // On tape ”alain”
ch3 désigne l’adresse du tableau où ranger la chaîne de caractèreslue (ce n’est pas une chaîne de caractères !)
4
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
5
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Déclaration d’un pointeur
1 # inc lude < s t d i o . h>2 char t a b [ ] ; // Pointeur sur UN caractere (DECONSEILLE)3 // Variable globale : Warning4 // Variable locale : ERROR5
6 i n t main ( )7 {8 i n t ∗p ; // Pointeur sur un entier9 char ∗ t a b 2 ; // Pointeur sur un caractere (CONSEILLE)
10 char t a b 3 [ 1 0 ] ; // Pointeur sur un tableau de 10 caracteres11 f l o a t ∗∗q ; // Pointeur sur un pointeur sur un flottant
pointeurs.c 2 warning: array ‘tab’ assumedto have one element [enabled by default]=== Build finished: 0 errors, 1 warnings ===
<type pointé> *<nom du pointeur>;
6
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Déclaration et const
1 i n t main ( )2 { // Avec const, il faut initialiser a la declaration3 i n t i =5 , j =3 ;4 i n t ∗ const p=&i ; // Le pointeur est constant5 const in t ∗q=&i ; // La valeur est constante6 const in t ∗ const r=&i ; // Les deux sont constants7 p=&j ; ∗p= j ; // Impossible, p est constant8 ∗q =7; q=&j ; // Impossible *q est constant9 ∗ r =8 ; r=&j ; // Impossible r et *r sont constants
constpointeurs.c 7 error: assignment ofread-only variable ‘p’constpointeurs.c 8 error: assignment ofread-only location ‘*q’constpointeurs.c 9 error: assignment ofread-only location ‘*r’constpointeurs.c 9 error: assignment ofread-only variable ‘r’
7
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Initialisation d’un pointeur
12 i n t i =5 ;13 p=&i ; // Le pointeur pointe sur la variable i14 ∗p =8; // La valeur de i est a 815 p r i n t f ( " i (∗ p ) v a u t : %d ou %d , \ n \16 l ’ a d r e s s e de i (& i ou p ) v a u t : %p ou %p \ n " ,17 i ,∗ p ,& i , p ) ; // Noter le %p pour un pointeur
i (*p) vaut : 8 ou 8,l’adresse de i (&i ou p) vaut : 0xbff26c68 ou0xbff26c68
8i
&ip
8
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Utilisation d’un pointeur
Adresse ValeurVariable i &i iPointeur p p *p
Donc :On a toujours :
*&i=i
Et de même :&*p=p
9
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Ne pas oublier l’initialisation
1 # inc lude < s t d i o . h>2
3 i n t main ( )4 {5 i n t ∗p ,∗ q ;6 p r i n t f ( "∗p v a u t : %d e t p=%p \ n \7 ∗q v a u t : %d e t q=%p " ,∗p , p ,∗ q , q ) ;8 return ( 0 ) ;9 }
*p vaut : 1723772 et p=0xb7781ff4*q vaut : 465290113 et q=0x8048439
10
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Pour ne pas faire d’erreur
1 # inc lude < s t d i o . h>2
3 i n t main ( )4 {5 i n t ∗p=NULL, i =5 ;6 p r i n t f ( " p v a u t %p \ n " , p ) ;7 p=&i ;8 p r i n t f ( " Main tenan t , p v a u t %p \ n " , p ) ;9 return ( 0 ) ;
10 }
p vaut (nil)Maintenant, p vaut 0xbff20278
11
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
12
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Comparaisons possibles entre pointeurs
Égalité (==)Non égalité (!=)
Ordre (<, <=, > et >=)
13
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Opérations possibles avec les pointeurs
Addition/soustraction avec un entier. Le résultat dépend dutype sur lequel pointe le pointeur !
1 # inc lude < s t d i o . h>2
3 i n t main ( )4 {5 i n t ∗p ,∗ q , i =1 ;6 p=&i ;7 q=p ++;8 p r i n t f ( " P o i n t e u r s s u r des e n t i e r s \ n \9 p v a u t %p e t q v a u t %p \ n " , p , q ) ;
10 long long in t ∗ r ,∗ s , j =1 ;11 r=&j ;12 s= r ++;13 p r i n t f ( " P o i n t e u r s s u r des e n t i e r s t r è s l o n g s \ n \14 r v a u t %p e t s v a u t %p \ n " , r , s ) ;15 return ( 0 ) ;16 }
14
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Addition : résultat
Pointeurs sur des entiersp vaut 0xbff2fc90 et q vaut 0xbff2fc8cPointeurs sur des entiers très longsr vaut 0xbff2fc88 et s vaut 0xbff2fc80
I Pour les entiers, une différence de 4. Pour les longs, longsentiers, une différence de 8.
0xbff 2fc90− 0xbff 2fc8c = 40xbff 2fc88− 0xbff 2fc80 = 8
15
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Opérations possibles avec les pointeurs
On peut donc faire :p+1; p+2; ... ; p-1; p-2; ...p++; p–; ++p; –p;p += 1; p += 2; ... p -= 1; p -= 2; ...p-q; (renvoie un entier)On ne peut par faire :
additions de pointeurs, multiplications, divisions, etc.toute autre opération logique ou arithmétique
16
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
17
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Tableau = pointeur
1 # inc lude < s t d i o . h>2
3 i n t main ( )4 {5 i n t t a b [ 3 ] ,∗ p , i ;6 p= t a b ; // Donc p et tab sont de meme type7 f o r ( i =0 ; i <3 ; i ++)8 p r i n t f ( " i=%d : %d \ n " , i , t a b [ i ]−∗(p+ i ) ) ;9 return ( 0 ) ;
10 }
i=0 : 0i=1 : 0i=2 : 0
Donc :tab[i] = ∗(tab+ i)
18
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Tableau 6= pointeur
1 # inc lude < s t d i o . h>2 # inc lude < s t d l i b . h> // Pour avoir la fonction calloc3
4 i n t main ( )5 {6 i n t ∗p , t a b [ 3 ] = { 0 , 1 , 2 } , i , j ; // Le tableau contient trois elements7 p r i n t f ( " Donner i : " ) ;8 s c a n f ( "%d " ,& i ) ;9 p =( i n t ∗ ) c a l l o c ( i , s i z e o f ( i n t ) ) ;
10 f o r ( j =0 ; j <= i ; j ++)11 p r i n t f ( " p[%d]=%d " , j , p [ j ] ) ;12 return ( 0 ) ;13 }
Donner i : 5p[0]=0 p[1]=0 p[2]=0 p[3]=0 p[4]=0 p[5]=135145
19
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Tableau et pointeur
La tableau est de longueur statiqueAvec de l’allocation dynamique de mémoire on peut, avec unpointeur, obtenir des tableaux de taille dynamique
Il faut utiliser stdlib.h et les fonctions :malloc : réserve de la mémoirecalloc : réserve de la mémoire et l’initialise à 0free : libère de la mémoire
20
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
21
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
À quoi servent les pointeurs ?
Allocation dynamique de mémoirePassage de paramètres modifiablesPassage de paramètres fonctionnelsPolymorphisme
22
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
À quoi servent les pointeurs : modifier les paramètres
1 # inc lude < s t d i o . h>2
3 void ModifyElement ( i n t ∗ ) ; // Prototypage4
5 i n t main ( )6 {7 i n t i =1 ;8 ModifyElement (& i ) ;9 p r i n t f ( " Et m a i n t e n a n t i v a u t : %d " , i ) ;
10 return ( 0 ) ;11 }12
13 void ModifyElement ( i n t ∗e )14 {15 // Parametre : l’element a modifier16 ∗e =2015;17 }
Et maintenant i vaut : 2015
23
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
À quoi servent les pointeurs : changer de fonction
1 # inc lude < s t d i o . h>2
3 i n t i n c r ( i n t n ) { return ( n + 1 ) ; }4
5 i n t d e c r ( i n t n ) { return ( n−1);}6
7 i n t main ( )8 {9 i n t (∗ f ) ( i n t ) ; // Declaration de f
10 f=&i n c r ;11 p r i n t f ( "On o b t i e n t a l o r s %d \ n " , (∗ f ) ( 3 ) ) ;12 f=&d e c r ;13 p r i n t f ( " P u i s %d " , (∗ f ) ( 3 ) ) ;14 return ( 0 ) ;15 }
On obtient alors 4Puis 2
24
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
À quoi servent les pointeurs : polymorphisme
I On a vu plusieurs tris (tri sélection, tri insertion à insertionlinéaire et tri insertion à insertion dichotomique).
Limités aux tableaux d’entiersLimités à ranger de manière croissante
Polymorphisme : essayer de pouvoir changer de type d’objetset d’ordre à utiliserI Nous allons essayer de changer d’ordre !
25
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Rappel : tri sélection
3 5 -1 2 0 2 4
-1 5 3 2 0 2 4
-1 0 3 2 5 2 4
-1 0 2 3 5 2 4
-1 0 2 2 5 3 4
-1 0 2 2 3 5 4
-1 0 2 2 3 4 5
26
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Rappel : tri sélection (1)
1 void t r i s e l e c t i o n ( i n t a [ ] , i n t n )2 {3 void swap ( i n t i , i n t j )4 {5 // Petite fonction interne6 // Echange les elements i et j du tableau7 // Notons que la fonction est locale a triselection8 // et que le tableau a est connue par cette fonction9 i n t aux ;
10 aux=a [ i ] ;11 a [ i ]= a [ j ] ;12 a [ j ]= aux ;13 }14
15 i n t minqueue ( i n t i )16 {17 // Petite fonction interne
27
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Rappel : tri sélection (2)
18 // Calcule l’indice du plus petit element apres a[i]19 i n t j , r e f ;20 r e f = i ;21 f o r ( j = i +1 ; j <n ; j ++)22 i f ( a [ j ] < a [ r e f ] ) r e f = j ;23 return ( r e f ) ;24 }25
26 i n t i ;27 f o r ( i =0 ; i <n ; i ++) // Le tri proprement dit28 swap ( i , minqueue ( i ) ) ;29 }
28
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Nouveau tri avec choix de l’ordre (1)
1 void t r i s e l ( i n t a [ ] , const in t n , i n t (∗ o r d r e ) ( int , i n t ) )2 {3 void swap ( i n t i , i n t j )4 {5 i n t aux ;6 aux=a [ i ] ;7 a [ i ]= a [ j ] ;8 a [ j ]= aux ;9 }
10 i n t minqueue ( i n t i )11 {12 i n t j , r e f ;13 r e f = i ;14 f o r ( j = i +1 ; j <n ; j ++)15 i f ( ( ∗ o r d r e ) ( a [ j ] , a [ r e f ] ) ) r e f = j ;16 return ( r e f ) ;17 }18
19 i n t i ;20 f o r ( i =0 ; i <n ; i ++) // Le tri proprement dit21 swap ( i , minqueue ( i ) ) ;22 } 29
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Nouveau tri avec choix de l’ordre (2)
1 # i f n d e f TRISEL_H_INCLUDED2 # de f ine TRISEL_H_INCLUDED3 void t r i s e l ( i n t [ ] , const int , i n t ( ∗ ) ( int , i n t ) ) ;4 # end i f
1 // Fichier call trisel.c2 # inc lude < s t d i o . h>3 # inc lude " t r i s e l . h "4
5 i n t main ( )6 {7 i n t t a b [8 ]={ −2 ,1 ,0 , −1 ,3 ,4 ,0 ,1} , i ;8
9 i n t p l p t t ( i n t a , i n t b ) { return ( a<b ) ; } ;10 i n t p lgd ( i n t a , i n t b ) { return ( a>b ) ; } ;
30
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Nouveau tri avec choix de l’ordre (3)
12 t r i s e l ( t ab ,8 ,& p l p t t ) ;13 f o r ( i =0 ; i <8 ; i ++)14 p r i n t f ( "%d \ t " , t a b [ i ] ) ;15 t r i s e l ( t ab ,8 ,& p lgd ) ;16 p r i n t f ( " \ n " ) ;17 f o r ( i =0 ; i <8 ; i ++)18 p r i n t f ( "%d \ t " , t a b [ i ] ) ;19 return ( 0 ) ;20 }
-2 -1 0 0 1 1 3 44 3 1 1 0 0 -1 -2
31
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
32
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
33
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Allocation de mémoire
Très utile pour les systèmes d’exploitationVoir Wikipedia
34
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
35
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
36
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Distribuer des cartes (1)
1 # inc lude < s t d i o . h>2 # inc lude < s t d l i b . h>3 # inc lude < t ime . h>4
5 void melange r ( i n t [ ] [ 1 3 ] ) ;6 void d i s t r i b u e r ( const in t [ ] [ 1 3 ] , const char ∗ [ ] ,7 const char ∗ [ ] ) ;8
9 i n t main ( )10 {11 const char ∗ c o u l e u r s [ ] = { " Coeur " , " C a r r e a u " , " P ique " , " T r è f l e " } ;12 const char ∗ c a r t e s [ ] = { " As " , " Deux " , " T r o i s " , " Qu a t r e " , " Cinq " ,13 " S ix " , " Sep t " , " Hu i t " , " Neuf " , " Dix " , " V a l e t " , "Dame" , " Roi " } ;14 i n t j e u [ 4 ] [ 1 3 ] = { 0 } ;15
16 s r a n d ( t ime (NULL ) ) ;17
18 melange r ( j e u ) ;19 d i s t r i b u e r ( j eu , c a r t e s , c o u l e u r s ) ;20 return ( 0 ) ;21 }
37
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Distribuer des cartes (2)
23 void melange r ( i n t p j e u [ ] [ 1 3 ] )24 {25 i n t l i g n e , co lonne , no ;26
27 f o r ( no =1; no <=52; no ++)28 {29 do30 {31 l i g n e = rand ( )%4;32 c o l o n n e = rand ( )%13;33
34 } while ( p j e u [ l i g n e ] [ c o l o n n e ] != 0 ) ;35 p j e u [ l i g n e ] [ c o l o n n e ] = no ;36 } ;37 }
38
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Distribuer des cartes (3)
39 void d i s t r i b u e r ( const in t p j e u [ ] [ 1 3 ] , const char ∗ p c a r t e s [ ] ,40 const char ∗ p c o u l e u r s [ ] )41 {42 i n t l i g n e , co lonne , no ;43
44 f o r ( no =1; no <=52; no ++)45 f o r ( l i g n e =0; l i g n e <4; l i g n e ++)46 f o r ( c o l o n n e =0; co lonne <13; c o l o n n e ++)47 i f ( p j e u [ l i g n e ] [ c o l o n n e ]== no )48 p r i n t f ( "%7s de %−8s%c " ,49 p c a r t e s [ c o l o n n e ] ,50 p c o u l e u r s [ l i g n e ] ,51 no %2 == 0 ? ’ \ n ’ : ’ \ t ’ ) ;52 }
39
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Distribuer des cartes (résultat)
Valet de Carreau Trois de Coeur Dix de Carreau As deCarreau Dame de Carreau Six de Carreau Six de TrèfleDame de Coeur Sept de Pique Huit de Coeur Neuf deCarreau Cinq de Coeur Valet de Trèfle Quatre dePique Sept de Carreau Six de Coeur Huit de TrèfleSept de Coeur Quatre de Trèfle Dix de Pique Neuf dePique Valet de Pique As de Trèfle Roi de Trèfle Huitde Carreau As de Pique Huit de Pique Sept de TrèfleCinq de Pique Deux de Carreau Trois de Trèfle As deCoeur Dame de Pique Trois de Pique Neuf de TrèfleSix de Pique Dix de Trèfle Deux de Pique Valet deCoeur Dame de Trèfle Quatre de Carreau Cinq deCarreau Trois de Carreau Quatre de Coeur Deux deCoeur Dix de Coeur Roi de Coeur Roi de Pique Cinq deTrèfle Roi de Carreau Deux de Trèfle Neuf de Coeur
40
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Plan
Les pointeursDéclaration, initialisation et utilisationComparaisons et opérations sur les pointeursTableaux (et chaînes de caractères)Passages de paramètres et polymorphisme
Utilisation de la mémoire par les systèmes d’exploitationStatique/Dynamique
ExerciceMélange de cartesTri en place, dynamique et polymorphe
41
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Exercice
On veut saisir au clavier un entier n ;générer un tableau aléatoire d’entiers dans [[1, 10]] de taille n ;pouvoir choisir le tri (sélection, insertion, etc.) et l’ordre surles entiers, tout cela au clavier ;et produire le tableau non trié puis le tableau trié.
Le tri se fera en place (sans recopiage du tableau)
42
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Tri sélection
3 5 -1 2 0 2 4
-1 5 3 2 0 2 4
-1 0 3 2 5 2 4
-1 0 2 3 5 2 4
-1 0 2 2 5 3 4
-1 0 2 2 3 5 4
-1 0 2 2 3 4 5
43
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Tri insertion
3 5 -1 2 0 2 4
3 5 -1 2 0 2 4
-1 3 5 2 0 2 4
-1 2 3 5 0 2 4
-1 0 2 3 5 2 4
-1 0 2 2 3 5 4
-1 0 2 2 3 4 5
44
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction de l’exercice
On a 5 fichiers :Le fichier général.Deux fichiers pour le tri-sélection (TriSelection.h etTriSelection.c).Deux fichiers pour le tri-insertion par recherche linéaire(TriInsertion.h et TriInsertion.c).
I L’objectif est d’utiliser des pointeurs sur des fonctions et del’allocation dynamique de mémoire !
45
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction – La fonction principale (1)
1 # inc lude < s t d i o . h> // Pour avoir les fonctions printf et scanf2 # inc lude < s t d l i b . h> // Pour avoir les fonctions malloc et rand3 # inc lude < t ime . h> // Pour initialiser srand4 # inc lude " T r i S e l e c t i o n . h "5 # inc lude " T r i I n s e r t i o n . h "6
7 i n t main ( )8 {9 i n t n ,∗ t ab , i ;
10 p r i n t f ( " Donner l a t a i l l e du t a b l e a u : " ) ;11 s c a n f ( "%d " ,&n ) ;12 // Prevoir la place pour le tableau13 t a b =( i n t ∗ ) m a l l oc ( n∗ s i z e o f ( i n t ) ) ;14 // Initialiser le generateur aleatoire15 // Uniquement apres la mise au point du programme16 s r a n d ( t ime (NULL ) ) ;17 f o r ( i =0 ; i <n ; i ++)18 t a b [ i ]=1+( r and ( ) % 1 0 ) ;
46
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction – La fonction principale (2)
19 // Choisir la methode20 char c ;21 do22 {23 // ATTENTION, il y a des caracteres entres !24 // Il faut vider la zone tampon25 while ( c != ’ \ n ’ )26 c= g e t c h a r ( ) ;27 p r i n t f ( " I n s e r t i o n ( i ) ou s é l e c t i o n ( s ) ? " ) ;28 s c a n f ( "%c " ,&c ) ;29 } while ( ( c != ’ i ’ ) && ( c != ’ s ’ ) ) ;30 void (∗ t r i ) ( i n t a [ ] , const in t l , i n t ( ∗ ) ( int , i n t ) ) ;31 i f ( c== ’ i ’ )32 t r i =& T r i I n s e r t i o n ;33 e l s e34 t r i =& T r i S e l e c t i o n ;
47
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction – La fonction principale (3)
35 // Choix de l’ordre36 do37 {38 while ( c != ’ \ n ’ )39 c= g e t c h a r ( ) ;40 p r i n t f ( " C r o i s s a n t ( <) ou d é c r o i s s a n t ( >) ? " ) ;41 s c a n f ( "%c " ,&c ) ;42 } while ( ( c != ’< ’ ) && ( c != ’> ’ ) ) ;43 // Definitions des ordres44 i n t p l g ( const in t a , const in t b )45 {46 return ( a<b ) ;47 } ;48 i n t p p t t ( const in t a , const in t b )49 {50 return ( a>b ) ;51 } ;
48
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction – La fonction principale (4)
53 i n t (∗ mon_ordre ) ( const int , const in t ) ;54 i f ( c== ’< ’ )55 mon_ordre=&p l g ;56 e l s e57 mon_ordre=&p p t t ;58 // Tri proprement dit59 p r i n t f ( " Le t a b l e a u i n i t i a l v a u t : \ n " ) ;60 f o r ( i =0 ; i <n ; i ++)61 p r i n t f ( "%d " , t a b [ i ] ) ;62 // On appelle le tout avec les bons parametres !63 (∗ t r i ) ( t ab , n ,∗ mon_ordre ) ;64 p r i n t f ( " \ nLe t a b l e a u t r i é v a u t : \ n " ) ;65 f o r ( i =0 ; i <n ; i ++)66 p r i n t f ( "%d " , t a b [ i ] ) ;67 return ( 0 ) ;68 }
49
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction – Le tri-sélection (1)
1 # i f n d e f TRISELECTION_H2 # de f ine TRISELECTION_H3 void T r i S e l e c t i o n ( i n t [ ] , const int , i n t ( ∗ ) ( int , i n t ) ) ;4 # end i f
1 // Fichier TriSelection.c2 void T r i S e l e c t i o n ( i n t a [ ] , const in t l , i n t (∗ o r d r e ) ( int , i n t ) )3 {4 void swap ( const in t i , const in t j )5 {6 i n t aux=a [ i ] ;7 a [ i ]= a [ j ] ;8 a [ j ]= aux ;9 }
50
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction – Le tri-sélection (2)
11 i n t minqueue ( const in t i )12 {13 i n t j , r e f ;14 r e f = i ;15 f o r ( j = i +1 ; j < l ; j ++)16 i f ( ( ∗ o r d r e ) ( a [ j ] , a [ r e f ] ) ) r e f = j ;17 return ( r e f ) ;18 }19
20 i n t i ;21 f o r ( i =0 ; i < l ; i ++) // Le tri proprement dit22 swap ( i , minqueue ( i ) ) ;23 }
51
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction – Le tri-insertion (1)
1 # i f n d e f TRIINSERTION_H2 # de f ine TRIINSERTION_H3 void T r i I n s e r t i o n ( i n t [ ] , const int , i n t ( ∗ ) ( int , i n t ) ) ;4 # end i f
1 // Fichier TriInsertion.c2 void T r i I n s e r t i o n ( i n t a [ ] , const in t l , i n t (∗ o r d r e ) ( int , i n t ) )3 {4 void swap ( const in t i , const in t j )5 {6 i n t aux=a [ i ] ;7 a [ i ]= a [ j ] ;8 a [ j ]= aux ;9 }
52
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction – Le tri-insertion (2)
11 void p l a c e ( const in t i )12 {13 i n t aux=a [ i ] , j ;14 f o r ( j = i −1;( j >=0) && ( ( ∗ o r d r e ) ( aux , a [ j ] ) ) ; j −−)15 swap ( j +1 , j ) ;16 }17
18 i n t i ;19 f o r ( i =1 ; i < l ; i ++)20 p l a c e ( i ) ;21 }
53
C
Forth
Lisp
Pascal
Prolog
C++
Fortran
JavaPython
APL
Ada
Correction – Un exemple d’exécution
Donner la taille du tableau : 15Insertion (i) ou sélection (s) ? iCroissant (<) ou décroissant (>) ? >Le tableau initial vaut :8 5 3 10 5 1 6 10 9 2 10 5 5 3 6Le tableau trié vaut :10 10 10 9 8 6 6 5 5 5 5 3 3 2 1
54