VIII)Les fonctions Une fonction est un sous-programme qui reçoit éventuellement des arguments en entrée (ces arguments sont toujours des valeurs numériques) et qui retourne éventuellement une valeur d'un certain type vers la fonction appelante. L'écriture d'une fonction se fait en plusieurs étapes :
On définit ce dont elle a besoin en entrée et ce qu'elle retourne en sortie.
On écrit le prototype. Le prototype indique notamment le nombre et les types des arguments nécessaires ainsi que le type du résultat renvoyé. Le prototype est déclaré avant la définition de la fonction. Il permet au compilateur de contrôler la cohérence des appels. Cette étape n'est pas obligatoire mais le compilateur doit connaître la fonction avant qu'elle ne soit appelée. Si le programmeur ne désire pas établir de prototype, il doit coder le corps de la fonction appelée avant de coder le corps de la fonction appelante.
On écrit enfin le corps de la fonction (on code le traitement attendu). Cette définition peut être placée dans le même fichier source que la fonction appelante ou dans un autre fichier (mais il faudra indiquer au compilateur quels fichiers utiliser).
Il n'y a pas de possibilité d'imbrication des fonctions comme en Pascal.
1)Définition de fonction Syntaxe d'une fonction :
[visibilité/classe] [type_de_retour] nom-de-fonction([déclarations de paramètres]) { Instructions }
Visibilité/Classe : Cet élément sera vu dans le chapitre traitant de la visibilité et des classes d'allocation des variables.
Type de retour : Cet élément indique le type du résultat renvoyé par la fonction. Ce type peut être simple (int, char, etc.) ou plus complexe. Si la fonction ne renvoie aucun résultat, un type spécial "void" permet d'indiquer ce fait. S'il n'est pas précisé, le type d'une fonction est int par défaut.
Nom-de-Fonction : Le nom d'une fonction peut être n'importe quel identificateur valide.
Déclarations d'arguments : Ce sont les données venant de l'extérieur qui sont nécessaires à l'exécution de la fonction. Ils sont placés entre parenthèses. Avec ou sans argument les parenthèses sont obligatoires. La position des paramètres est primordiale.
Si la fonction reçoit des paramètres, ils seront déclarés sous la forme :
type , type ...
Il est bien évident que le type de l'identificateur qui stockera la valeur du paramètre reçu par la fonction doit être le même que le type de la valeur envoyée par la fonction appelante. Si tel n'est pas le cas il y aura conversion implicite si c'est possible, avec perte si le type du paramètre reçu n'est pas suffisanmment grand pour stocker le paramètre envoyé. Chaque paramètre est séparé d'un autre par une virgule. Ces paramètres sont locaux à la fonction où ils sont déclarés. Deux fonctions distinctes peuvent donc utiliser chacune des même noms de variables pour leurs paramètres. Bloc de la fonction : Celui ci commence par une accolade ouvrante et se termine par une accolade fermante (comme pour le "main()". A l'intérieur, on trouve, dans l'ordre :
La déclaration des variables locales.
Les instructions (ou blocs d'instructions) de la fonction.
2)Prototype des fonctions Placés en tête du programme (au maximum avant le codage de la première fonction), les prototypes de fonctions sont facultatifs mais ont pour intérêt :
de vérifier la validité (en quantité et qualité) des paramètres transmis aux fonctions
de ne pas être obligé de coder la fonction appelée avant la fonction appelante appelante (ce qui est impossible si deux fonctions s'appellent l'une l'autre) On écrit un prototype de fonction en écrivant
le type de la fonction
le nom de la fonction
le type des paramètres entre parenthèses séparés par une virgule (le nom des paramètres n'est pas obligatoire). Si la fonction n'a pas à recevoir de paramètre, on peut mettre le mot clef "void" dans les parenthèses ou ne rien mettre.
un point-virgule final obligatoire
Il n'y a à l'exécution aucun contrôle ni sur le nombre ni sur le type des paramètres. D'où l'intérêt d'utiliser un prototype systématique afin de détecter à la compilation les erreurs non décelées à l'exécution.
Exemple :
void fonc1(); // fonc1 ne reçoit rien et ne renvoie rien void fonc2(void); // fonc2 ne reçoit rien et ne renvoie rien (comme "fonc1") void fonc3(int); // fonc3 reçoit un "int" et ne renvoie rien float fonc4(int, char); // fonc4 reçoit un "int" et un "char" et renvoie un "float" double fonc5(void); // fonc5 ne reçoit rien et renvoie un "double" double fonc6(double); // fonc6 reçoit un double et renvoie un "double"
|