pdf - e-book - archive - github.com

2.8  Pointeurs

2.8.1  Aliasing

Exercice 1

Ecrivez un programme déclarant une variable i de type int et une variable p de type pointeur sur int. Affichez les dix premiers nombres entiers en :

Exercice 2

Même exercice en

Exercice 3

Déterminez ce qu’affiche ce programme, exécutez-ensuite pour vérifier.

#include<stdio.h>

main()
{
  int i = 4;
  int j = 10;
  int* p;
  int* q;
  p = &i;
  q = &j;
  printf("i = %d, j = %d, p = %d, q = %d\n", i, j, *p, *q);
  *p = *p + *q;
  printf("i = %d, j = %d, p = %d, q = %d\n", i, j, *p, *q);
  p = &j;
  printf("i = %d, j = %d, p = %d, q = %d\n", i, j, *p, *q);
  *q = *q + *p;
  printf("i = %d, j = %d, p = %d, q = %d\n", i, j, *p, *q);
  q = &i;
  printf("i = %d, j = %d, p = %d, q = %d\n", i, j, *p, *q);
  i = 4;
  printf("i = %d, j = %d, p = %d, q = %d\n", i, j, *p, *q);
  *q = *q + 1;
  printf("i = %d, j = %d, p = %d, q = %d\n", i, j, *p, *q);
}

Télécharger le fichier

2.8.2  Tableaux

Exercice 4 prise en main

Ecrire un programme qui place dans un tableau t les N premiers nombres impairs, puis qui affiche le tableau. Vous accéderez à l’élément d’indice i de t avec l’expression *(t + i).

Exercice 5 Tri à bulle

Ecrire un sous-programme triant un tableau t avec la méthode du tri à bulle. Vous accéderez à l’élément d’indice i de t avec l’expression *(t + i).

2.8.3  Exercices sans sous-programmes

Exercice 6 Tableaux de carrés

Ecrire un programme qui demande à l’utilisateur de saisir un nombre n, et qui place les n premiers nombres impairs dans un tableau t. Utilisez ensuite le fait que k2 est la somme des k premiers nombres impairs pour calculer puis afficher les n premiers nombres carrés.

Corrigé

Exercice 7 Matrices et pointeurs de pointeurs

Ecrivez un programme qui demande à l’utilisateur de saisir un nombre n et qui crée une matrice T de dimensions n × n avec un tableau de n tableaux de chacun n éléments. Nous noterons tij le j-ème élément du i-ème tableau. Vous initialiserez T de la sorte : pour tous i, j, tij = 1 si i = j (les éléments de la diagonale) et tij = 0 si ij (les autres éléments). Puis vous afficherez T.

Corrigé

Exercice 8 Copie de chaînes de caractères

Ecrivez un programme qui saisit proprement une chaîne de caractère s et qui la recopie dans un tableau crée avec malloc et de contenance correspondant exactement à la longueur de s. Vous n’utiliserez ni strlen, ni strcpy.

Corrigé

Exercice 9 Tableau de chaînes

Reprennez le programme précédent en saissisant successivement 4 chaînes de caractères et en les stockant dans un tableau de chaînes de caractères.

Corrigé

2.8.4  Allocation dynamique

Exercice 10 Prise en main

Créez dynamiquement un int, affectez-y la valeur 5, affichez-le, libérez la mémoire.

Exercice 11 Tableaux sur mesure

Demandez à l’utilisateur la taille du tableau qu’il souhaite créer, allouez dynamiquement l’espace nécessaire et placez-y les valeurs {0, …  n−1}, affichez-le et libérez la mémoire.

2.8.5  Pointeurs et pointeurs de pointeurs

Exercice 12 Tableaux sur mesure

Qu’affiche le programme suivant :

#include<stdio.h>

int main()
{
  long A, B, C, D;
  long *p1, *p2, *p3;
  long **pp;
  A = 10 ; 
  B = 20 ; 
  C = 30 ; 
  D = 40;
  p1 = &A;
  p2 = &B;
  p3 = &B;
  *p1 = (*p1 + 1);
  *p3 = (*p2 + D);
  p3 = &C;
  *p3 = (*p2 + D);
  printf("A = %ld, B = %ld, C = %ld, D = %ld\n", A, B, C, D);
  pp = &p3;
  printf("%ld\n", **pp);
  return 0;
}

Télécharger le fichier

2.8.6  Passages de paramètres par référence

Exercice 13

Déterminez ce qu’affiche ce programme, exécutez-ensuite pour vérifier.

#include<stdio.h>

void affiche2int(int a, int b)
{
  printf("%d, %d\n", a, b);
}

void incr1(int x)
{
  x = x + 1;
}

void incr2(int* x)
{
  *x = *x + 1 ;
}

void decr1(int* x)
{
  x = x - 1;
}

void decr2(int* x)
{
  *x = *x - 1;
}

