Outils pour utilisateurs

Outils du site


lang:cpp:boucles

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
lang:cpp:boucles [2020/01/02 10:28] – [La boucle traditionnelle] : mise à jour de "Conteneur supportant les itérateurs" rootlang:cpp:boucles [2020/06/16 15:00] (Version actuelle) – Précision sur le style fonctionnel root
Ligne 1: Ligne 1:
-====La boucle traditionnelle===+=====Boucle sur des données (old style)===== 
-===Intervalle=== +====Conteneur supportant les index====
-<code cpp> +
-for (int i 0; i < 100; i++) +
-  std::cout << i << std::endl; +
-</code> +
- +
-Chaque paramètre est optionnel : +
-<code cpp> +
-int i = 0; +
-for (;;) +
-+
-  if (i >= 100) +
-    break; +
-  std::cout << i << std::endl; +
-  i++; +
-+
-</code> +
- +
-Et sa version ''while''+
-<code cpp> +
-int i = 0; +
-while (i < 100) +
-+
-  std::cout << i << std::endl; +
-  i++; +
-+
-</code> +
- +
-===Conteneur supportant les index===+
  
 <code cpp> <code cpp>
Ligne 36: Ligne 8:
 </code> </code>
  
-===Conteneur supportant les itérateurs===+====Conteneur supportant les itérateurs====
 <code cpp> <code cpp>
 std::vector<int> vector{ 10, 20, 30, 40 }; std::vector<int> vector{ 10, 20, 30, 40 };
-std::vector<int>::const_iterator it; 
-std::vector<int>::iterator itc; 
  
 // Lecture / écriture // Lecture / écriture
-for (itc = vector.begin(); itc != vector.end(); itc++) +std::vector<int>::iterator it; 
-  (*itc)++;+for (it = vector.begin(); it != vector.end(); it++) 
 +  (*it)++;
  
 // Lecture seule // Lecture seule
-for (it = vector.cbegin(); it != vector.cend(); it++) +std::vector<int>::const_iterator itc; 
-  std::cout << *it << std::endl;+for (itc = vector.cbegin(); itc != vector.cend(); itc++) 
 +  std::cout << *itc << std::endl;
 </code> </code>
 +
 +=====Programmation fonctionnelle=====
  
 ====for each==== ====for each====
Ligne 57: Ligne 31:
 <code cpp> <code cpp>
 std::array<int, 4> arr = { 10, 20, 30, 40 }; std::array<int, 4> arr = { 10, 20, 30, 40 };
-for (int i : arr)+// Ici, on utilise const & pour conserver le style fonctionnel. 
 +// Mais passer en copie un type primitif n'est pas plus penalisant que d'utiliser une référence. 
 +for (const inti : arr)
   std::cout << i << std::endl;   std::cout << i << std::endl;
 </code> </code>
Ligne 70: Ligne 46:
 </code> </code>
  
