Outils d'utilisateurs

Outils du Site


collection2

Différences

Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.

Lien vers cette vue

collection2 [2016/03/28 04:44]
gbdivers
collection2 [2019/04/08 22:55] (Version actuelle)
foxdry42 [Suppression]
Ligne 5: Ligne 5:
 ====== Les fonctionnalités de base des collections ====== ====== Les fonctionnalités de base des collections ======
  
-Le chapitre précédent présentait chaque collection et ses spécificités, mais sans entrer dans les détails. Certaines fonctionnalités étant commune à plusieurs collections, ces fonctionnalités ne vont pas être décrites par collection, mais par catégories de fonctionnalités. N’hésitez pas à consulter la documentation pour savoir si une collection en particulier permet d'utiliser une fonctionnalité ou non.+Le chapitre précédent présentait chaque collection et ses spécificités, mais sans entrer dans les détails. Certaines fonctionnalités étant communes à plusieurs collections, ces fonctionnalités ne vont pas être décrites par collection, mais par catégories de fonctionnalités. N’hésitez pas à consulter la documentation pour savoir si une collection en particulier permet d'utiliser une fonctionnalité ou non.
  
-Certaines fonctionnalités ont déjà étaient décrites dans les chapitres précédents, ce chapitre ne sera qu'un rappel dans ce cas.+Certaines fonctionnalités ont déjà été décrites dans les chapitres précédents, ce chapitre ne sera qu'un rappel dans ce cas.
  
  
Ligne 165: Ligne 165:
    
 int main() { int main() {
-    const std::vector<int> v1 { 1, 2, 3 };+    std::vector<int> v1 { 1, 2, 3 };
          
     std::vector<int> v2;  // déclaration     std::vector<int> v2;  // déclaration
Ligne 283: Ligne 283:
  
 Si une collection est redimensionnée avec une taille plus petite, les éléments en fin de collection sont simplement supprimés. Pour supprimer tous les éléments, vous pouvez utiliser la fonction ''clear'' (nettoyer). Si une collection est redimensionnée avec une taille plus petite, les éléments en fin de collection sont simplement supprimés. Pour supprimer tous les éléments, vous pouvez utiliser la fonction ''clear'' (nettoyer).
 +
 +<note>**empty ou isEmpty**
 +
 +Si vous dites a une personne qu'il existe deux fonctions dans les collections de la bibliothèque standard  ''empty'' et ''clear'', et que l'une d'elle permet de supprimer tous les éléments de la collection et l'autre permet de tester si la collection ne contient aucun element. Il est très probable que cette personne soit incapable de dire qui fait quoi entre ''empty'' et ''clear'' (les deux termes pouvant correspondre aussi bien a l'adjectif "vide" qu'au verbe "vider").
 +
 +Pour améliorer la lisibilité du code, il est classique que les guides de codage recommandent que les fonctions qui retourne un booléen commencent par un verbe, en général "is" (être quelque chose) ou "has" (avoir quelque chose).
 +
 +Plus généralement, les fonctions correspondent a des actions, quelque chose qui est fait. Il est classique de nommer les fonctions en utilisant un verbe, exprimant cette action. 
 +
 +En suivant ces recommandations, ''empty'' devrait s'appeler ''is_empty'', qui se traduit alors par "est vide", et ''clear'' se traduit par "vider".
 +
 +La bibliothèque standard ne suis pas cette recommandation, certaines bibliothèques vont les suivre et d'autres bibliothèques vont proposer les deux versions des fonctions.
 +</note>
  
 Ces quatre fonctions sont disponibles pour toutes les collections. En revanche, les fonctions suivantes sont uniquement disponibles pour ''std::vector'' et les chaînes de caractères (''std::string'' et équivalents). Ces quatre fonctions sont disponibles pour toutes les collections. En revanche, les fonctions suivantes sont uniquement disponibles pour ''std::vector'' et les chaînes de caractères (''std::string'' et équivalents).
Ligne 401: Ligne 414:
 </code> </code>
  
-Le dernier point est plus complexe à comprendre, cela nécessite de comprendre la fonctionnement des ordinateurs, en particulier des caches mémoire. Sachez simplement qu'une mémoire contiguë comme dans ''std::vector'' sera généralement plus rapide qu'une mémoire non contiguë comme dans ''std::list''.+Le dernier point est plus complexe à comprendre, cela nécessite de comprendre le fonctionnement des ordinateurs, en particulier des caches mémoire. Sachez simplement qu'une mémoire contiguë comme dans ''std::vector'' sera généralement plus rapide qu'une mémoire non contiguë comme dans ''std::list''.
  
  
Ligne 418: Ligne 431:
   * //back// (derrière) correspond à la fin d'une collection.   * //back// (derrière) correspond à la fin d'une collection.
  
-Avec ces quatre mots-clés, vous avez donc les fonctions suivantes :+Avec ces cinq mots-clés, vous avez donc les fonctions suivantes :
  
   * ''emplace_front'' pour créer au début ;   * ''emplace_front'' pour créer au début ;
Ligne 452: Ligne 465:
     auto it = std::find(begin(v), end(v), 2);     auto it = std::find(begin(v), end(v), 2);
     v.insert(it, { -1, -2, -3 });     v.insert(it, { -1, -2, -3 });
-    for (auto i: v) std::cout << i << ' '; std::cout << std::endl;+    for (auto i: v) std::cout << i << ' '; 
 +    std::cout << std::endl;
 } }
 </code> </code>