int main()
{
  int i = 1;
  int j = 1;
  affiche2int(i, j);
  incr2(&i);
  affiche2int(i, j);
  decr1(&j);
  affiche2int(i, j);
  decr2(&j);
  affiche2int(i, j);
  while(i != j)
    {
      incr1(j);
      decr2(&i);
    }
  affiche2int(i, j);
  return 0;
}

Télécharger le fichier

Exercice 14

Ecrivez le corps du sous-programme additionne, celui-ci doit placer dans res la valeur i + j.

#include<stdio.h>

void additionne(int a, int b, int* res)
{
  /* Ecrivez le corps du sous-programme ici */
    

}

int main()
{
  int i = 2;
  int j = 3;
  int k;
  additionne(i, j, &k);
  printf("k = %d\n", k); // doit afficher "k = 5"
  return 0;
}

Télécharger le fichier

Exercice 15

Ecrivez le sous-programme void puissance(int b, int n, int* res), qui place dans la variable pointée par res le résultat de bn.

Exercice 16

Ecrivez le sous-programme void tri(int* a, int* b, int*\ c) qui permute les valeurs de *a, *b et *c de sorte que *a ≤ *b ≤ *c. Vous utiliserez le sous-programme void echange(int* x, int* y).

2.8.7  Les pointeurs sans étoile

Le but de cet exercice est d’encapsuler les accès à la mémoire par le biais des pointeurs dans des fonctions. Ecrivez le corps des fonctions suivantes :

  1. int getIntVal(int* p) retourne la valeur se trouvant à l’adresse p.
  2. void setIntVal(int* p, int val) affecte la valeur val à la variable pointée par p.
  3. int* getTiAdr(int* t, int i) retourne l’adresse de l’élément T[i]
  4. int getTiVal(int* t, int i) retourne la valeur de l’élément T[i], vous utiliserez getTiAdr et getIntVal
  5. void setTiVal(int* t, int i, int val) affecte à T[i] la valeur val, vous utiliserez getTiAdr et setIntVal.
  6. void swapInt(int* a, int* b) échange les valeurs des variables pointées par a et b. Vous utiliserez getIntVal et setIntVal.
  7. void swapTij(int* t, int i, int j) échange les valeurs T[i] et T[j], vous utiliserez swapInt et getTiAdr.

Ecrivez le corps de la fonction de tri void sort(int* t, int n) de votre choix en utilisant au mieux les fonctions ci-dessus.

2.8.8  Tableau de tableaux

Le but de cet exercice est de créer n tableaux de chacun m éléments, de placer les n pointeurs ainsi obtenus dans un tableau de pointeurs T de type int** et de manier T comme un tableau à deux indices. Ecrivez les corps des fonctions suivantes :

  1. int** getTi_Adr(int** T, int i) retourne l’adresse du pointeur vers le i-ème tableau d’int de T.
  2. int* getTi_(int** T, int i) retourne le i-ème tableau d’int de T, vous utiliserez getTi_Adr.
  3. void setT__Adr(int** T, int* p) place dans la variable pointée par T le pointeur p.
  4. void setTi_(int** T, int i, int* p) fait de p le i-ème tableau de T, vous utiliserez getT__Adr et setTi_Adr
  5. void createT__(int** T, int n, int m) fait pointer chacun des n éléments de T vers un tableau à m éléments. Vous utiliserez setTi_Adr.

Nous noterons Tij le j-ème élément du tableau T[i]. Pour tous (i, j) ∈ {1, …, 10}2, le but est de placer dans tij la valeur 10i + j. Vous utiliserez les fonctions int getIntVal(int* p), void setIntVal(int* p, int val), int* getTiAdr(int* t, int i), int getTiVal(int* t, int i) et void setTiVal(int* t, int i, int val) pour écrire les corps des sous-programmes ci-dessous :

  1. int* getTijAdr(int** t, int i, int j) retourne l’adresse de Tij
  2. int getTijVal(int** t, int i, int j) retourne la valeur de Tij
  3. void setTijVal(int** t, int i, int j, int val) affecte à Tij la valeur val.

2.8.9  Triangle de Pascal

En utilisant les sous-programmes ci-dessus, ecrire un programme qui demande à l’utilisateur un nombre n, puis qui crée un triangle de Pascal à n+1 lignes, et qui pour finir affiche ce triangle de Pascal. Vous utiliserez les sous-programmes définis dans les questions précédentes et rédigerez des sous-programmes les plus simples possibles (courts, le moins d’étoiles possible).

Corrigé

2.8.10  Pointeurs et récursivité

