Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Exercices C

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 25

Travaux Dirigés de langage C - DUT 1ere année

c
Copyright Jean-François Mari
Chapitre 1

Syntaxe de base

1.1 Test d’un générateur de nombre aléatoire

La bibliothèque standard du langage C offre au programmeur plusieurs fonctions pour


générer des nombres aléatoires. La plus connue est rand(). Vous allez écrire un programme
verifrand.c qui estime la répartition des nombres aléatoires générés : moyenne et variance.
Générez 1 million (NBTIRAGE) notes (xi ) entre 0 et 20 (N) comprises (NB_NOTE = 21) à
l’aide de la fonction rand(). Répartissez-les dans le tableau effectif (int n[NB_NOTE]) où
n[xi ] représente l’effectif (nombre d’occurrences cumulées) de la note xi .
1 PN
– calculez et affichez la moyenne arithmétique : moy = N BT IRAGE i ∗ n[i] ;
1 PN 0 2
– calculez et affichez la variance de la série : var = N BT IRAGE k=0 k ∗ n[k] − moy 2

1.2 Conjugaison d’un verbe régulier du premier groupe

Ecrire un programme C qui lit au clavier un verbe régulier du premier groupe, le vérifie
(terminaison en er) et le conjugue au présent de l’indicatif sans utiliser de boucle puis en
utilisant une boucle et les tableaux de chaı̂nes à deux dimensions.

1.3 Participe présent des verbes du deuxième groupe

Les verbes du deuxième groupe sont les verbes en -ir dont le participe présent est en
-issant. ex : bondir > bondissant.
Ecrire en C la fonction void partPres(char verbe2[], char pp[]) qui prend dans
verbe2 un verbe du deuxième groupe et lui calcule son participe présent dans pp.

1
2 Chapitre 1. Syntaxe de base

1.4 Evaluer les expressions suivantes

En supposant

A=20 B=5 C=-10 D=2 X=12 Y=15

Calculez la valeur des expressions suivantes et les nouvelles valeurs des variables dont le
contenu a changé. Faites le calcul sans utiliser l’ordinateur puis véfifier le sur votre machine.

(1) (5*X)+2*((3*B)+4)
(2) (5*(X+2)*3)*(B+4)
(3) A == (B=5)
(4) A += (X+5)
(5) A != (C *= (-D))
(6) A *= C+(X-D)
(7) A %= D++
(8) A %= ++D
(9) (X++)*(A+C)
(10) A = X*(B<C)+Y*!(B<C)
(11) !(X-D+C)||D
(12) A&&B||!0&&C&&!D
(13) ((A&&B)||(!0&&C))&&!D
(14) ((A&&B)||!0)&&(C&&(!D))

solutions sur http ://www.ltam.lu/cours-c/homesol.htm ou sur votre machine.

1.5 Utilisation de l’instruction switch

Ecrire un programme C qui lit un nombre hexadécimal sur 2 chiffres et écrit sa valeur à
l’écran. Utiliser l’instruction scanf("%c%c", &c1, &c2); et les déclarations char c1,c2;.

1.6 Conversions de chaı̂nes en nombres

1.6.1 Exercice

Ecrire un programme main() qui lit une chaı̂ne de caractères pris entre ’0’ et ’9’ et
imprime leur somme.
1.6. Conversions de chaı̂nes en nombres 3

./ex
89
17
./ex
32
5

1.6.2 Exercice

Ecrire une procédure qui lit une chaı̂ne de caractères pris entre ’0’ et ’9’ et l’interprète
comme un entier positif dans la base décimale. Pour la conversion, utiliser les fonctions de
<ctype> 1 et la relation d’ordre alphabétique des caractères ’0’ à ’9’. Mémoriser le résultat
dans une variable du type long. La conversion s’arrête à la rencontre du premier caractère
qui ne représente pas de chiffre décimal. Utiliser un indicateur logique OK qui précise si la
chaı̂ne représente correctement une valeur entière et positive.

1.6.3 Exercice

Ecrire une procédure qui lit une chaı̂ne de caractères et l’interprète comme un entier
positif dans la base hexadécimale. Pour la conversion, utiliser la fonction isdigit() de
<ctype> et la précédence alphabétique des caractères. La conversion ignore les caractères qui
ne représentent pas de chiffre hexadécimal et s’arrête à la fin de la chaı̂ne de caractères. Le
résultat sera mémorisé dans une variable du type long et affiché dans les bases hexadécimale
et décimale.

1.6.4 Le cas de nombres réels

On considère la fonction suivante qui convertit une chaı̂ne C de caractères (par exemple
char t[] = ‘‘123’’ ;) dans une variable numérique (par exemple int x ;).

#include <stdio.h>
#include <stdlib.h>
int ascInt(char t[])
/* conversion chaine -> valeur */
{
char cx ;
int i = 0 ;
1. taper “ctype” sur un moteur de recherche
4 Chapitre 1. Syntaxe de base

int x = 0 ;
cx = t[0] ;
while (cx != ’\0’) {
if (cx <= ’9’ && cx >= ’0’) x = x * 10 + (cx - ’0’) ;
i++ ;
cx = t[i] ;
}
return x ;
}

Sur la base de cette fonction, écrire en C la fonction float ascFloat(char t[]) qui conver-
tit une chaı̂ne C (par exemple char t[] = ‘‘123.45’’ ;) dans une variable numérique (par
exemple float x ;). Les chaı̂nes peuvent (ou non) avoir des parties décimales et entières,
par exemple : ‘‘123.45’’, ‘‘123’’, ‘‘123.’’, ‘‘.45’’.

