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

TD,TP-07_Algo_June.2018 - Corrigé--

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

Akli Mohand Oulhadj University of Bouira (Algeria)

Department: MI 1st year MI


Module: Algorithmique et structure de données (ASD) 2nd Semester 2018/2019
Chapter: Les pointeurs
Série de (TD et TP) n° 07 -corrigé
Exercice 1. TP

Copiez le tableau suivant et complétez-le pour chaque


main()
instruction du programme ci-dessus.
{
int A = 1; A B C P1 P2
int B = 2; Init. 1 2 3 / /
int C = 3; P1=&A 1 2 3 &A /
int *P1, *P2; P2=&C
P1=&A; *P1=(*P2)++
P2=&C; P1=P2
*P1=(*P2)++; P2=&B
P1=P2; *P1-=*P2
P2=&B; ++*P2
*P1-=*P2; *P1*=*P2
++*P2; A=++*P2**P1
*P1*=*P2; P1=&A
A=++*P2**P1; *P2=*P1/=*P2
P1=&A;
*P2=*P1/=*P2;
return 0;
}

Solution :
A B C P1 P2
Init. 1 2 3/ /
P1=&A 1 2 3 &A /
P2=&C 1 2 3 &A &C
*P1=(*P2)++ 3 2 4 &A &C
P1=P2 3 2 4 &C &C
P2=&B 3 2 4 &C &B
*P1-=*P2 3 2 2 &C &B
++*P2 3 3 2 &C &B
*P1*=*P2 3 3 6 &C &B
A=++*P2**P1 24 4 6 &C &B
P1=&A 24 4 6 &A &B
*P2=*P1/=*P2 6 6 6 &A &B

Exercice 2. TD
Soient i une variable de type int, p et q des pointeurs sur int.
On suppose que :
― i se trouve à l’adresse 4830000,
― p à l’adresse 4830010, et
― q à l’adresse 4830020.

ASD (1st MI)/TD,TP - 07 Page 1 / 10 DJOUABRI(June.2018)


On suppose aussi que :
― l’adresse 4830000 contient 2,
― l’adresse 4830010 contient 4840010,
― l’adresse 4830020 contient 4840020,
― l’adresse 4840010 contient 12, et
― l’adresse 4840020 contient 22
1. Lesquelles parmi les expressions suivantes affectent un pointeur à une variable de type
pointeur, ou un entier à une variable de type entier, et pour ces expressions, quel est leur effet
sur le contenu de la mémoire.

1)p = i 2)*p = &i 3)&p = q 4)p = &q

5)p =*&q 6)*p = q 7)p =*q 8)*p =*q


Solution:

1. Lesquelles parmi les expressions suivantes :


A) Affectent un pointeur à une variable de type pointeur

4)p = &q 5)p =*&q 7)p =*q

B) affecte un entier à une variable de type entier


2)*p = &i 6)*p = q 8)*p =*q

2. Quel est leur effet sur le contenu de la mémoire.

1) p = i → affecte la valeur de i au pointeur p, opération illégale (tentative d’accès interdit ou


zone d’accès interdit) → erreur sémantique se produit au moment d’exécution
2) *p = &i → affecte l’adresse de i à la valeur pointée par p (l’dresse est considéré comme
un entier)
3) &p = q → erreur syntaxique, la partie gauche doit être une variable et pas une adresse
mémoire (parce que la variable est une adresse déjà réservé au nom de ce programme →
donc accès autorisé, mais une adresse on ne sait pas est ce qu’appartient au programme ou
non)
4) p = &q → p pointe vers q, (*p  14 affecte E comme adresse pointée par q), erreur
sémantique
5) p =*&q → c’est l’équivalent de p = q ;
6) *p = q → affecte l’adresse pointée par q à la valeur pointée par p
7) p =*q → affecte la valeur pointée par q au p
8) *p =*q → affecte la valeur pointée par q à la valeur pointée par p