Vous rédigerez toutes les fonctions suivantes sous forme itérative, puis récursive.

  1. Ecrire une fonction void initTab(int* t, int n) plaçant dans le tableau t les éléments 1, 2, …, n.
  2. Ecrire une fonction void printTab(int* t, int n) affichant les n éléments du tableau t.
  3. Ecrire une fonction int sommeTab(int* t, int n) retournant la somme des n éléments du tableau t.
  4. Ecrire une fonction (ni récursive, ni itérative) void swap(int* t, int i, int j) échangeant les éléments d’indices i et j du tableau t.
  5. Ecrire une fonction void mirrorTab(int* t, int n) inversant l’ordre des éléments du tableau t.
  6. Ecrire une fonction int find(int* t, int n, int x) retournant 1 si x se trouve dans le tableau t à n éléments, 0 sinon.
  7. Ecrire une fonction int distinctValues(int* t, int n) retournant le nombre de valeurs distinctes du tableau t à n éléments. Le nombre de valeurs distinctes s’obtient en comptant une seule fois chaque valeur du tableau si elle apparaît plusieurs fois. Par exemple, les valeurs distinctes de {1, 2, 2, 3, 9, 4, 3, 7} sont {1, 2, 3, 4, 7, 9} et il y en a 6.

Corrigé

En utilisant les exercices sur les heures dans la section structures, vous rédigerez les fonctions suivantes sous forme récursive.

  1. Ecrire une fonction void afficheTabHeures(heure_t* t, int n) affichant les n heures de t.
  2. Ecrire une fonction void initTabHeures(heure_t* t, int n, heure_t depart, heure_t pas) initialisant le tableau t à n éléments comme suit : la première heure est depart et chaque heure s’obtient à additionnant pas à la précédente.
  3. Ecrire une fonction heure_t sommeTabHeures(heure_t* t, int n) retournant la somme des n heures du tableau t.
  4. Ecrire une fonction heure_t minTabHeure(heure_t* t, int n) retournant la plus petite des n heures du tableau t.

2.8.11  Tri fusion

Complétez le code suivant :

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define MOD 10000

/*********************************************/

/*
  Affiche les n elements du tableau t.
*/

void printTab(int* t, int n)
{
  if (n > 0)
    {
      printf("%d ", *t);
      printTab(t + 1, n - 1);
    }
  else
    printf("\n");
}

/*********************************************/

/*
  Place n elements aleatoires de valeurs maximales
  MOD - 1 dans le tableau t.
*/

void initTab(int* t, int n)
{
  if (n > 0)
    {
      *t = rand()%MOD;
      initTab(t + 1, n - 1);
    }
}

/*********************************************/

/*
  Retourne un tableau de n 
  elements alloue dynamiquement.
*/

int* createTab(int n)
{
  int* t = (int*)malloc(sizeof(int)*n);
  if (t == NULL)
    {
      printf("no memory avalaible\n");
      exit(0);
    }
  return t;
}

/*********************************************/

/*
  Libere la zone memoire pointee par *t 
  et met ce pointeur a NULL.
*/

void destroyTab(int** t)
{
  free(*t);
  *t = NULL;
}

/*********************************************/

/*
  (Recursive) 
  Retourne l'indice du plus petit
  element du tableau t a n elements. 
  Affiche une erreur si le tableau est vide.
*/

int indexOfMin(int* t, int n)
{
  return 0;
}

/*********************************************/

/*
  Echange les elements *x et *y.
*/

void swap(int* x, int* y)
{
  int temp = *x;
  *x = *y;
  *y = temp;
}

/*********************************************/

/*
  Echange le plus petit element du tableau 
  t a n elements avec le premier.
*/

void swapMin(int* t, int n)
{
}

/*********************************************/

/*
  (Recursive)
  Trie le tableau t a n elements avec la 
  methode du tri par selection.
*/

void selectionSort(int* t, int n)
{
}

/*********************************************/

/*
  (Recursive)
  Recopie les n elements du tableau source 
  a l'adresse dest.
 */

void copyTab(int* source, int* dest, int n)
{
}

/*********************************************/

/*
  (Recursive)
  Interclasse les n1 elements de source1 avec les n2 elements de source2.
  source1 et source2 sont supposes tries. L'interclassement se fait 
  en disposant ces elements dans l'ordre dans le tableau dest.
*/

void shuffleTab(int* source1, int* source2, int* dest, 
  int n1, int n2)
{
}

/*********************************************/

/*
  Trie les n elements de t avec la methode du tri fusion.
*/

void fusionSort(int* t, int n)
{
}

/*********************************************/
 
/*
  Compare les performances en temps de calcul 
  des tris par selection et par fusion.
*/

int compareSorts(int firstValue, int lastValue, int step)
{
  int i;
  int start, stop;
  int *t, *q;
  srand(time(NULL));
  for(i = firstValue ; i <= lastValue ; i += step)
    {
      printf("with %d elements : \n", i);
      t = createTab(i);
      q = createTab(i);
      initTab(t, i);
      copyTab(t, q, i);
      start = time(NULL);
      selectionSort(t, i);
      stop = time(NULL);
      printf("* selection sort : %d\n", stop - start);
      destroyTab(&t);
      start = time(NULL);
      fusionSort(q, i);
      stop = time(NULL);
      printf("* fusion sort : %d\n", stop - start);
      destroyTab(&q);
    }
  return 0;
}

/*********************************************/
 
/*
  Pour tester les fonctions au fur et a mesure qu'elles sont 
  ecrites...
*/

int main()
{
  compareSorts(10000, 500000, 1000);
  return 0;
}

Télécharger le fichier

Corrigé