1.6.5 Conversion d’un nombre en chaı̂ne

Sans utiliser de fonctions de la bibliothèque C, écrire la fonction

int itoa(int val, char* s, int maxLen)

qui convertit la valeur val en une chaı̂ne de caractères s en notation hexadécimale. Par
exemple la valeur 123, dans val donne la chaı̂ne “7B” dans s. Le paramètre maxLen donne
la taille disponible dans s (cf. Tab. 1.1). Si la conversion est possible, la fonction retourne 0
sinon 1. Effectuez des divisions successives par 16 et transformez les restes – entre 0 et 15 –
en un caractère correspondant grâce au tableau char n2c[] = "0123456789ABCDEF" ;.

1.7 Tableaux à plusieurs dimensions

Attention aux déclarations ! le langage C manipule très mal les tableaux à plusieurs
dimensions car celles-ci ne font pas partie de la représentation du tableau. En particulier,
il est très lourd de passer une matrice en paramètre d’une fonction.

1.7.1 Multiplication de matrices

En multipliant une matrice A de dimensions N et M avec une matrice B de dimensions


M et P on obtient une matrice C de dimensions N et P : A(N,M) * B(M,P) = C(N,P)
1.7. Tableaux à plusieurs dimensions 5

i n t main ( )
{
c h a r buf1 [ 8 0 ] , buf2 [ 2 ] ;
i n t n = 1023 ;

i t o a ( n , buf1 , 8 0 ) ;
p r i n t f (”% s \n ” , buf1 ) ; /∗ imprime 3FF s u r une l i g n e ∗/

i f ( i t o a ( n , buf2 , 2 ) == 0 )
p r i n t f (”% s \n ” , buf2 ) ; /∗ n e v e r g e t t h e r e ∗/
else
p r i n t f ( ” c o n v e r s i o n i m p o s s i b l e \n ” ) ; /∗ imprime c o n v e r s i o n i m p o s s i b l e ∗/
return 0 ;
}

Table 1.1 – Deux appels de itoa

La multiplication de deux matrices se fait en multipliant les composantes des deux


matrices lignes par colonnes :
M
X
cij = aik ∗ bkj
k=1

Rappel :

   
a b c   a∗p+b∗r+c∗t a∗q+b∗s+c∗u
p q
 e ∗ p + f ∗ r + g ∗ t e ∗ q + f ∗ s + g ∗ u
e f g   
 ∗ r s  = 
  
h∗p+i∗r +j ∗t h∗q +i∗s+j ∗u
 
h i j 
t u
k l m k∗p+l∗r+m∗t k∗q+l∗s+m∗u
Ecrire un programme qui effectue la multiplication de deux matrices A et B. Le résultat de
la multiplication sera mémorisé dans une troisième matrice C qui sera ensuite affichée.
Refaire ce programme sous forme d’une fonction qui admet les matrices et leurs dimen-
sions en paramètres. Les matrices sont de tailles quelconques mais compatibles.
Application : prendre
! !
cos θ sin θ cos θ
A= , B=
− sin θ cos θ sin θ
!
1
On doit trouver, pour n’importe quelle valeur de θ, C =
0
6 Chapitre 1. Syntaxe de base

1.7.2 Révisions

Ecrire un programme qui vérifie la validité d’un numéro de CCP entré au clavier. Un
numéro de CCP est composé de trois parties : un numéro de compte, un séparateur ’-’ et
un numéro de contrôle. Un numéro de CCP est correct :
– si le reste de la division entière de la valeur devant le séparateur ’-’ par 97 est différent
de zéro et égal à la valeur de contrôle ;
– si le reste de la division par 97 est zéro et la valeur de contrôle est 97.
Exemples : On entre au clavier les chaı̂nes suivantes
– CCP 15742-28 : 15742 modulo 97 = 28 correct
– CCP 72270-5 : 72270 modulo 97 = 5 correct
– CCP 22610-10 : 22610 modulo 97 = 9 incorrect
– CCP 50537-0 : 50537 modulo 97 = 0 nombre incorrect, car la valeur de contrôle
devrait être 97.
– CCP 50537-97 : 50537 modulo 97 = 0 correct
Ecrivez et utiliser une fonction ccptest() qui obtient comme paramètres les deux parties
numériques d’un nombre de CCP et qui affiche alors un message indiquant si le numéro de
CCP est valide ou non.
Chapitre 2

Les Pointeurs

Un pointeur est une variable qui contient une référence (sous forme d’une adresse en
mémoire) à une autre variable.

2.1 Exercice

Soit P un pointeur qui ’pointe’ sur un tableau A :

int A[] = {12, 23, 34, 45, 56, 67, 78, 89, 90};
int *P;
P = A;

Quelles valeurs ou adresses fournissent ces expressions ? Faites l’exercice dans un premier
temps sans machine puis vérifiez vos résultats grâce à un programme C qui imprime les
valeurs des expressions. Quand l’expression est une adresse (par ex. &i) , imprimez la valeur
de la variable référencée (par ex. *(&i)) et comparez (par ex. à i).
1. *P+2
2. *(P+2)
3. &P+1
4. &A[4]-3
5. A+3
6. &A[7]-P
7. P+(*P-10)
8. *(P+*(P+8)-A[7])

7
8 Chapitre 2. Les Pointeurs

2.2 Exercice
– Quelles sont les valeurs des variables a et t après l’exécution du programme ci-dessous
(Tab. 2.1) ?