Exercice 3. TD
Considérons un tableau d’entiers tab avec des valeurs dont certaines seront nulles.
1. Écrire un programme qui parcoure le tableau tab et qui imprime les indices des éléments
nuls du tableau, sans utiliser aucune variable de type entier.
Solution :
Algo parcours_tab_pointeur
Const N =10 ;
Var tab : tableau [N] d’entier
P : pointeur d’entier
ASD (1st MI)/TD,TP - 07 Page 2 / 10 DJOUABRI(June.2018)
Begin
P = tab ;
For (p =tab ; p<tab + N ; P++) do
If ( *p = 0) then
Writeln(p-tab));
endFor
end.

Exercice 4.
Ecrire un programme qui lit deux tableaux A et B et leurs dimensions N et M au clavier et qui
ajoute les éléments de B à la fin de A. Utiliser le formalisme pointeur à chaque fois que cela est
possible.
Solution :
#include <stdio.h>
main()
{
/* Déclarations */
int A[100], B[50]; /* tableaux */
int N, M; /* dimensions des tableaux */
int I; /* indice courant */

/* Saisie des données */


printf("Dimension du tableau A (max.50) : ");
scanf("%d", &N );
for (I=0; I<N; I++)
{
printf("Elément %d : ", I);
scanf("%d", A+I);
}
printf("Dimension du tableau B (max.50) : ");
scanf("%d", &M );
for (I=0; I<M; I++)
{
printf("Elément %d : ", I);
scanf("%d", B+I);
}
/* Affichage des tableaux */
printf("Tableau donné A :\n");
for (I=0; I<N; I++)
printf("%d ", *(A+I));
printf("\n");
printf("Tableau donné B :\n");
for (I=0; I<M; I++)
printf("%d ", *(B+I));
printf("\n");
/* Copie de B à la fin de A */
for (I=0; I<M; I++)
*(A+N+I) = *(B+I);
/* Nouvelle dimension de A */
N += M;
/* Edition du résultat */
printf("Tableau résultat A :\n");
for (I=0; I<N; I++)
printf("%d ", *(A+I));
printf("\n");
return 0;
}

Exercice 5. TD

ASD (1st MI)/TD,TP - 07 Page 3 / 10 DJOUABRI(June.2018)


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 :
a) *P+2
b) *(P+2)
c) &P+1
d) &A[4]-3
e) A+3
f) &A[7]-P
g) P+(*P-10)
h) *(P+*(P+8)-A[7])
solution :

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:


a) *P+2 => la valeur 14
b) *(P+2) => la valeur 34
c) &P+1 => l'adresse du pointeur derrière le pointeur P
(rarement utilisée)
d) &A[4]-3 => l'adresse de la composante A[1]
e) A+3 => l'adresse de la composante A[3]
f) &A[7]-P => la valeur (indice) 7
g) P+(*P-10) => l'adresse de la composante A[2]
*(P+*(P+8)-
h) A[7]) => la valeur 23

Exercice 6. TP
Ecrire un programme qui lit une chaîne de caractères CH et détermine la longueur de la chaîne à
l'aide d'un pointeur P. Le programme n'utilisera pas de variables numériques.

Solution :
#include <stdio.h>

main()
{
/* Déclarations */
char CH[101]; /* chaîne donnée */
char *P; /* pointeur d'aide */

/* Saisie des données */


printf("Entrez une ligne de texte (max.100 caractères) :\n");
gets(CH);
/* Placer P à la fin de la chaîne */
for (P=CH; *P; P++)
;
/* Affichage du résultat */
printf("La chaîne \"%s\" est formée de %d caractères.\n",
CH, P-CH);

ASD (1st MI)/TD,TP - 07 Page 4 / 10 DJOUABRI(June.2018)


return 0;
}

Exercice 7. TD
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 moins une fois dans le texte.

Exemple:

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


