Vous êtes sur la page 1sur 4

ALGORITHMIQUE ET LANGAGE C – L1S2–MPI TD 7 – GROUPE D1

ROSELINE DESCOUT-RENIER JEUDI 20 MARS 2014

Objectifs de la séance :
• Prototypes, déclarations et appels de fonctions ;
• Types de valeur en sortie de fonction ;
• Conception d’algorithmes utilisant les fonctions.

Exercices étudiés pendant la séance : 4 – 5 – 11 TD5.

Exercice 4 :
#include <stdio.h>

/* Prototypes des fonctions - à placer avant le programme principal */


void afficheTab(int indinf, int indsup, int * tab);
void lireTab(int indinf, int indsup, int * tab);

/* Programme principal (main) */


int main(void) {
int indinf = 0, indsup = 9;
int tab[10];

/* Appels des fonctions au sein du programme principal */


lireTab(indinf, indsup, tab);
afficheTab(indinf, indsup, tab);

return 0;
}

/* Déclarations des fonctions - à placer après le programme principal */


void afficheTab(int indinf, int indsup, int * tab) {
int i;
for (i = indinf; i <= indsup; i++) {
printf("%d", tab[i]);
}
printf("\n");
}

void lireTab(int indinf, int indsup, int * tab) {


int i;
for (i = indinf; i <= indsup; i++) {
printf("\nEntrez une valeur entière :");
scanf("%d", &tab[i]);
}
}

Remarques :
• Si les déclarations de fonctions sont placées avant le programme principal, l’usage des prototypes n’est pas
nécessaire. Prendre tout de même l’habitude de rédiger les prototypes en prévision de la séparation en
plusieurs fichiers des prototypes / déclarations de fonctions / programme principal.
• Les noms de variables ne sont pas obligatoires dans les prototypes : le compilateur a seulement besoin de
connaître les types de paramètres employés par la fonction.
• Ne pas oublier le point virgule en fin de prototype.
• L’énoncé ne précise pas la taille du tableau. Ici, on a choisi un tableau de 10 cases car indinf vaut 0 et
indsup vaut 9. Mais on pouvait également choisir de définir un tableau de 9 cases, auquel cas les boucles
for doivent tester i < indsup.
Exercice 5 :
1. Analyse de la fonction pour rédiger le prototype :
• La fonction a besoin d’un nombre en entrée (de type entier) : un paramètre entier.
• La fonction doit retourner la valeur de la somme des chiffres de ce nombre : sortie de type entier.

Prototype : int sommeChiffres(int nombre) ;

2. Conception de l’algorithme :
Comment récupérer chacun des chiffres du nombre ? Grâce au reste de la division entière par 10.
Exemple : nombre 215
215 → division par 10 : 21, reste 5.
21 → division par 10 : 2, reste 1.
2 → division par 10 : 0, reste 2.
→ extraction des chiffres à additionner
On arrête le parcours de boucle lorsque le quotient de la division par 10 est nul.

3. Déclaration de la fonction :
int sommeChiffres(int nombre) {
int somme = 0;
while (nombre != 0) {
somme += nombre%10;
nombre -= nombre%10;
nombre /= 10;
}
return somme;
}

4. Fonction de type procédure, soit sans valeur retournée.


Il faut pouvoir accéder à la valeur de la somme des chiffres en sortie de fonction. Elle va donc être en paramètre de
la fonction. Les modifications sur ce paramètre doivent persister en sortie de fonction : passage par adresse.

Prototype : void sommeChiffresP (int nombre, int * pSomme) ;

Remarques :
• penser à donner des noms différents à des variables de types différents (somme ≠ pSomme) ;
• penser à donner des noms différents à des fonctions différentes (sommeChiffres ≠ sommeChiffresP) ;
• déclarer une variable dans le main et passer cette variable par adresse dans la fonction – ne pas déclarer un
pointeur qui apparaîtra comme paramètre de la fonction (erreur de compilation).

Déclaration de la fonction :
void sommeChiffresP(int nombre, int * pSomme) {
int somme = 0;
while (nombre != 0) {
somme += nombre%10;
nombre -= nombre%10;
nombre /= 10;
}
*pSomme = somme;
}
5. Code complet :

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