1 i n t main ( )
2 {
3 int t [ 2 ] ;
4 i n t a , ∗b , ∗ c ;
5 t [0] = 3 ;
6 t [1] = 5 ;
7 a = 10 ;
8 b = t ;
9 c = &a ;
10 ∗ c = ∗b ;
11 a++ ;
12 b++ ;
13 ∗b = 2 ∗ a ;
14 }

Table 2.1 – Quelles sont les valeurs de a et t à la fin de l’exécution de ce programme ?

– Simuler l’exécution de ce programme (cf. Tab. 2.2) :

1 #include < s t d i o . h>


2 i n t main ( )
3 {
4 int a ;
5 i n t ∗x , ∗ y ;
6
7 a = 90;
8 x = &a ;
9 p r i n t f ( ” ∗x = %d\n” , ∗x ) ;
10
11 ∗x = 1 0 0 ;
12 p r i n t f ( ”a vaut : %d\n” , a) ;
13
14 y = x;
15 ∗y = 8 0 ;
16 p r i n t f ( ”a vaut : %d\n” , a) ;
17
18 return 0 ;
19 }

Table 2.2 – Remarquez comment a est modifiée par le biais des pointeurs x et y

– Qu’imprime le programme suivant (cf. Tab. 2.3) ?

2.3 Fonction qui calcule plusieurs résultats

Ecrire une fonction void minmax (int i, int j, ...) qui calcule le minimum et le
max de i et j. Utilisez un passage de paramètres par adresse. Testez minmax() dans un
programme principal.
2.4. Tableau de compteurs 9

1 #include < s t d i o . h>


2 #include < s t d l i b . h>
3 #include < s t r i n g . h>
4 i n t main ( )
5 {
6 char ∗ m e s s a g e ;
7 char ∗dm [ 3 ] ;
8 m e s s a g e = ( char ∗ ) m a l l o c ( 3 5 ) ;
9 s t r c p y ( message , ” B e l l e Marquise , v o s beaux yeux . . . ”) ;
10 m e s s a g e [ 1 9 ] = ’ \0 ’ ;
11 m e s s a g e [ 1 4 ] = ’ \0 ’ ;
12 dm [ 0 ] = m e s s a g e ;
13 dm [ 2 ] = m e s s a g e + 20 ;
14 dm [ 1 ] = m e s s a g e + 15 ;
15 p r i n t f ( ”%s %s %s \n” , dm [ 1 ] , dm [ 0 ] , dm [ 2 ] ) ;
16 p r i n t f ( ”%s %s %s \n” , dm [ 0 ] , dm [ 1 ] , dm [ 2 ] ) ;
17 f r e e ( message ) ;
18 return 0 ;
19 }

Table 2.3 – Que dit monsieur Jourdain ?

2.4 Tableau de compteurs

Ecrire un programme qui lit une chaı̂ne de caractères CH au clavier et qui compte les
occurrences des lettres de l’alphabet en ne distinguant pas les majuscules et les minuscules.
Utiliser un tableau ABC de dimension 26 pour mémoriser le résultat et un pointeur PCH
pour parcourir la chaı̂ne CH et un pointeur PABC pour parcourir ABC. Afficher seulement
le nombre des lettres qui apparaissent au mois une fois dans le texte.
Exemple :

Entrez un ligne de texte (max. 100 caractères) :


Jeanne
La cha^ıne "Jeanne" contient :
1 fois la lettre ’A’
2 fois la lettre ’E’
1 fois la lettre ’J’
2 fois la lettre ’N’

2.5 Tableaux de pointeurs

Exercice

Refaire l’exercice de la conjugaison d’un verbe du premier groupe avec deux tableaux
de pointeurs : pronoms[] et terminaisons[] que vous initialiserez dans la déclaration.

char *pronoms[] = { ... } ;


10 Chapitre 2. Les Pointeurs

char *terminaisons[] = { ... } ;

2.5.1 Arguments de la fonction main()

Ecrire la commande echo du système Unix. Ce programme ne gérera que l’option -n


qui supprime le passage à ligne. 1 Testez le avec la commande : monEcho *. Que déduisez
vous ?

2.6 Ajouter / supprimer / modifier des composantes d’un


nom de fichier

Réaliser sous forme de procédures C des fonctions utilitaires pour ajouter, supprimer,
modifier des extensions ou des répertoires de noms de fichier.

char *chgext(char *name, const char *ext)


/* change the extension of NAME with EXT
UNIX Version. return modified name */

char *chgdir(char *name, const char *dir)


/* change the directory of NAME with DIR
Version UNIX. return modified name */

Mettez en œuvre (c.-a.-d. testez) ces procédures en utilisant un programme main() simple
(cf. test-ext et test-dir dans l’exemple ci-dessous).

Src$ ./test-ext /Users/jfmari/Src/a.out .exe


/Users/jfmari/Src/a.exe
Src$ ./test-dir /Users/jfmari/Src/a.out /tmp/
/tmp/a.out
Src$

2.7 Affectation de chaı̂nes en Java

Ecrire en C sans utiliser les fonctions de string.h, deux versions de la fonction strcpy(char
s1[], char s2[]). Cette fonction copie s2 dans s1, elle se traduit par s1 = s2 en Java.
1. Appelez le monEcho afin qu’il ne soit pas confondu avec la fonction Unix du même nom
2.8. Pointeurs et chaı̂nes de caractères 11