Fatima Zohra
La chaîne "Jeanne" contient :
1 fois la lettre ‘F’
3 fois la lettre 'A'
1 fois la lettre 'T'
1 fois la lettre 'I'
1 fois la lettre 'Z'
1 fois la lettre 'O'
1 fois la lettre 'H'
1 fois la lettre 'R'
Solution :
#include <stdio.h>
main()
{
/* Déclarations */
char CH[101]; /* chaîne donnée */
char *PCH; /* pointeur d'aide dans CH */
int ABC[26]; /* compteurs des différents caractères */
int *PABC; /* pointeur d'aide dans ABC */

/* Saisie des données */


printf("Entrez une ligne de texte (max.100 caractères) :\n");
gets(CH);
/* Initialiser le tableau ABC */
for (PABC=ABC; PABC<ABC+26; PABC++)
*PABC=0;
/* Compter les lettres */
for (PCH=CH; *PCH; PCH++)
{
if (*PCH>='A' && *PCH<='Z')
(*(ABC+(*PCH-'A')))++; /* Attention aux parenthèses! */
if (*PCH>='a' && *PCH<='z')
(*(ABC+(*PCH-'a')))++;
}
/* Affichage des résultats */
/* (PABC-ABC) est le numéro de la lettre de l'alphabet. */
printf("La chaîne \"%s\" contient :\n", CH);
for (PABC=ABC; PABC<ABC+26; PABC++)
if (*PABC)
printf(" %d\tfois la lettre '%c' \n",
*PABC, 'A'+(PABC-ABC));
return 0;
}

Exercice 8. TD

ASD (1st MI)/TD,TP - 07 Page 5 / 10 DJOUABRI(June.2018)


Ecrire un programme qui lit une matrice A de dimensions N et M au clavier et affiche les données
suivantes en utilisant le formalisme pointeur à chaque fois que cela est possible :

a) la matrice A
b) la transposée de A
c) la matrice A interprétée comme tableau unidimensionnel

Solution :
#include <stdio.h>
main()
{
/* Déclarations */
int A[50][50]; /* matrice */
int N, M; /* dimensions de la matrice */
int I, J; /* indices courants */
/* Saisie des données */
printf("Nombre de lignes (max.50) : ");
scanf("%d", &N );
printf("Nombre de colonnes (max.50) : ");
scanf("%d", &M );
/* Lecture de la matrice au clavier */
for (I=0; I<N; I++)
for (J=0; J<M; J++)
{
printf("Elément[%d][%d] : ",I,J);
scanf("%d", (int *)A+I*50+J);
}

/* a) Affichage de la matrice */
printf("Matrice donnée :\n");
for (I=0; I<N; I++)
{
for (J=0; J<M; J++)
printf("%7d", *((int *)A+I*50+J));
printf("\n");
}

/* b) Affichage de la transposée de A */
printf("Matrice transposée :\n");
for (J=0; J<M; J++)
{
for (I=0; I<N; I++)
printf("%7d ", *((int *)A+I*50+J));
printf("\n");
}

/* c) Interprétation de la matrice comme vecteur : */


/* Attention, ce serait une faute grave d'afficher */
/*'simplement' les NxM premiers éléments de A ! */
printf("Matrice affichée comme vecteur :\n");
for (I=0; I<N; I++)
for (J=0; J<M; J++)
printf(" %d ", *((int *)A+I*50+J));
printf("\n");
return 0;
}

