Fonctions et prototypes
Fonctions ? What ?
Les fonctions sont les étapes à la résolution d'un problème. Quand un problème devient difficile il est bon de découper en plusieurs étapes sa résolution, afin d'éviter les erreurs fréquentes.
Imaginons que l'on veuille faire un pendu...
Pour simplifier on va imaginer que le mot mystère à découvrir est déjà généré, ce qui évite ça recherche dans un fichier ou autres.
Plusieurs étapes découlent de cette problématique:
- Générer le mot caché composé des caractères '*'
- Trouver le caractère proposé par l'utilisateur et le remplacer le caractère '*' par la lettre si trouvé, sinon rien
- Vérifier que le mot mystère est équivalent au mot caché, si oui c'est gagné, sinon on continue à deviner
Vous le voyez ci-dessus, si vous êtes observateur, ces étapes sont représentées par des verbes, ça sera la même chose en programmation et si possible en anglais
Voici une proposition de fonctions pour chacune des ces étapes:
- generate
- replace
- check
Donc garder cela en tête, une fonction est une étape à la résolution d'un problème, elle est représentée par un verbe anglais.
Vous utilisez depuis le début du cours une fonction, elle se nomme main
Code:
int main(void) { /* code */ return 0; }
Le prototype? what ?
Le prototype, c'est le plan d'une fonction, elle se représente en une seule ligne et se termine par un point virgule... On retrouve les prototypes dans les documentations du langage C, on en a besoin pour savoir plusieurs choses
- Valeur/Adresse que retourne cette fonction
- Paramètres que prend cette fonction pour être fonctionnelle
Souvenez-vous de la fonction puts, son prototype est le suivant
Code:
int puts ( const char * str );
prototype.gif
Le type de retour de la fonction:
Dans notre exemple, le type de retour est int, ce qui veut dire que cette fonction retourne (et non affiche) un entier. Retourner en informatique, est équivalent à dire valeur/adresse à enregistrer dans une variable.
Euh oui, mais puts, on enregistrait pas sa valeur de retour dans une variable, c'est mal non? Oui c'est très mal d'ignorer la valeur de retour d'une fonction, elle retourne un état indiquant si la fonction s'est bien ou mal passée.
Ce que dis la documentation, est explicite
On success, a non-negative value is returned.
On error, the function returns EOF and sets the error indicator (ferror).
En cas de succès, une valeur positive est retournée.
En cas d'erreur, le retour renvoie EOF et on peut utiliser ferror, pour en savoir plus sur l'erreur (ne faites pas attention à ferror pour l'instant).
Ok, Fred, c'est pas que je te crois pas, mais j'aimerais vérifier cela par le code... Okok, faisons ça !
Code:
#include <stdio.h> int main(void) { char result[] = "Bonjour"; int ret; /* valeur de retour de la fonction */ ret = puts(result); /* affichage du tableau de caractères result */ printf("La fonction s'est bien passée ? resultat : %d\n", ret); /* valeur positive, donc oui ça s'est bien passé */ return 0; }
Le/Les paramètre(s) de fonction:
Ok, ça roule, mais je comprend pas, la fonction puts prend en paramètre l'adresse d'un caractère, bah oui char *... Vous avez raison, modifions...
Code:
#include <stdio.h> int main(void) { char result[] = "Bonjour"; int ret; /* valeur de retour de la fonction */ ret = puts(&result[0]); /* affichage du tableau de caractères result */ printf("La fonction s'est bien passée ? resultat : %d\n", ret); /* valeur positive, donc oui ça s'est bien passé */ return 0; }
Arf, oui mais? Quoi encore ? Eh bien la fonction prend en paramètre un type const char * ... const c'est juste pour indiquer que l'on prend un type constant, qui ne sera donc pas modifiable... On peut préciser const lors de la déclaration de la fonction result.
En effet puts permet d'afficher du texte, pas besoin d'avoir un type modifiable pour notre variable en paramètre de fonction.
Code:
#include <stdio.h> int main(void) { const char result[] = "Bonjour"; int ret; /* valeur de retour de la fonction */ ret = puts(result); /* affichage du tableau de caractères result */ printf("La fonction s'est bien passée ? resultat : %d\n", ret); /* valeur positive, donc oui ça s'est bien passé */ return 0; }
Le type de retour void
Il arrive que vous n'ayez pas besoin d'enregistrer dans une variable le retour d'une fonction (exemple affichage simple d'un entier), dans ce cas, nous utiliserons le mot clé void, il indiquera que la fonction ne retourne rien !
Exemple
Code:
void display(const char chaine[]) { int ret; /* valeur de retour puts */ if ((ret = puts(chaine)) == EOF) { puts("Erreur"); /* Afficher Erreur */ exit(-1); /* Sortir du programme avec code -1 */ } }
Code:
#include <stdio.h> #include <stdlib.h> void display(const char chaine[]); int main(void) { const char result[] = "Bonjour"; display(result); /* Affiche Bonjour */ return 0; } void display(const char chaine[]) { int ret; /* valeur de retour puts */ if ((ret = puts(chaine)) == EOF) /* Si ret vaut EOF */ { puts("Erreur"); /* Afficher Erreur */ exit(-1); /* Sortir du programme avec code -1 */ } }
- La déclaration de notre prototype en début de code (simplement un copier/coller avec un point virgule à la fin de la ligne)
- La fonction display est après la fonction main
On a apprit pas mal de choses là, oufff...
Fonction sans paramètre
Une fonction sans paramètre sera indiqué par le mot clé void, exemple, ce que vous utilisez couramment
Code:
int main(void) { /* code */ return 0; }
Exemple:
Code:
void displayHello(void) { puts("Hello World !"); }
EXERCICES
Ça va se compliquer, nous allons mélanger ce qu'on a appris (boucle, pointeurs et fonctions), ça demandera sans doute lectures, relectures, refaire les exercices précédents, ...
Exercice n°1:
Compléter le code suivant permettant de transformer la chaine "bonjour" par "*******".
Code:
#include <stdio.h> void generate(const char chaine[], char *str); /* prototype de la fonction à construire */ int main(void) { const char ch[] = "bonjour"; char chaineCache[8]; generate(ch, chaineCache); puts(chaineCache); /* Affichage de "*******" sur la console */ return 0; } void generate(const char chaine[], char *str) { /* À compléter */ /* ne pas oublier le caractère de fin de chaîne '\0' */ }
Exercice n°2:
Compléter le code suivant où l'on souhaite une fonction retournant le double de la valeur en paramètre.
Code:
#include <stdio.h> /* prototype à compléter */ int main(void) { int value = 18; int result; /* variable enregistrant le résultat de la fonction foisDeux */ /* Utilisation de la fonction foisDeux à compléter */ printf("Le double de %d est %d\n", value, result); /* Le double de 18 est 36 */ return 0; } /* fonction à créer */
Merci de m'avoir lu et à bientôt pour le prochain cours
Commentaire