Ligne 473: Ligne 487:
 </code> </code>
  
-La première version permet d'insérer un élément, la deuxième version permet d'insérer plusieurs fois la même valeur (faites bien attention à l'ordre des informations données : le nombre d'occurence puis la valeur), la troisième version permet d'insérer plusieurs éléments provenant d'une collection (paire d'itérateurs), la dernière version permet d'insérer une liste de valeurs.+La première version permet d'insérer un élément, la deuxième version permet d'insérer plusieurs fois la même valeur (faites bien attention à l'ordre des informations données : le nombre d'occurrence puis la valeur), la troisième version permet d'insérer plusieurs éléments provenant d'une collection (paire d'itérateurs), la dernière version permet d'insérer une liste de valeurs.
  
 Lorsque vous insérez des éléments dans un ''std::vector'', les indirections sur les éléments peuvent être invalidés. Il n'est donc pas sûr d'insérer des éléments provenant d'un ''std::vector'' sur lui-même. Lorsque vous insérez des éléments dans un ''std::vector'', les indirections sur les éléments peuvent être invalidés. Il n'est donc pas sûr d'insérer des éléments provenant d'un ''std::vector'' sur lui-même.
Ligne 494: Ligne 508:
 Pour ''emplace'', il existe également une version qui prend un itérateur de positionnement, mais la fonction change de nom. Il faut utiliser dans ce cas la fonction ''emplace_hint''. Pour ''emplace'', il existe également une version qui prend un itérateur de positionnement, mais la fonction change de nom. Il faut utiliser dans ce cas la fonction ''emplace_hint''.
  
-Les fonctions ''insert'', ''emplace'' et ''emplace_int'' suivent les prototypes suivants :+Les fonctions ''insert'', ''emplace'' et ''emplace_hint'' suivent les prototypes suivants :
  
 <code> <code>
Ligne 516: Ligne 530:
     std::set<int> s { 1, 2, 3, 4 };     std::set<int> s { 1, 2, 3, 4 };
     s.insert({ -1, -2, -3 });     s.insert({ -1, -2, -3 });
-    for (const auto i: s) std::cout << i << ' '; std::cout << std::endl;+    for (const auto i: s) std::cout << i << ' '; 
 +    std::cout << std::endl;
 } }
 </code> </code>
Ligne 599: Ligne 614:
     auto last  = std::find(begin(v), end(v), 7);     auto last  = std::find(begin(v), end(v), 7);
     v.erase(first, last);     v.erase(first, last);
-    for (auto i: v) std::cout << i << ' '; std::cout << std::endl;      +    for (auto i: v) std::cout << i << ' '; 
 +    std::cout << std::endl;      
 } }
 </code> </code>
Ligne 632: Ligne 648:
     auto it = std::remove_if(begin(v), end(v), isdigit);     auto it = std::remove_if(begin(v), end(v), isdigit);
     v.erase(it, end(v));     v.erase(it, end(v));
