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
destring.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 lemain()
seront soit demandés à l'utilisateur avec unscanf()
, 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 indicesi
etj
, et échange le contenu de la casei
avec le contenu de la casej
.
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 particulierint 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¶
- Lire cette présentation au moins jusqu'au transparent 13.
- Lire cette présentation au moins juqu'au transparent 18.
- Lire ce tutoriel au moins jusqu'à l'étape 7.
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.