version 1 : void strcpy(char s1[], char s2[]). On suppose que le tableau s1 est
assez grand pour recevoir s2 ;
version 2 : char* strcpy(char* s1, char* s2). On suppose que s1 et s2 sont deux
pointeurs vers des chaı̂nes de caractères allouées grâce à la fonction malloc. Ecrire
une version qui copie s2 dans s1 et retourne l’adresse de s1 (qui peut être nouvelle dans
le cas où un nouvel emplacement a été alloué parce que la taille de s2 était supérieure
à la taille initialement allouée pour s1).

2.8 Pointeurs et chaı̂nes de caractères

1. Écrire une fonction qui admet en paramètre une chaı̂ne contenant 5 mots, séparés par
des espaces et qui les affiche ensuite dans une ligne, mais dans l’ordre inverse. Les
mots sont mémorisés dans 5 variables m1, ... , m5.
Utiliser cette fonction pour traiter un fichier texte. Pour lire une ligne contenant
des espaces, utilisez la fonction char* fgets(char* s, int n, FILE* stream) en
donnant la valeur stdin à la variable stream.
char buffer[80] ;
...
fgets(buffer, 80, stdin) ; /* lecture au clavier dans buffer */
Donnez deux versions : une qui utilise la fonction C strtok() définie dans string.h
et une autre sans utiliser strtok().
2. A partir d’un dictionnaire (fichier contenant les couples ( mot, prononciation ) avec
une prononciation par mot et par ligne, ce fichier est trié selon l’ordre alphabétique des
mots) et d’un texte quelconque représenté dans un fichier texte, phonétiser le texte,
c’est à dire, créer un nouveau fichier contenant le texte où les mots du dictionnaire sont
remplacés par leur prononciation. Si un mot n’est pas dans le dictionnaire le laisser
tel quel et faire un message d’erreur à l’écran. Comme dans l’exercice précédent,
utiliser fgets(buffer, ..) pour lire une ligne du fichier dans laquelle apparaissent
des espaces.
Exemple de dictionnaire :
cent s an
comme k o m
france f r an s
vingt v in
Exemple de texte source : Il y a cent vingt ans en République de France
Exemple de résultat : Il y a s an v in ans en République de f r an s
12 Chapitre 2. Les Pointeurs

2.9 Debugger

