Les mathématiciens définissent maintenant les fonctions comme des relations, c'est-à-dire des sous-ensembles du produit cartésien de deux ensembles, qui vérifient simplement des propriétés d'existence et d'unicité (tout élément a une image et une seule).
Les informaticiens n'adoptent pas cette définition pour au moins deux raisons : d'une part, une fonction n'est pas seulement un ensemble de couples, mais est une méthode (ou algorithme) de calcul, et d'autre part une fonction, pour un argument donné, peut ne pas toujours rendre le même résultat (c'est le cas de la fonction drand48 de génération de nombres pseudo-aléatoires).
Les fonctions sont un des moyens les plus importants pour donner une structure compréhensible à un programme. On peut bien sûr écrire un programme de 10 000 lignes avec une seule fonction, main (qui est obligatoire) ; un tel programme est sûrement incompréhensible, et si par hasard il fonctionne, il sera impossible de le modifier.
On définit une fonction par son en-tête et son corps, c'est-à-dire :
Sauf quand le type du résultat est void, le corps d'une fonction contient au minimum une instruction << return expression; >> qui permet de communiquer son résultat. Quand le type du résultat est void, son corps peut contenir l'instruction << return; >>, mais ce n'est pas obligatoire.
La principale opération que l'on peut faire sur une fonction est l'appeler avec des arguments2.
On obtient la déclaration d'une fonction en omettant son corps, remplacé par un << ; >>, les noms des paramètres pouvant être omis : la fonction n'est pas définie, seulement son usage est spécifié. Par exemple, les déclarations des fonctions définies dans l'exemple du § 2 sont :
double f(double x); // avec nom de paramètre bool lancer(); double calcul_aire(int); // sans nom de paramètre int main();