Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
predicats [2014/09/01 12:52] gbdivers |
predicats [2019/02/21 23:04] (Version actuelle) alavida Corps de la fonction lambda est entre les accolades et non entre les crochets |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ^ Chapitre précédent ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ Chapitre suivant ^ | + | ^ [[autres_collections|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[bitset|Chapitre suivant]] ^ |
- | ====== Les foncteurs ====== | + | |
+ | ====== Les foncteurs et fonctions lambdas ====== | ||
__foncteur ? fonction objet ? opérateur ? autre ? __ | __foncteur ? fonction objet ? opérateur ? autre ? __ | ||
Ligne 20: | Ligne 21: | ||
Cet algorithme est dit "modifiant" puisqu'il modifie directement le conteneur sur lequel on applique la fonction. | Cet algorithme est dit "modifiant" puisqu'il modifie directement le conteneur sur lequel on applique la fonction. | ||
- | Fondamentalement, cet algorithme fonctionne de la façon suivante : il parcourir les éléments de la collection et réalise des tests de comparaison par paire d'éléments. Pour faire cette comparaison, l'algorithme utilise l'opérateur de comparaison ''<'' sur les éléments. Par exemple, pour faire le trie d'un tableau d'entiers (''vector<int>''), l'algorithme réaliser des comparaisons d'entiers (''valeur 1 < valeur 2''). | + | Fondamentalement, cet algorithme fonctionne de la façon suivante : il parcourt les éléments de la collection et réalise des tests de comparaison par paire d'éléments. Pour faire cette comparaison, l'algorithme utilise l'opérateur de comparaison ''<'' sur les éléments. Par exemple, pour faire le tri d'un tableau d'entiers (''vector<int>''), l'algorithme réalise des comparaisons d'entiers (''valeur 1 < valeur 2''). |
- | Dit autrement, cela veut dire que si on utilise un ''vector<un_type>'', il faut que la comparaison ''<'' est un sens pour ce type ''un-type'' (ce qui sera le cas avec la majorité des types de base du C++). | + | Dit autrement, cela veut dire que si on utilise un ''vector<un_type>'', il faut que la comparaison ''<'' ait un sens pour ce type ''un_type'' (ce qui sera le cas avec la majorité des types de base du C++). |
On dit que l'opérateur ''<'' est le prédicat utilisé par l'algorithme de trie ''std::sort''. Plus généralement, un prédicat est une expression qui retourne un booléen (''true'' ou ''false''). Les différents algorithmes de la bibliothèque standard n'utilisent pas tous l'opérateur ''<'', certains utilisent l'opérateur d'égalité ''=='', d'autres n'utilisent pas de prédicat. | On dit que l'opérateur ''<'' est le prédicat utilisé par l'algorithme de trie ''std::sort''. Plus généralement, un prédicat est une expression qui retourne un booléen (''true'' ou ''false''). Les différents algorithmes de la bibliothèque standard n'utilisent pas tous l'opérateur ''<'', certains utilisent l'opérateur d'égalité ''=='', d'autres n'utilisent pas de prédicat. | ||
- | Imaginons maintenant que l'on souhaite trier une collection dans l'ordre inverse, c'est-à-dire du plus grand au plus petit. Une première solution serait de trier dans l'ordre par défaut (plus petit au plus grand), puis d'inverser l'ordre des éléments. Une autre solution serait de réécrire un algorithme de trie (appelé ''reverse_sort'' par exemple) et qui trie dans l'ordre inverse (du plus grand au plus petit). | + | Imaginons maintenant que l'on souhaite trier une collection dans l'ordre inverse, c'est-à-dire du plus grand au plus petit. Une première solution serait de trier dans l'ordre par défaut (plus petit au plus grand), puis d'inverser l'ordre des éléments. Une autre solution serait de réécrire un algorithme de tri (appelé ''reverse_sort'' par exemple) et qui trie dans l'ordre inverse (du plus grand au plus petit). |
- | Ces deux solutions ne sont pas correctes en termes de C++ moderne. La première est inutilement plus compliqué (il faut écrire deux lignes au lieu d'une seule), la seconde demande de réécrire l'algorithme de trie. | + | Ces deux solutions ne sont pas correctes en termes de C++ moderne. La première est inutilement plus compliqué (il faut écrire deux lignes au lieu d'une seule), la seconde demande de réécrire l'algorithme de tri. |
===== Les foncteurs de la bibliothèque standard ===== | ===== Les foncteurs de la bibliothèque standard ===== | ||
Ligne 92: | Ligne 93: | ||
</code> | </code> | ||
- | Pour bien comprendre la différence entre les différents types de fonction, revoyons les différentes syntaxes pour créer une variable (nommée ''object'') d'un type donné (''MyObject'') et sur laquelle nous appliquons une fonction : | + | Pour bien comprendre la différence entre les divers types de fonction, revoyons les multiples syntaxes pour créer une variable (nommée ''object'') d'un type donné (''MyObject'') et sur laquelle nous appliquons une fonction : |
<code cpp> | <code cpp> | ||
Ligne 128: | Ligne 129: | ||
* ''isprint'' (caractère affichable) ; | * ''isprint'' (caractère affichable) ; | ||
* ''ispunct'' (ponctuation). | * ''ispunct'' (ponctuation). | ||
- | * les fonctions de modification (//Character manipulation) : | + | * les fonctions de modification (//Character manipulation//) : |
* ''tolower'' (convertie en minuscule) ; | * ''tolower'' (convertie en minuscule) ; | ||
* ''toupper'' (converti en majuscule). | * ''toupper'' (converti en majuscule). | ||
Ligne 137: | Ligne 138: | ||
#include <iostream> | #include <iostream> | ||
#include <string> | #include <string> | ||
- | #include <cctype> | + | #include <algorithm> |
int main() { | int main() { | ||
Ligne 154: | Ligne 155: | ||
==== Exercices ==== | ==== Exercices ==== | ||
- | * tirer avec d'autres prédicats | + | * trier avec d'autres prédicats |
* combiner des prédicats | * combiner des prédicats | ||
Ligne 163: | Ligne 164: | ||
Il est important que vous sachiez créer des fonctions, c'est un point fondamental en C++, vous les utiliserez dans tous vos codes. Et plus important, ce qui sera fondamental est de savoir découper correctement les problèmes complexes en fonctions plus simples. Ce chapitre ne sera pas suffisant pour étudier toutes les possibilités offertes par les fonctions, nous reviendrons dessus en détail par la suite. Cette partie se focalise sur l'utilisation simple des fonctions lambdas avec les algorithmes de la bibliothèque standard. | Il est important que vous sachiez créer des fonctions, c'est un point fondamental en C++, vous les utiliserez dans tous vos codes. Et plus important, ce qui sera fondamental est de savoir découper correctement les problèmes complexes en fonctions plus simples. Ce chapitre ne sera pas suffisant pour étudier toutes les possibilités offertes par les fonctions, nous reviendrons dessus en détail par la suite. Cette partie se focalise sur l'utilisation simple des fonctions lambdas avec les algorithmes de la bibliothèque standard. | ||
- | Les fonctions lambdas sont une technique issue de la programmation fonctionnelle. Vous avez déjà utiliser des fonctions (membres ou libres) et vous avez déjà définit une fonction : la fonction ''main''. Pour rappel, une fonction permet de réaliser une tâche particulière et est constituée de : | + | Les fonctions lambdas sont une technique issue de la programmation fonctionnelle. Vous avez déjà utilisé des fonctions (membres ou libres) et vous avez déjà défini une fonction : la fonction ''main''. Pour rappel, une fonction permet de réaliser une tâche particulière et est constituée de : |
* un nom de fonction (''main'') ; | * un nom de fonction (''main'') ; | ||
Ligne 185: | Ligne 186: | ||
<note info>''Programmation fonctionnelle''</note> | <note info>''Programmation fonctionnelle''</note> | ||
- | Une fonction lambda est une fonction particulière. Elle n'a pas de nom et peut être déclarée dans le corps d'une autre fonction. A part cela, elle se comporte comme une fonction classique et peut recevoir des arguments, retourner une valeur. Il existe plusieurs façon d'écrire des fonctions lambdas, mais comme nous les utilisons ici dans les algorithmes de la bibliothèques standard, il est nécessaire de respecter la signature imposée par les algorithmes. | + | Une fonction lambda est une fonction particulière. Elle n'a pas de nom (elle est dite anonyme) et peut être déclarée dans le corps d'une autre fonction. A part cela, elle se comporte comme une fonction classique et peut recevoir des arguments, retourner une valeur. Il existe plusieurs façon d'écrire des fonctions lambdas, mais comme nous les utilisons ici dans les algorithmes de la bibliothèques standard, il est nécessaire de respecter la signature imposée par les algorithmes. |
La définition d'une fonction lambda se décompose en trois parties : | La définition d'une fonction lambda se décompose en trois parties : | ||
Ligne 217: | Ligne 218: | ||
</code> | </code> | ||
- | Le corps de la fonction lambda (entre les crochets) peut contenir plusieurs lignes (séparées par un point-virgule), déclarer des variables, appeler d'autres fonctions, etc. Bref, vous pouvez mettre dans le corps d'une fonction lambda toutes les instructions que vous souhaitez. | + | Le corps de la fonction lambda (entre les accolades) peut contenir plusieurs lignes (séparées par un point-virgule), déclarer des variables, appeler d'autres fonctions, etc. Bref, vous pouvez mettre dans le corps d'une fonction lambda toutes les instructions que vous souhaitez. |
Pour écrire une fonction lambda qui prend deux paramètres, compare les valeurs et retourne un booléen, on peut donc écrire : | Pour écrire une fonction lambda qui prend deux paramètres, compare les valeurs et retourne un booléen, on peut donc écrire : | ||
Ligne 276: | Ligne 277: | ||
* trier selon la valeur absolue | * trier selon la valeur absolue | ||
- | ^ Chapitre précédent ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ Chapitre suivant ^ | ||
- | {{tag> Cours C++}} | + | ^ [[autres_collections|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[bitset|Chapitre suivant]] ^ |