Dans le programme wordcnt.c 2 , des bugs ont été introduits afin que vous appreniez à
utiliser le “debugger” gdb. Commencez par enlever tous les avertissements (warning) puis
corrigez les 2 bugs.
1 /∗ ∗∗∗∗
2 ∗ L i t un f i c h i e r t e x t e ; c o m p t e le nombre d e mots d e l o n g u e u r
3 ∗ 1 , 2 , 3 , etc .
4 ∗ REMARQUE : c e programme e s t à utiliser pour l ’ a p p r e n t i s s a g e du
5 ∗ d é b o g u e u r .
6 ∗ Des b o g u e s o n t é t é introduites intentionnellement .
7 ∗∗∗∗∗ ∗/
8 #include < s t d i o . h>
9 #include <c t y p e . h>
10 #include < s t r i n g . h>
11 #include < s t d l i b . h>
12
13 #d e f i n e MAXWORDLEN 16
14 #d e f i n e NUL ( ( char ) 0 )
15 #d e f i n e SPACE ( ( char ) 0 x20 )
16 /∗ ∗∗∗∗
17 ∗ T r o u v e l e mot s u i v a n t d a n s l e tampon d e l i g n e .
18 ∗ EN ENTREE : w o r d p t r p o i n t e s u r l e p r e m i e r c a r a c t è r e
19 ∗ d ’ un mot ou l ’ e s p a c e p r é c é d e n t .
20 ∗ VALEUR RETOURNEE : un p o i n t e u r s u r l e p r e m i e r c a r a c t è r e du mot .
21 ∗ S ’ i l n ’ y a p a s d ’ a u t r e s mots , un p o i n t e u r s u r
22 ∗ l e c a r a c t è r e n u l d ’ a r r e t .
23 ∗∗∗∗ ∗/
24 char ∗ nextword ( char ∗ w o r d p t r )
25 {
26 /∗ Avance j u s q u ’ au p r o c h a i n c a r a c t è r e q u i n ’ e s t p a s un e s p a c e . ∗/
27 while ( ∗ w o r d p t r == SPACE )
28 w o r d p t r ++;
29 return w o r d p t r ;
30 }
31 /∗ ∗∗∗∗
32 ∗ T r o u v e l a l o n g u e u r d ’ un mot . Un mot e s t une s u i t e d e c a r a c t è r e s
33 ∗ t e r m i n é e p a r un e s p a c e ou un c a r a c t è r e n u l .
34 ∗ EN ENTREE : w o r d p t r p o i n t e s u r un mot .
35 ∗ VALEUR RETOURNEE : l a l o n g u e u r du mot .
36 ∗∗∗∗ ∗/
37 i n t w o r d l e n ( char ∗ w o r d p t r )
38 {
39 char ∗ w o r d l i m i t ;
40
41 w o r d l i m i t = wordptr ;
42 while ( ∗ w o r d l i m i t && ∗ w o r d l i m i t != SPACE )
43 w o r d l i m i t ++;
44 return w o r d l i m i t − w o r d p t r ;
45 }
46 /∗ ∗∗∗∗
47 ∗ La f o n c t i o n p r i n c i p a l e .
48 ∗∗∗∗ ∗/
49 i n t main ( i n t a r g c , char ∗ a r g v [ ] )
50 {
51 FILE ∗infile ; /∗ F i c h i e r en e n t r é e d e nom d a n s a r g v [ ] ∗/
52 char linebfr [1024] , /∗ Tampon d e l i g n e en e n t r é e , ∗/
53 /∗ t r è s l o n g p a r s é c u r i t é . ∗/
54 ∗ wordptr ; /∗ P o i n t e u r s u r l e mot s u i v a n t d e l i n e b f r . ∗/
55 int i; /∗ V a r i a b l e u t i l i t a i r e . ∗/
56 int w o r d l e n c n t [MAXWORDLEN] ,
57 /∗ L e s l o n g u e u r s d e mot s o n t c o m p t é e s d a n s
58 l e s é l é m e n t s d e 1 à MAXWORDLEN. L ’ é l é m e n t
59 0 n ’ e s t p a s u t i l i s é . Le t a b l e a u e s t
60 s t a t i q u e d e s o r t e q u e l e s é l é m e n t s n ’ o n t
61 p a s à e t r e mis à z é r o au moment d e
62 l ’ e x é c u t i o n . ∗/
63 overlencnt ;

2. http ://www.loria.fr/˜ jfmari/Cours/wordcnt.c


2.9. Debugger 13

64 /∗ L e s mots t r o p longs sont c o m p té s i c i . ∗/


65 if ( argc < 2) {
66 printf (” I l faut s p é c i f i e r un f i c h i e r d ’ e n t r é e ! \ n” ) ;
67 exit (1) ;
68 }
69 strcpy ( linebfr , argv [ 1 ] ) ;
70
71 f o r ( i = 0 ; i < MAXWORDLEN ; i ++) w o r d l e n c n t [ i ] = 0 ;
72 i n f i l e = fopen ( l i n e b f r , ” r ” ) ;
73 if ( ! infile ) {
74 p e r r o r ( argv [ 1 ] ) ;
75 exit (1) ;
76 }
77 /∗ Chaque b o u c l e t r a i t e une l i g n e . REMARQUE : L o r s q u e l a l o n g u e u r
78 d ’ une l i g n e d é p a s s e l a c a p a c i t é du tampon d ’ e n t r é e , l e programme
79 p e u t p r o d u i r e d e s r é s u l t a t s i n c o r r e c t s . C e c i d e v i e n t i m p r o b a b l e
80 a v e c un t r è s g r a n d tampon . ∗/
81
82 while ( fgets ( linebfr , sizeof ( l i n e b f r ) , i n f i l e ) ) {
83 /∗ p r i n t f (”% s \n ” , l i n e b f r ) ; ∗/
84 /∗ V é r i f i e qu ’ i l n ’ y a p a s d é b o r d e m e n t d e c a p a c i t é du tampon
85 e t s u p p r i m e l e c a r a c t è r e d ’ i n t e r l i g n e f i n a l . ∗/
86 i = strlen ( linebfr ) ;
87 i f ( l i n e b f r [ i −1] != ’ \n ’ )
88 p r i n t f ( ” L i g n e t r o p l o n g u e commençant p a r : \ n\ t %70 s \n” , l i n e b f r ) ;
89 else
90 l i n e b f r [ i −1] = NUL ;
91
92 /∗ w o r d p t r p o i n t e s u r l e p r e m i e r mot d e linebfr ( a p r è s les espaces
93 du d é b u t ) . ∗/
94 w o r d p t r = nextword ( l i n e b f r ) ;
95
96 /∗ Chaque b o u c l e t r a i t e un mot . La b o u c l e s e t e r m i n e l o r s q u e [ n e x t w o r d ]
97 r e t o u r n e un NULL, i n d i q u a n t qu ’ i l ne r e s t e p l u s d e mots . ∗/
98 while ( ∗ w o r d p t r ) {
99 /∗ T r o u v e l a l o n g u e u r d e c e mot , i n c r é m e n t e l ’ é l é m e n t a p p r o p r i é
100 du t a b l e a u d e s c o m p t e u r s d e l o n g u e u r e t p o i n t e s u r l ’ e s p a c e
101 s u i v a n t l e mot . ∗/
102 i = wordlen ( wordptr ) ;
103 i f ( i > MAXWORDLEN )
104 o v e r l e n c n t ++;
105 else
106 ;
107 w o r d l e n c n t [ i ]++;
108 w o r d p t r += i ;
109
110 /∗ T r o u v e l e mot s u i v a n t ( s ’ i l e x i s t e ) . ∗/
111 w o r d p t r = nextword ( w o r d p t r ) ;
112 }
113 }
114 /∗ A f f i c h e l e s c o m p t e u r s d e l o n g u e u r s d e s mots . Chaque b o u c l e
115 en i m p r i m e un . ∗/
116 p r i n t f ( ”%s \n” , ” Comptage d e s l o n g u e u r s ” ) ;
117 f o r ( i =1; i < MAXWORDLEN; i++ )
118 p r i n t f ( ” %5d %5d\n” , i , w o r d l e n c n t [ i ] ) ;
119 printf ( ” Mots p l u s l o n g s %5d\n” , o v e r l e n c n t ) ;
120
121 /∗ Ferme l e f i c h i e r et q u i t t e . ∗/
122 fclose ( infile ) ;
123 return 0 ;
124 }
14 Chapitre 2. Les Pointeurs

2.10 Traduction de Java vers C

2.10.1 PileString

On souhaite traduire en C le programme Java donné table 2.4. Ce programme manipule


2 piles de chaı̂nes de caractères. Pour traduire en C les classes Java String et PileString,
vous utiliserez les types de données MString et PileString définis ci-dessous :

typedef struct pile_string {


MString *tab ; // tab[0], tab[1], ... sont les chaines de la pile
int sommet ; // de la pile
int sommetMax ; // de la pile
} PileString ;