-===Conteneur multi-types (''std::map''''std::tuple'', ...)===+===Conteneur multi-types (map, tuple, ...)===
  
 <code cpp> <code cpp>
-std::map<int, std::string> map { {10, "10"}, {20, "20"}, {30, "30"}, {40, "40"} };+std::map<int, long> map { {10, 10}, {20, 20}, {30, 30}, {40, 40} };
  
 // L'utilisation de auto est obligatoire. // L'utilisation de auto est obligatoire.
 +// const s'applique sur toutes les variables.
 for (const auto & [key, value] : map) for (const auto & [key, value] : map)
   std::cout << value << std::endl;   std::cout << value << std::endl;
 </code> </code>
  
-===Sur une classe personnalisée===+L'interprétation par le compilateur sera : 
 + 
 +<code cpp> 
 +std::map<int, long> map std::map<int, long, std::less<int>, std::allocator<std::pair<const int, long> > >{std::initializer_list<std::pair<const int, long> >{std::pair<const int, long>{10, 10}, std::pair<const int, long>{20, 20}, std::pair<const int, long>{30, 30}, std::pair<const int, long>{40, 40}}, std::less<int>(), std::allocator<std::pair<const int, long> >()}; 
 +
 +  std::map<int, long, std::less<int>, std::allocator<std::pair<const int, long> > > & __range1 map; 
 +  std::_Rb_tree_iterator<std::pair<const int, long> > __begin1 __range1.begin(); 
 +  std::_Rb_tree_iterator<std::pair<const int, long> > __end1 = __range1.end(); 
 +  for(; __begin1.operator!=(__end1); __begin1.operator++())  
 +  { 
 +    const std::pair<const int, long> & __operator9 = __begin1.operator*(); 
 +    std::tuple_element<0, const std::pair<const int, long> >::type& key = std::get<0UL>(__operator9); 
 +    std::tuple_element<1, const std::pair<const int, long> >::type& value = std::get<1UL>(__operator9); 
 +    std::cout.operator<<(value).operator<<(std::endl); 
 +  } 
 +
 +</code> 
 + 
 +===Implémentation sur une classe personnalisée===
  
 Il faut définir l'itérateur et la classe à parcourir. [[https://www.cprogramming.com/c++11/c++11-ranged-for-loop.html|C++11 range-based for loops]] {{ :lang:cpp:boucles:range-based_for_loops_in_c_11_-_cprogramming.com_2019-12-26_12_35_03_.html |Archive le 26/12/2019}} Il faut définir l'itérateur et la classe à parcourir. [[https://www.cprogramming.com/c++11/c++11-ranged-for-loop.html|C++11 range-based for loops]] {{ :lang:cpp:boucles:range-based_for_loops_in_c_11_-_cprogramming.com_2019-12-26_12_35_03_.html |Archive le 26/12/2019}}
  
-L'exemple ci-dessous se passe de ''template''.+Dans l'idéal, ''DataSample'' devrait prendre une classe en ''template'' plutôt que la classe ''Data'' en dur.
  
 Il faut commencer par déclarer l'itérateur. Il faut commencer par déclarer l'itérateur.
Ligne 188: Ligne 183:
 </code> </code>
  
-===Via une coroutine===+====Ranges==== 
 + 
 +Les ''ranges'' de la ''std'' n'implémentent que des algorithmes en $O(1)$. Il n'est donc pas possible de trier des vues. 
 + 
 +  * Boucle 
 + 
 +<code cpp> 
 +#include <ranges> 
 + 
 +for (int i : std::views::iota(0, 100)) 
 +  std::cout << i << std::endl; 
 +</code> 
 + 
 +  * Pour faire la boucle à l'envers : 
 + 
 +<code cpp> 
 +#include <ranges> 
 + 
 +for (int i : std::views::iota(0, 100) | std::views::reverse) 
 +  std::cout << i << std::endl; 
 + 
 +</code> 
 + 
 +  * S'arrêter sous une certaine condition : 
 + 
 +<code cpp> 
 +#include <ranges> 
 + 
 +for (int i : std::views::iota(0, 100) | std::views::take_while([](int i){ return 0 <= i && i <= 15; })) 
 +  std::cout << i << std::endl; 
 +</code> 
 + 
 +  * Filter les valeurs : 
 + 
 +<code cpp> 
 +#include <ranges> 
 + 
 +for (int i : std::views::iota(0, 100) | std::views::filter([](int i){ return 50 <= i && i <= 66; })) 
 +  std::cout << i << std::endl; 
 +</code> 
 + 
 +  * Modifier les valeurs dans la vue : 
 + 
 +<code cpp> 
 +#include <ranges> 
 + 
 +int main() { 
 +  for (const std::string& i : 
 +      // Integer 
 +      std::views::iota(0, 100) | 
 +      // const char * 
 +      std::views::transform([](int i) { 
 +        if (i % 15 == 0) 
 +          return "FooBar\n"; 
 +        else if (i % 3 == 0) 
 +          return "Foo\n"; 
 +        else if (i % 5 == 0) 
 +          return "Bar\n"; 
 +        else 
 +          return ""; 
 +      })) 
 +    std::cout << i << std::endl; 
 +
 +</code> 
 + 
 +<WRAP center round important 60%> 
 +Les vues sont en lecture seule 
 +</WRAP> 
 + 
 +Le code  
 +<code cpp> 
 +int main() { 
 +  std::vector<int> v {1, 2, 3, 4, 5, 6, 7, 8, 9}; 
 +  for (int & i : 
 +       v | 
 +       std::views::take(5)) 
 +    i = 3; 
 +  for (const int & i : v) 
 +    std::cout << i << "\n"; 
 +
 +</code> 
 + 
 +affichera 
 + 
 +<code> 
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +</code> 
 + 
 +  * Ne prendre que les premiers résultats 
 + 
 +<code cpp> 
 +#include <ranges> 
 + 
 +int main() { 
 +  for (int i : 
 +       std::views::iota(0, 100) | 
 +       std::views::take(10)) 
 +    std::cout << i << std::endl; 
 +
 +</code> 
 + 
 +=====Via une coroutine=====
  
 <code cpp> <code cpp>
Ligne 211: Ligne 315:
 </code> </code>
  
-====Algorithmes==== 
-===mismatch=== 
-Comparer deux classes itérables. 
- 
-Ici, comparaison de deux string insensible à la casse. 
- 
-<code cpp> 
-#include <algorithm> 
-#include <string> 
-#include <utility> 
- 
-std::string un = "texte"; 
-std::string deux = "Texte"; 
- 
-std::tuple<std::string::const_iterator, std::string::const_iterator> retval = 
-  std::mismatch( 
-    un.cbegin(), 
-    un.cend(), 
-    deux.cbegin(), 
-    deux.cend(), 
-    [](char un, char deux) 
-    { 
-      return std::tolower(un) == std::tolower(deux); 
-    }); 
- 
-if (retval == std::make_tuple(un.cend(), deux.cend())) 
-  std::cout << "Identique" << std::endl; 
-else 
-  std::cout << "Différent" << std::endl; 
-</code> 
lang/cpp/boucles.1577957301.txt.gz · Dernière modification : 2020/01/02 10:28 de root