définition-de-fonction :
type identificateur ( liste-de-déclarations-de-paramètres )
{
liste-de-déclarationsoption
liste-d'instructions
}
Note
type est le type de la valeur rendue par la fonction ;
identificateur est le nom de la fonction ;
liste-de-déclarations-de-paramètres
est la liste (séparés par des virgules) des déclarations des paramètres formels.
La liste-de-déclarationsoption permet si besoin est,
de déclarer des variables qui seront locales à la fonction,
elles seront donc inaccessibles de l'extérieur.
La liste-d'instructions est l'ensemble des instructions
qui seront exécutées sur appel de la fonction.
Parmi ces instructions,
il doit y avoir au moins une instruction du type :
return expression ;
Lors de l'exécution d'une telle instruction, expression est évaluée,
et le contrôle d'exécution est rendu à l'appelant de la fonction.
La valeur rendue par la fonction est celle de expression.
int sum_square(int i,int j) /* la fonction sum_square délivre un int */ /* ses paramètres formels sont les int i et j */ { int resultat; /* déclaration des variables locales */ resultat = i*i + j*j; return(resultat); /* retour a l'appelant en délivrant résultat */ }
int max(int i,int j) /* la fonction max délivre un int */ /* ses paramètres formels sont les int i et j */ { /* pas de variables locales pour max */ if (i > j) return(i); else return(j); }
Si la dernière instruction exécutée par une fonction n'est pas une instruction return, la valeur rendue par la fonction est indéterminée.
void
est mis en tant que liste-de-déclarations-de-paramètres.
Exemple :
double pi(void) /* pas de paramètres formels */ { /* pas de variables locales */ return(3.14159); }
int i; int j;Mais on peut aussi n'utiliser qu'une déclaration pour déclarer les deux variables :
int i,j;Cette possibilité n'existe pas pour une liste de paramètres formels. Il n'est pas possible d'écrire
max
de la manière suivante :
int max(int i,j) /* incorrect */ { ... }
expression :
identificateur ( liste-d'expressions )
Les expressions de liste-d'expressions sont évaluées, puis passées en tant que paramètres effectifs à la fonction de nom identificateur, qui est ensuite exécutée. La valeur rendue par la fonction est la valeur de l'expression appel de fonction.
{ int a,b,m,s; double d; s = sum_square(a,b); /* appel de sum_square */ m = max(a,b); /* appel de max */ d = pi(); /* appel de pi */ }
void
en tant
que paramètre effectif.
d = pi(void); /* appel incorrect de pi */
sum_square(f(x),g(y));La fonction
g
sera peut-être exécutée avant f
.
Lors de l'appel de la procédure, il faudra ignorer la valeur rendue c'est à dire ne pas l'englober dans une expression.
void print_add(int i,int j) /* la procédure et ses paramètres formels */ { int r; /* une variable locale à print_add */ r = i + j; ... /* instruction pour imprimer la valeur de r */ } void prints(void) /* une procédure sans paramètres */ { int a,b; /* variables locales à prints */ a = 12; b = 45; print_add(a,b); /* appel de print_add */ print_add(13,67); /* un autre appel à print_add */ }
int facto(int n) { if (n == 1) return(1); else return(n * facto(n-1)); }
extern int sum_square(int i, int j);Le cas le plus courant d'utilisation de fonction définie ailleurs est l'utilisation des fonctions de la bibliothèque standard. Avant d'utiliser une fonction de la bibliothèque standard, il faudra donc la déclarer en fonction externe. Il y a une méthode permettant de faire cela de manière automatique grâce au mécanisme d'inclusion de source du préprocesseur. Cela est expliqué dans la documentation de chaque fonction.
#include <math.h> double cos(double x);Il faut comprendre que le fichier
math.h
contient un ensemble de
définitions nécessaires à l'utilisation de cos
,
en particulier la déclaration de cos en fonction externe, à savoir :
extern double cos(double x);Il faut donc inclure le fichier
math.h
avant toute utilisation de la
fonction cos.
int sum_square(i,j) /* liste des noms des paramètres formels */ int i, int j; /* déclaration du type des paramètres */ { int resultat; resultat = i*i + j*j; return(resultat); }
En ce qui concerne la déclaration de fonction externe, il faut préfixer avec le mot-clé extern, l'en-tête de la fonction débarrassée de la liste des noms des paramètres, comme ceci :
extern int sum_square();
Dans ce cas, le compilateur ne connaît pas le type des paramètres de la fonction, il lui est donc impossible de détecter une erreur portant sur le type des paramètres lors d'un appel de fonction externe. Cette situation est assez catastrophique et c'est la raison pour laquelle le comité de normalisation a introduit le concept de prototype de fonction vu au chapitre 1.15.1. Il n'a cependant pas voulu faire un changement incompatible, il a donc décidé que les deux méthodes étaient acceptées, en précisant toutefois que la méthode K&R était une caractéristique obsolescente. En clair, cela signifie que cette méthode sera abandonnée dans la prochaine révision de la norme, si prochaine révision il y a.