et

typedef char* MString ; // le type chaine de caracteres

2.11 Fichiers et pointeurs

Nous disposons d’un fichier texte qui indique le nom, le prénom et le groupe de chaque
étudiant (cf. Tab 2.5).
A partir de la méthode de tri par permutation (appelée aussi tri à bulles) donnée page
37 du poly, on demande de créer un fichier trié à partir de etudiant.txt de plusieurs façons
différentes.

2.11.1 Allocation statique

Les étudiants sont rangés dans un tableau de structures où chaque chaı̂ne de caractères
fait 80 caractères de long.

2.11.2 Allocation dans des tableaux dynamiques

les étudiants sont rangés dans un tableau dont on calcule la taille après avoir compté le
nombres d’étudiants dans le fichier. Chaque étudiant est représenté par le type Etudiant1
donné Tab. 2.6.
2.11. Fichiers et pointeurs 15

1 import j a v a . u t i l . ∗ ;
2
3 public c l a s s P i l e S t r i n g // une p i l e d e c h a i n e s d e c a r a c t e ‘ r e s
4 {
5 private S t r i n g tab [ ] = null ;
6 p r i v a t e i n t sommet = 0 ;
7 p r i v a t e i n t sommetMax ;
8 public P i l e S t r i n g ( i n t t a i l l e M a x )
9 {
10 t a b = new S t r i n g [ t a i l l e M a x ] ;
11 sommet = 0 ; // p r e m i e r e c a s e l i b r e au d e s s u s d e l a p i l e
12 sommetMax = t a i l l e M a x ;
13 }
14 public void e m p i l e r ( S t r i n g v )
15 {
16 i f ( sommet < sommetMax ) {
17 t a b [ sommet ] = v ;
18 sommet++ ;
19 }
20 }
21 public S t r i n g d e p i l e r ( )
22 {
23 S t r i n g v = ”” ;
24 i f ( sommet > 0 ) {
25 sommet−− ;
26 v = t a b [ sommet ] ;
27 }
28 return v ;
29 }
30 public void a f f i c h e r ( )
31 {
32 f o r ( i n t i = 0 ; i < sommet ; i ++) System . o u t . p r i n t l n ( t a b [ i ] ) ;
33 }
34 public boolean p i l e V i d e ( )
35 {
36 return sommet == 0 ;
37 }
38
39 public s t a t i c void main ( S t r i n g a r g s [ ] ) {
40 P i l e S t r i n g p1 = new P i l e S t r i n g ( 1 0 ) ;
41 S t r i n g t [ ] = { ” J e s u s ” , ” Marie ” , ” J o s e p h ” , ” Le D i a b l e ” } ;
42 // i n i t d e p1
43 f o r ( i n t i = 0 ; i < t . l e n g t h ; i ++) p1 . e m p i l e r ( t [ i ] ) ;
44 // on r e n v e r s e p1 d a n s p2
45 P i l e S t r i n g p2 = new P i l e S t r i n g ( 2 0 ) ;
46 while ( p1 . p i l e V i d e ( ) == f a l s e ) p2 . e m p i l e r ( p1 . d e p i l e r ( ) ) ;
47
48 p1 = new P i l e S t r i n g ( 2 0 ) ;
49 // on r e n v e r s e p2 d a n s p1
50 while ( p2 . p i l e V i d e ( ) == f a l s e ) p1 . e m p i l e r ( p2 . d e p i l e r ( ) ) ;
51
52 p1 . a f f i c h e r ( ) ;
53 }
54 }

Table 2.4 – Manipulation de Piles

101 ANDREUX Jereme E


0 ANDRIAMIARINA Tsiorintsoa A
126 ANTCZAK Matthieu F
127 ANTONIAK Jereme F

Table 2.5 – Quelques lignes du fichier etudiant.txt


16 Chapitre 2. Les Pointeurs

typedef struct etu {


char* nom ;
char* prenom ;
char groupe[10] ;
} Etudiant1 ;

Table 2.6 – Définition du type Etudiant1


Chapitre 3

Les listes

3.1 Les listes chaı̂nées

3.1.1 LinkedList

1. On souhaite traduire en C le programme Java donné Table 3.1 dont l’exécution donne
le résultat suivant :
jfmari@MacBook:C$ java LinkedListExample1
Linked List Example!
Linked list data: 44 33 22 11
Linked list size: 4
Linked list is empty
jfmari@MacBook:C$
Complétez le squelette du programme C donné Table 3.2 en remplaçant les points de
suspension par les instruction C équivalentes. Utilisez la classe Maillon comme dans
le projet Java.
2. Comparez les vitesses d’exécution de la version Java et de la version C.
3. On souhaite traduire en C le programme Java donné Table 3.3. Son exécution donne
le résultat suivant :
jfmari@macjfm1:C$ java LinkedListExample2 Janvier
LinkedList contenait Janvier
LinkedList ne contient pas maintenant Janvier
jfmari@macjfm1:C$
Complétez le squelette du programme C donné Table 3.4 en remplaçant les points de
suspension par les instruction C équivalentes. Utilisez la classe Maillon comme dans
le projet Java.

17
18 Chapitre 3. Les listes