int sommeChiffres(int nombre) {


int somme = 0;
while (nombre != 0) {
somme += nombre%10;
nombre -= nombre%10;
nombre /= 10;
}
return somme;
}

void sommeChiffresP(int nombre, int * pSomme) {


int somme = 0;
while (nombre != 0) {
somme += nombre%10;
nombre -= nombre%10;
nombre /= 10;
}
*pSomme = somme;
}

int main(void) {
int nombre;
printf("\nEntrer un nombre entier :");
scanf("%d", &nombre);

int somme = sommeChiffres(nombre);


printf("\nLa somme des chiffres vaut %d (version fonction).", somme);

int sommeParPointeur;
sommeChiffresP(nombre, &sommeParPointeur);
printf("\nLa somme des chiffres vaut %d (version procédure).\n", sommeParPointeur);

return 0;
}

Exercice 11 :
Coordonnées cartésiennes dans le plan : deux variables (abscisse et ordonnée), de type réel (ici : flottants).
Ces coordonnées ne doivent pas changer lors de la recherche des coordonnées polaires : passage des paramètres par
valeur.

Coordonnées polaires : deux variables (rayon et azimut), de type réel.


Une fonction ne peut retourner qu’une seule valeur au maximum.
→ deux possibilités :
• une fonction pour calculer le rayon, une autre pour calculer l’angle ;
• une seule fonction pour l’ensemble, qui ne retourne rien et qui prend quatre paramètres :
◦ abscisse et ordonnée passées par valeur ;
◦ rayon et angle passés par adresse pour que les modifications apportées à ces paramètres soient
persistantes.

Remarque : continuer à séparer, au sein du programme principal, les parties Entrées / Traitements / Sorties.
Code – version une fonction par coordonnée : Code – version fonction unique :
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>

/* Prototypes des fonctions. */ /* Prototype de la fonction. */


float rayon(float x, float y); void coordPolaires(float x, float y, float * pRayon, float *
float azimut(float x, float y); pAzimut);

/* Programme principal. */ /* Programme principal. */


int main(void) { int main(void) {
float x, y; /* Coordonnées cartésiennes */ float x, y; /* Coordonnées cartésiennes */
float r, t; /* Coordonnées polaires */ float r, t; /* Coordonnées polaires */

printf("\nEntrer l'abscisse du point :"); printf("\nEntrer l'abscisse du point :");


scanf("%f", &x); scanf("%f", &x);

printf("\nEntrer l'ordonnée du point :"); printf("\nEntrer l'ordonnée du point :");


scanf("%f", &y); scanf("%f", &y);

r = rayon(x, y); coordPolaires(x, y, &r, &t);


t = azimut(x, y); printf("\nLes coordonnées polaires de ce point sont (%f,
printf("\nLes coordonnées polaires de ce point %f).\n", r, t);
sont (%f, %f).\n", r, t); return 0;
return 0; }
}
/* Déclaration des fonctions. */
/* Déclaration des fonctions. */ void coordPolaires(float x, float y, float * pRayon, float *
float rayon(float x, float y) { pAzimut) {
float r; float r, t;
r = sqrt(x*x + y*y); /* Calcul du rayon */
return r; r = sqrt(x*x + y*y);
} /* Calcul de l'azimut */
float azimut(float x, float y) { if (x > 0) {
float t; if (y >= 0) {
if (x > 0) { t = atan(y/x);
if (y >= 0) { }
t = atan(y/x); else {
} t = 2*M_PI + atan(y/x);
else { }
t = 2*M_PI + atan(y/x); }
} else if (x < 0) {
} t = M_PI + atan(y/x);
else if (x < 0) { }
t = M_PI + atan(y/x); else if (y > 0) {
} t = M_PI / 2;
else if (y > 0) { }
t = M_PI / 2; else if (y < 0) {
} t = 3*M_PI / 2;
else if (y < 0) { }
t = 3*M_PI / 2; else {
} t = 0;
else { printf("\nProblème de définition de thêta : valeur fixée à 0.");
t = 0; }
printf("\nProblème de définition de thêta : /* Affectation aux adresses des variables entrées en paramètres
valeur fixée à 0."); modifiables 3 et 4 de la fonction */
} *pRayon = r;
return t; *pAzimut = t;
} }