Exercice 9.
Ecrire un programme qui lit deux matrices A et B de dimensions N et M respectivement M et P au
clavier et qui effectue la multiplication des deux matrices. Le résultat de la multiplication sera
affecté à la matrice C, qui sera ensuite affichée. Utiliser le formalisme pointeur à chaque fois que
cela est possible.
Solution :
ASD (1st MI)/TD,TP - 07 Page 6 / 10 DJOUABRI(June.2018)
#include <stdio.h>
main()
{
/* Déclarations */
int A[50][50]; /* matrice donnée */
int B[50][50]; /* matrice donnée */
int C[50][50]; /* matrice résultat */
int N, M, P; /* dimensions des matrices */
int I, J, K; /* indices courants */

/* Saisie des données */


printf("*** Matrice A ***\n");
printf("Nombre de lignes de A (max.50) : ");
scanf("%d", &N );
printf("Nombre de colonnes de A (max.50) : ");
scanf("%d", &M );
for (I=0; I<N; I++)
for (J=0; J<M; J++)
{
printf("Elément[%d][%d] : ",I,J);
scanf("%d", (int *)A+I*50+J);
}
printf("*** Matrice B ***\n");
printf("Nombre de lignes de B : %d\n", M);
printf("Nombre de colonnes de B (max.50) : ");
scanf("%d", &P );
for (I=0; I<M; I++)
for (J=0; J<P; J++)
{
printf("Elément[%d][%d] : ",I,J);
scanf("%d", (int *)B+I*50+J);
}

/* Affichage des matrices */


printf("Matrice donnée A :\n");
for (I=0; I<N; I++)
{
for (J=0; J<M; J++)
printf("%7d", *((int *)A+I*50+J));
printf("\n");
}
printf("Matrice donnée B :\n");
for (I=0; I<M; I++)
{
for (J=0; J<P; J++)
printf("%7d", *((int *)B+I*50+J));
printf("\n");
}

/* Affectation du résultat de la multiplication à C */


for (I=0; I<N; I++)
for (J=0; J<P; J++)
{
*((int *)C+I*50+J)=0;
for (K=0; K<M; K++)
*((int*)C+I*50+J) += *((int*)A+I*50+K) * *((int*)B+K*50+J);
}

/* Edition du résultat */
printf("Matrice résultat C :\n");
for (I=0; I<N; I++)
{
for (J=0; J<P; J++)
printf("%7d", *((int *)C+I*50+J));
printf("\n");
}
return 0;
}

ASD (1st MI)/TD,TP - 07 Page 7 / 10 DJOUABRI(June.2018)


Exercice 10. TD
Considérez les déclarations de NOM1 et NOM2:

char *NOM1[] = {"Mohammed", "Fatima", "Ahmed",


"Iyad", "Oueiss" };

char NOM2[][16] = {" Mohammed", " Fatima", "Ahmed",


"Iyad", "Oueiss" };

a) Représenter graphiquement la mémorisation des deux variables NOM1 et NOM2.


b) Imaginez que vous devez écrire un programme pour chacun des deux tableaux qui trie les
chaînes selon l'ordre lexicographique. En supposant que vous utilisez le même algorithme de
tri pour les deux programmes, lequel des deux programmes sera probablement le plus rapide
?
Solution :

a) Représenter graphiquement la mémorisation des deux variables NOM1 et NOM2.

b)
Pour trier les chaînes du tableau de pointeurs, il faut uniquement changer les pointeurs. La durée d'une
opération d'échange est constante, peu importe la longueur des chaînes.

Pour trier le tableau de chaînes de caractères, il faut changer tous les caractères des chaînes un à un. La durée
d'une opération d'échange est dépendante de la longueur des chaînes de caractères.

Pour des chaînes de caractères d'une longueur 'normale', le tri d'un tableau de pointeurs est donc certainement
plus rapide que le tri d'un tableau de chaînes de caractères.