1 import j a v a . u t i l . ∗ ;
2
3 public c l a s s L i n k e d L i s t E x a m p l e 1 {
4 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
5 System . o u t . p r i n t l n ( ” L i n k e d L i s t Example ! ” ) ;
6 L i n k e d L i s t <I n t e g e r > l i s t = new L i n k e d L i s t <I n t e g e r >() ;
7 i n t num1 = 1 1 , num2 = 2 2 , num3 = 3 3 , num4 = 4 4 ;
8 int l i s t S i z e ;
9 Iterator iterator ;
10 // A d d i n g d a t a i n t h e l i s t
11 l i s t . a d d F i r s t ( num1 ) ;
12 l i s t . a d d F i r s t ( num2 ) ;
13 l i s t . a d d F i r s t ( num3 ) ;
14 l i s t . a d d F i r s t ( num4 ) ;
15 l i s t S i z e = l i s t . size () ;
16 System . o u t . p r i n t ( ” L i n k e d l i s t d a t a : ” ) ;
17 // C r e a t e a i t e r a t o r
18 iterator = l i s t . iterator () ;
19 while ( i t e r a t o r . h as Next ( ) ) {
20 System . o u t . p r i n t ( i t e r a t o r . n e x t ( )+” ” ) ;
21 }
22 System . o u t . p r i n t l n ( ) ;
23 // C h e c k l i s t e m p ty o r n o t
24 i f ( l i s t . isEmpty ( ) ) {
25 System . o u t . p r i n t l n ( ” L i n k e d l i s t i s empty ” ) ;
26 }
27 else {
28 System . o u t . p r i n t l n ( ” L i n k e d l i s t s i z e : ” + l i s t S i z e ) ;
29 }
30 // Remove a l l
31 l i s t . clear () ;
32 i f ( l i s t . isEmpty ( ) ) {
33 System . o u t . p r i n t l n ( ” L i n k e d l i s t i s empty ” ) ;
34 }
35 else {
36 System . o u t . p r i n t l n ( ” L i n k e d l i s t s i z e : ” + l i s t . s i z e ( ) ) ;
37 }
38 }
39 }

Table 3.1 – Manipulation d’une liste chaı̂née en Java


3.1. Les listes chaı̂nées 19

1 #include < s t d i o . h>


2 #include < s t d l i b . h>
3 typedef s t r u c t c e l l u l e t {
4 int val ;
5 struct c e l l u l e t ∗ suc ;
6 } Maillon ;
7
8 Maillon ∗ addFirst ( Maillon ∗ l , int v ) {
9 /∗ a j o u t e l ’ e n t i e r v a l a l i s t e d e t e t e l ∗/
10 Maillon ∗ p ;
11 p = ( Maillon ∗) malloc ( s i z e o f ( Maillon ) ) ;
12 ...
13 return p ;
14 }
15
16 int s i z e ( . . . )
17 {
18 /∗ c o m p t e l e n b r d ’ e l e m e n t s
19 ∗∗ d e l a l i s t e l d a n s n
20 ∗/
21 int n = 0 ;
22 ...
23 return n ;
24 }
25
26 void c l e a r ( . . . )
27 {
28 ...
29 }
30
31 i n t isEmpty ( . . . )
32 {
33 ...
34 }
35
36 i n t main ( )
37 {
38 Maillon ∗ l i s t ;
39
40 i n t num1 = 1 1 , num2 = 2 2 , num3 = 3 3 , num4 = 4 4 ;
41 int l i s t S i z e ;
42 Maillon ∗ p ;
43 p r i n t f ( ” L i n k e d L i s t Example ! \ n” ) ;
44 /∗ A d d i n g d a t a i n t h e l i s t ∗/
45 l i s t = a d d F i r s t ( l i s t , num1 ) ;
46 l i s t = a d d F i r s t ( l i s t , num2 ) ;
47 l i s t = a d d F i r s t ( l i s t , num3 ) ;
48 l i s t = a d d F i r s t ( l i s t , num4 ) ;
49 listSize = size ( list ) ;
50 p r i n t f ( ” Linked l i s t data : ” ) ;
51 ...
52 return 0 ;
53 }

Table 3.2 – Manipulation de la même liste en C


20 Chapitre 3. Les listes

1 import j a v a . u t i l . L i n k e d L i s t ;
2
3 public c l a s s L i n k e d L i s t E x a m p l e 2
4 {
5
6 public s t a t i c void main ( S t r i n g [ ] args )
7 {
8
9 L i n k e d L i s t <S t r i n g > l k L i s t e = new L i n k e d L i s t <S t r i n g >() ;
10
11 // A j o u t des e l e m e n t s dans l a l i s t e
12 String t [ ] = { ” F e v r i e r ” , ” Mars ” } ; // init
13
14 f o r ( i n t i = 0 ; i < t . l e n g t h ; i ++) l k L i s t e . a d d F i r s t ( t [ i ] ) ;
15 l k L i s t e . a d d L a s t ( ” Decembre ” ) ;
16 // V e r i f i e r s i a r g s [ 0 ] e x i s t e d a n s l e L i n k e d L i s t
17 i f ( l k L i s t e . contains ( args [ 0 ] ) )
18 {
19 System . o u t . p r i n t l n ( ” L i n k e d L i s t c o n t e n a i t ” + a r g s [ 0 ] ) ;
20 }
21 else
22 {
23 System . o u t . p r i n t l n ( ” L i n k e d L i s t ne c o n t e n a i t p a s ” + a r g s [ 0 ] ) ;
24 }
25 // e f f a c e r l a l i s t e
26 lk Liste . clear () ;
27 // V e r i f i e r a n o u v e a u s i a r g s [ 0 ] e x i s t e d a n s l e L i n k e d L i s t
28 i f ( l k L i s t e . contains ( args [ 0 ] ) )
29 {
30 System . o u t . p r i n t l n ( ” L i n k e d L i s t c o n t i e n t m a i n t e n a n t ” + a r g s [ 0 ] ) ;
31 }
32 else
33 {
34 System . o u t . p r i n t l n ( ” L i n k e d L i s t ne c o n t i e n t p a s m a i n t e n a n t ” + a r g s [ 0 ] ) ;
35 }
36 }
37 }

