Skip to content

TP3 : Tableaux et pointeurs

Manipulation de Tableaux et chaînes de caractères

Ecrivez les fonctions suivantes, n'oubliez pas d'écrire une fonction main() permettant de les tester. Les arguments devant être fournis aux fonctions par le main() seront soit demandés à l'utilisateur avec un scanf(), soit rentrés sur la ligne de commande.

  • Écrire une fonction qui prend un tableau d'entiers et renvoie le plus grand élément.
  • Écrire une fonction qui prend deux tableaux d'entiers et recopie le premier dans le second. Réfléchissez aux paramètres pour gérer correctement les cas où les deux tableaux ne font pas la même taille.
  • Ecrire une fonction qui prend trois tableaux d'entiers et recopie le 2e puis le 3e dans le 1er.

Conseil

Vous pouvez (devez ?) vous servir de la fonction précédante.

  • Écrire une fonction qui renvoie le nombre de caractères d'une chaine de caractères (sans utiliser la fonction strlen de string.h)
  • Écrire une fonction qui prend deux chaines de caractères et renvoie la taille du plus long prefixe commun

Exemple

pour "avion" et "aviation", la fonction renvoie 3 car le plus long prefixe commun est "avi".

Pointeurs : All IN!

  • Écrire la fonction all_in() qui prend en paramètre un entier. Cette fonction tire un nombre aléatoire, si celui ci est pair, l'entier passé en paramètre doit être doublé, sinon il est divisé par 2. La fonction doit renvoyer l'information gagné ou perdu (1 ou 0). L'entier sur lequel travailler est donc passé par adresse à la fonction, puisque le retour est déjà utilisé pour autre chose.

Nombre aléatoire

Pour obtenir un nombre "aléatoire", on peut utiliser les deux fonctions srandom() et random(). À chaque appel, random() renverra un nouvel entier, qui paraitra aléatoire. Les entiers renvoyés constituent en réalité une suite périodique avec une période très large. On peut paramètrer la génération de cette suite avec une graine grâce à la fonction srandom(). L'astuce consiste alors à utiliser comme graine une quantité aléatoire, comme le nombre de secondes écoulées depuis le 1er janvier 1970, que renvoit la fonction time() (lui donner la valeur spéciale de pointeur NULL en paramètre).

  • Ecrivez une fonction main() permettant de tester. Les arguments devant être fournis aux fonctions par le main() seront soit demandés à l'utilisateur avec un scanf(), soit rentrés sur la ligne de commande.

Pointeurs et Tableaux

Le but est d'écrire une fonction swap() qui prend deux arguments et permet d'inverser le contenu de deux variables entières.

Exemple de code appelant :

int main()

{

  int a = 3;

  int b = 4;

  /* appel de swap() a completer */

  printf("a=%d, b=%d\n",a,b); /* doit afficher a=4, b=3 */

  return 0;

}

Etape 1

  • Ecrire une fonction swap_tab() qui prend en paramètre un tableau d'entiers (tab) et deux indices i et j, et échange le contenu de la case i avec le contenu de la case j.

Note

En principe une fonction qui prend en paramètre un tableau prend aussi la taille en paramètre. Ici ce n'est pas nécessaire car on ne travaillera qu'avec les cases i et j, et ces indices sont fournis en paramètre.

  • Ecrire une fonction main() correspondante qui appelle votre fonction avec un tableau de taille 2 et les indices 0 et 1.

Etape 2

Transformez le code de votre fonction swap_tab() selon les règles d'équivalance que vous avez apprises en cours,

Rappel

  • Dans le prototypde de la fonction : int tab[] <=> int * tab (attention au cas particulier int tab[] = {...)
  • Dans le corps de la fonction : tab[toto] <=> *(tab+toto)

Etape 3

On peut maintenant ecrire swap() : la fonction sera très similaire à swap_tab(), sauf qu'au lieu de prendre en paramètre un pointeur (tab dans l'exemple précédant) et deux indices de décalages (i et j), elle prendra directement en paramètre deux pointeurs, par exemple p1 et p2.

Tip

Au lieu d'écrire *(tab+i), on écrira donc *p1 et au lieu d'écrire *(tab+j) on écrira *p2.

Etape 4

Il ne reste plus qu'a changer le code appelant. On a plus besoin de creer un tableau, mais simplement de déclarer deux entiers et de passer leurs adresses comme paramètres à la fonction.

Bilan :

Dessinez la pile mémoire lors de l'appel à swap_tab() et lors de l'appel à swap()

Structures

Complexes

Ecrire, dans un fichier complex.h, la définition d'un nombre complexe sous la forme d'un type structuré. Déclarer également les prototypes des fonctions suivantes :

  • new_complex qui crée un nombre complexe en prenant les parties réelle et imaginaire comme paramètres;
  • print_complex qui affiche, sur la sortie standard, un nombre complexe de la façon suivante : la partie réelle suivie d'un espace puis de la partie imaginaire;
  • sum qui calcule la somme de deux nombres complexes;
  • conjugate qui calcule le conjugué d'un nombre complexe;
  • norm qui calcule la norme d'un nombre complexe.

Implémenter dans un fichier complex.c, les fonctions précédentes. Tester votre code en créant un fichier test.c où seront implémentés des tests. Ne pas oublier de faire un Makefile pour compiler vos sources. Vous pouvez vous inspirer du template de Makefile, issu de l'étape 7 ou 8 du tutoriel.