Exercice 11. TP
Ecrire un programme qui lit 10 mots au clavier (longueur maximale: 50 caractères) et attribue leurs
adresses à un tableau de pointeurs MOT. Copier les mots selon l'ordre lexicographique en une
seule 'phrase' dont l'adresse est affectée à un pointeur PHRASE. Réserver l'espace nécessaire à la
PHRASE avant de copier les mots. Libérer la mémoire occupée par chaque mot après l'avoir copié.
Utiliser les fonctions de <string>.
Solution :
ASD (1st MI)/TD,TP - 07 Page 8 / 10 DJOUABRI(June.2018)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
main()
{
/* Déclarations */
char INTRO[51];/* chaîne pour l'introduction des données */
char *MOT[10]; /* Tableau de pointeurs sur les 10 chaînes */
char *PHRASE; /* Pointeur cible */
int MAX; /* indice du prochain candidat à copier */
int I,J; /* indices courants */
int L; /* Longueur de la phrase */

/* Saisie des données et allocation dynamique de mémoire */


puts("Introduire 10 phrases terminées chaque fois"
" par un retour à la ligne :");
for (I=0; I<10; I++)
{
/* Lecture d'une phrase */
printf("Phrase %d : ",I);
gets(INTRO);
/* Réservation de la mémoire */
MOT[I] = malloc(strlen(INTRO)+1);
if (MOT[I])
strcpy(MOT[I], INTRO);
else
{
printf("\aPas assez de mémoire \n");
exit(-1);
}
}
/* Calcul de la longueur totale de la 'phrase' */
L=11; /* pour les espaces et le symbole de fin de chaîne */
for (I=0; I<10; I++)
L += (strlen(MOT[I])+1);
/* Réservation de la mémoire pour la 'phrase' */
PHRASE = malloc(L);
if (!PHRASE)
{
printf("\aPas assez de mémoire pour"
" mémoriser la phrase.\n");
exit(-1);
}
/* Initialisation de la PHRASE */
PHRASE[0]='\0';
/* Copier et supprimer les mots du tableau par */
/* ordre lexicographique */
for (I=0; I<10; I++)
{
/* Recherche de la dernière chaîne dans l'ordre */
/* lexicographique : Initialiser d'abord MAX avec */
/* l'indice d'une chaîne encore existante. */
for (MAX=0 ; !MOT[MAX] ; MAX++) ;
for (J=MAX; J<10; J++)
if (MOT[J] && strcmp(MOT[MAX], MOT[J])>0)
MAX=J;
/* Copier la chaîne dans la PHRASE */
strcat(PHRASE,MOT[MAX]);
strcat(PHRASE," ");
/* Suppression de la chaîne */
free(MOT[MAX]);
MOT[MAX]=0;
}
/* Affichage de la PHRASE */
puts("Résultat :");
puts(PHRASE);
return 0;
}

ASD (1st MI)/TD,TP - 07 Page 9 / 10 DJOUABRI(June.2018)


Exercice 12. TD
Pourquoi les créateurs du standard ANSI-C ont-ils décidé de légaliser les pointeurs sur le premier
élément derrière un tableau ? Donner un exemple.

Solution :

En traitant des tableaux à l'aide de pointeurs, nous utilisons souvent des expressions de la forme:

for (P=A ; P<A+N ; P++) ou for (P=CH ; *P ; P++)

{ {
... ...
} }

ou les versions analogues avec while.

Dans ces boucles, le pointeur P est incrémenté à la fin du bloc d'instruction et comparé ensuite à la condition de
la boucle. Au moment où la condition est remplie, P pointe déjà à l'extérieur du tableau; plus précisément sur le
premier élément derrière le tableau.

Exemple:

#include <stdio.h>
main()
{
/* Déclarations */
int A[10]; /* tableau */
int *P; /* pointeur dans A */

/* Saisie des données */


printf("Introduire 10 entiers : \n");
for (P=A; P<A+10; P++)
scanf("%d", P);
/* Affichage du tableau */
printf("Tableau donné A :\n");
for (P=A; P<A+10; P++)
printf("%d ", *P);
printf("\n");
return 0;
}

A la fin des boucles, P contient l'adresse A+10 et pointe donc sur l'élément A[10] qui ne fait plus partie du
tableau.

ASD (1st MI)/TD,TP - 07 Page 10 / 10 DJOUABRI(June.2018)

Vous aimerez peut-être aussi