Table 3.3 – Manipulation d’une liste chaı̂née en Java


3.1. Les listes chaı̂nées 21

1 #include <s t d i o . h>


2 #include < s t d l i b . h>
3 #include <s t r i n g . h>
4
5 /∗ m a i l l o n pour une l i s t e c h a i n e e de c h a i n e s de c a r a c t e r e s ∗/
6 typedef struct c e l l u l e t {
7 char∗ s t r ;
8 struct c e l l u l e t ∗ s u c ;
9 } Maillon ;
10
11 M a i l l o n ∗ a d d F i r s t ( M a i l l o n ∗ l , char∗ v ) {
12 /∗ a j o u t e l a c h a i n e v a l ’ a t t r i b u t s t r de l a l i s t e de t e t e l ∗/
13 Maillon ∗ p ;
14 char ∗ pc ;
15 p = ( M a i l l o n ∗ ) m a l l o c ( s i z e o f ( M a i l l o n ) ) ; /∗ nouveau m a i l l o n ∗/
16 pc = m a l l o c ( s t r l e n ( v ) + 1 ) ; /∗ p l a c e a l l o u e ’ e pour r a n g e r v ∗/
17 ...
18 return p ; /∗ r e t o u r n e l a n o u v e l l e t e t e de l i s t e ∗/
19 }
20
21 void c l e a r ( . . . )
22 /∗ e r a s e t h e l i s t and f r e e i t s e l e m e n t s ∗/
23 {
24 . . .
25 }
26
27 int c o n t a i n s ( M a i l l o n ∗ l , char ∗v )
28 /∗ r e t o u r n e 1 s i v e s t dans l a l i s t e de t e t e l
29 ∗∗ s i n o n r e t o u r n e 0 ∗/
30 {
31 . . .
32 }
33
34 M a i l l o n ∗ addLast ( M a i l l o n ∗ l , char∗ v )
35 /∗ a j o u t e v a l a f i n de l i s t e de t e t e l
36 ∗∗ r e t o u r n e l a t e t e de l i s t e ∗/
37 {
38 . . .
39 }
40
41 int main ( int argc , char ∗∗ argv )
42 {
43 M a i l l o n ∗ l i s t = NULL ;
44 char ∗ t [ 2 ] = {” F e v r i e r ” , ”Mars” } ; /∗ i n i t ∗/
45 int i ;
46
47 i f ( argc < 2) {
48 p r i n t f ( ” Usage : %s c h a i n e \n” , argv [ 0 ] ) ;
49 exit (1) ;
50 }
51
52 /∗ Ajout d e s e l e m e n t s dans l a l i s t e ∗/
53 f or ( i = 0 ; i < 2 ; i ++)
54 l i s t = addFirst ( l i s t , t [ i ] ) ;
55 . . .
56 return 0 ;
22 Chapitre 3. Les listes

3.1.2 La bibliothèque Liste d’entiers

On considère la liste formée d’éléments du type suivant :

typedef struct TCell {


int val;
struct TCell *suc;
} Maillon ;

Une liste sera désignée par sa tête de type Maillon*.


– Compléter la bibliothèque Liste avec les fonctions suivantes :
affichage des éléments : void liste afficher(Maillon*) ;
insertion d’un élément en tête de liste : Maillon* tete inserer(Maillon*, int) ;
insertion d’un élément en queue de liste : Maillon* queue inserer(Maillon*,
int) ;
suppression d’un élément en queue de liste : Maillon* queue supprimer(Maillon*) ;
recherche d’un élément dans la liste : int liste rechercher(Maillon*, int). La
fonction retournera le rang (compté à partir de 1) si l’élément est bien dans la
liste. Sinon, la fonction retournera 0.
– Ecrire la fonction int main() qui permet de tester toutes ces fonctions. Comme
dans les exercices prcédents, prévoir la présentation d’un menu regroupant toutes ces
fonctions et permettant ainsi une interaction avec l’utilisateur.

3.1.3 Lecture de fichier texte et codes postaux

L’objectif de ce programme est de manipuler un fichier contenant tous les codes postaux
des villes françaises. Ce fichier (codePost.txt) se présente sous la forme d’un fichier texte
formaté en lignes comme suit :

aast 64460
abainville 55130
abancourt 59265
abancourt 60220
abaucourt-hautecourt 55400

1. Créer une classe (structure) Ville, correspondant à une ligne du fichier, avec deux
attributs : le nom et le code postal de la ville (deux chaı̂nes de caractères).
3.1. Les listes chaı̂nées 23

2. Ecrire un int main(int argc, char **argv) pour qui argv[1] est le nom du fichier
de codes postaux. Ce programme lit le fichier et le stocke sous forme d’une liste chaı̂née
dont le maillon sera :
typedef struct cellule_t {
Ville* town ;
struct cellule_t *suc ;
} Maillon ;
3. Définir une méthode void afficher(int n, ...) permettant d’afficher à l’écran ses
n premiers éléments, ou tous ses éléments si n vaut 0. Cette méthode sera utiliséee
pour valider les résultats obtenus par les différentes méthodes à définir ultérieurement.

Vous aimerez peut-être aussi