-    for (auto i: v) std::cout << i << ' '; std::cout << std::endl;      +    for (auto i: v) std::cout << i << ' '; 
 +    std::cout << std::endl;      
 } }
 </code> </code>
Ligne 644: Ligne 661:
 L'algorithme ''std::remove'' est un algorithme de la bibliothèque standard (il faut donc inclure le fichier d'en-tête ''<algorithm>''). Il parcourt une collection et à chaque fois qu'il rencontre un élément à supprimer, il le remplace par l’élément valide suivant de la collection. A la fin, il retourne un itérateur sur le premier élément invalide de la collection (la taille de la collection n'a pas été modifiée). L'algorithme ''std::remove'' est un algorithme de la bibliothèque standard (il faut donc inclure le fichier d'en-tête ''<algorithm>''). Il parcourt une collection et à chaque fois qu'il rencontre un élément à supprimer, il le remplace par l’élément valide suivant de la collection. A la fin, il retourne un itérateur sur le premier élément invalide de la collection (la taille de la collection n'a pas été modifiée).
  
-Notez que "invalide" signifie que les éléments présent dans le collection sont encore accessible (les utiliser ne produit pas de comportement indéterminé), mais peuvent correspondre a n'importe quel élément. Le comportement est laisse a la discrétion des développeurs de la bibliothèque standard. Si vous avez la totalité de la collection du code précédent après l'appel a ''std::remove'', vous pouvez obtenir par exemple le résultat suivant :+Notez que "invalide" signifie que les éléments présent dans la collection sont encore accessible (les utiliser ne produit pas de comportement indéterminé), mais peuvent correspondre a n'importe quel élément. Le comportement est laisser a la discrétion des développeurs de la bibliothèque standard. Si vous avez la totalité de la collection du code précédent après l'appel a ''std::remove'', vous pouvez obtenir par exemple le résultat suivant :
  
 <code> <code>
Ligne 650: Ligne 667:
 </code> </code>
  
-Vous voyez dans cette version de l'algorithme que les éléments valides sont places au début de la collection (comme attendu), les éléments invalides sont simplement laisses tel quel.+Vous voyez dans cette version de l'algorithme que les éléments valides sont placer au début de la collection (comme attendu), les éléments invalides sont simplement laisser tel quel.
  
 La fonction membre ''erase'' est ensuite utilisée pour supprimer les éléments invalides, qui sont les éléments entre l'itérateur retourne par ''std::remove'' et la fin de la collection. La fonction membre ''erase'' est ensuite utilisée pour supprimer les éléments invalides, qui sont les éléments entre l'itérateur retourne par ''std::remove'' et la fin de la collection.
Ligne 656: Ligne 673:
 En termes de performances par rapport a appeler plusieurs fois ''erase'', cet idiome garantie que la complexité est linéaire, ce qui signifie que chaque élément n'est déplacé qu'une seule fois. (Vous verrez la complexité algorithmique au chapitre sur la création d'algorithmes). En termes de performances par rapport a appeler plusieurs fois ''erase'', cet idiome garantie que la complexité est linéaire, ce qui signifie que chaque élément n'est déplacé qu'une seule fois. (Vous verrez la complexité algorithmique au chapitre sur la création d'algorithmes).
  
-**Exercice** : dans code précédent, il y a au total trois déplacements d’éléments avec l'idiome "remove-erase" (un pour chaque élément 'a', 'b' et 'c'). Essayez de calculer le nombre de déplacements qu'il faudrait si vous n'utilisez que la fonction ''erase''.+**Exercice** : dans le code précédent, il y a au total trois déplacements d’éléments avec l'idiome "remove-erase" (un pour chaque élément 'a', 'b' et 'c'). Essayez de calculer le nombre de déplacements qu'il faudrait si vous n'utilisez que la fonction ''erase''.
  
 <note>**Les idiomes de programmation** <note>**Les idiomes de programmation**
Ligne 698: Ligne 715:
 ===== Accès aléatoire ===== ===== Accès aléatoire =====
  
-Quelques types de collections, comme ''std::vector'' et ''std::array'' autorisent d'accéder directement à un élément quelconque, en utilisant les crochets droits ''[POSITION]''. Le terme "aléatoire" signifie "n'importe quel élément" et pas "un élément au hasard. Les éléments sont identifiés par leur position dans la collection, en commençant avec l'indice 0.+Quelques types de collections, comme ''std::vector'' et ''std::array'' autorisent d'accéder directement à un élément quelconque, en utilisant les crochets droits ''[POSITION]''. Le terme "aléatoire" signifie "n'importe quel élément" et pas "un élément au hasard". Les éléments sont identifiés par leur position dans la collection, en commençant avec l'indice 0.
  
 Le type de l'indice est formellement donné selon le type de collection, en utilisant ''size_type'' sur la collection. Par exemple pour ''std::vector'' : Le type de l'indice est formellement donné selon le type de collection, en utilisant ''size_type'' sur la collection. Par exemple pour ''std::vector'' :
Ligne 756: Ligne 773:
 </code> </code>
  
-<note>Il existe également la fonction membre ''at'', qui est similaire à l'opérateur ''[]'', mais son usage n'est pas recommandé.</note>+<note>Il existe également la fonction membre ''at'', qui est similaire à l'opérateur d'indexation ''[]'', mais son usage n'est pas recommandé.</note>
  
 ===== Collections associative ===== ===== Collections associative =====
Ligne 762: Ligne 779:
 Dans le cas des collections associatives, la notion de position n'a pas réellement de sens, puisque la collection est libre de réorganiser les éléments. Il est cependant possible d'accéder séquentiellement aux éléments, en utilisant l'algorithme ''std::advance'', comme indiqué ci-dessus. Dans le cas des collections associatives, la notion de position n'a pas réellement de sens, puisque la collection est libre de réorganiser les éléments. Il est cependant possible d'accéder séquentiellement aux éléments, en utilisant l'algorithme ''std::advance'', comme indiqué ci-dessus.
  
-L'opérateur crochet droit ''[]'' n'est donc pas utilisable avec un indice dans la collection, mais avec une clé.+L'opérateur d'indexation ''[]'' n'est donc pas utilisable avec un indice dans la collection, mais avec une clé.
  
 <code>  <code> 
Ligne 768: Ligne 785:
 </code> </code>
  
-Cet opérateur ''[]'' est utilisable aussi bien pour lire une valeur que pour la créer et la modifier. Si la clé n'existe pas, l'opérateur ''[]'' va créer un élément correspondant à cette clé.+Cet opérateur d'indexation ''[]'' est utilisable aussi bien pour lire une valeur que pour la créer et la modifier. Si la clé n'existe pas, l'opérateur d'indexation ''[]'' va créer un élément correspondant à cette clé.
  
  
Ligne 792: Ligne 809:
 </code> </code>
  
-La taille de la collection est bien augmenté de un après l'utilisation de l'opérateur ''[]''.+La taille de la collection est bien augmenté de un après l'utilisation de l'opérateur d'indexation ''[]''.
  
-Cela implique que l'accès en utilisant l'opérateur ''[]'' sur une collection associative est toujours valide, puisque cela va créer un élément si la clé n'existe pas. Vous pouvez quand même utiliser une assertion, dans le cas où vous souhaitez garantir qu'un élément ne sera pas ajouté dans la collection.+Cela implique que l'accès en utilisant l'opérateur d'indexation ''[]'' sur une collection associative est toujours valide, puisque cela va créer un élément si la clé n'existe pas. Vous pouvez quand même utiliser une assertion, dans le cas où vous souhaitez garantir qu'un élément ne sera pas ajouté dans la collection.
  
 <code cpp> <code cpp>
Ligne 801: Ligne 818:
 </code> </code>
  
-<note>Il existe également une fonction membre ''at'', qui est similaire à l'opérateur ''[]'', mais son usage n'est pas non recommandé.</note>+<note>Il existe également une fonction membre ''at'', qui est similaire à l'opérateur d'indexation ''[]'', mais son usage n'est pas recommandé.</note>
  
  
 ^ [[map|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[comparer|Chapitre suivant]] ^ ^ [[map|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[comparer|Chapitre suivant]] ^
  
collection2.1459133055.txt.gz · Dernière modification: 2016/03/28 04:44 par gbdivers