abdelouafi
Administrator
إذا كنت ترغب في مشاهدة الصور ، يرجى النقر عليها
Blog
SUIVEZ NOTRE CHAINE YOUTUBE: قم بالتسجيل في قناتنا عبر هذا الرابط https://www.youtube.com/channel/UCCITRMWPcElh-96wCS3EyUg
devoir 1 math tronc commun
مجموعة من دروس و فروض جميع المستويات
دروس الإعدادي - دروس الثانوي الثأهيلي - دروس التعليم الابتدائي - فروض مختلف المستويات الدراسيةفضلا و ليس أمرا شارك هذه الصفحة مع أصدقائك:
Dans les leçons précédentes, nous avons beaucoup parlé de tableaux fixes et dynamiques. Bien que les deux soient construits directement dans le langage C ++, ils présentent tous deux des inconvénients: les tableaux fixes se décomposent en pointeurs, perdent l'information de longueur de tableau, et les tableaux dynamiques posent des problèmes de désallocation et sont difficiles à redimensionner sans erreur.
Pour résoudre ces problèmes, la bibliothèque standard C ++ inclut des fonctionnalités facilitant la gestion des tableaux, std :: array et std :: vector. Nous allons examiner std :: array dans cette leçon et std :: vector dans la suivante.
Une introduction à std :: array en C ++ 11
Introduit dans C ++ 11, std :: array fournit des fonctionnalités de tableau fixes qui ne s’affaiblissent pas lorsqu’elles sont transmises à une fonction. std :: array est défini dans l'en-tête du tableau, à l'intérieur de l'espace de noms std.
Déclarer une variable std :: array est simple:
Tout comme l'implémentation native des tableaux fixes, la longueur d'un std :: array doit être définie au moment de la compilation.
std :: array peut être initialisé en utilisant une liste d'initialisation ou une initialisation uniforme:
Contrairement aux tableaux fixes intégrés, avec std :: array, vous ne pouvez pas omettre la longueur du tableau lorsque vous fournissez un initialiseur:
Vous pouvez également affecter des valeurs au tableau à l'aide d'une liste d'initialisation.
L'accès aux valeurs de std :: array à l'aide de l'opérateur subscript fonctionne exactement comme prévu:
Tout comme les tableaux fixes intégrés, l'opérateur en indice ne vérifie pas les limites. Si un index non valide est fourni, de mauvaises choses vont probablement arriver.
std :: array supporte une seconde forme d'accès à un élément de tableau (la fonction at ()) qui vérifie les limites:
Dans l'exemple ci-dessus, l'appel à array.at (1) vérifie que l'élément de tableau 1 est valide et, ce qui est vrai, renvoie une référence à l'élément de tableau 1. Nous lui affectons ensuite la valeur 6. Cependant, l'appel à array.at (9) échoue car l'élément de tableau 9 est hors limites pour le tableau. Au lieu de renvoyer une référence, la fonction at () génère une erreur qui termine le programme (remarque: elle lève en fait une exception de type std :: out_of_range - nous traitons des exceptions dans le chapitre 15). Comme il vérifie les limites, at () est plus lent (mais plus sûr) que l'opérateur [].
std :: array nettoiera lui-même quand il sortira de sa portée, il n’a donc pas besoin d’être nettoyé.
Taille et tri
La fonction size () peut être utilisée pour récupérer la longueur du std :: array:
Cela imprime:
length: 5
Std :: array ne se décomposant pas en pointeur lorsqu'il est transmis à une fonction, la fonction size () fonctionnera même si vous l'appelez de l'intérieur d'une fonction:
Cela imprime:
length: 5
Notez que la bibliothèque standard utilise le terme «taille» pour désigner la longueur du tableau. Ne confondez pas ce résultat avec les résultats de sizeof () sur un tableau natif fixe, qui renvoie la taille réelle du tableau en mémoire (la taille d'un fichier). élément multiplié par la longueur du tableau). Oui, cette nomenclature est incohérente.
Notez également que nous avons passé std :: array par référence (const). Cela empêche le compilateur de faire une copie du std :: array lorsque le std :: array a été passé à la fonction (pour des raisons de performances).
Règle: toujours passer std :: array par référence ou par référence const
Comme la longueur est toujours connue, les boucles for-each (rangeed for) fonctionnent avec std :: array:
Vous pouvez trier std :: array en utilisant std :: sort, qui réside dans l'en-tête de l'algorithme:
Cela imprime:
1 3 5 7 9
La fonction de tri utilise des itérateurs, concept que nous n’avons pas encore abordé. Vous pouvez donc traiter les paramètres comme suit: std :: sort () est un peu magique. Nous allons les expliquer dans la leçon sur les itérateurs.
Indexer manuellement std :: array via size_type
Pop quiz: Quel est le problème avec le code suivant?
La réponse est qu’il ya probablement une incompatibilité signée / non signée dans ce code! En raison d’une décision curieuse, la fonction size () et le paramètre d’index de tableau de l’opérateur [] utilisent un type appelé size_type, défini par le standard C ++ en tant que type intégral non signé. Notre compteur / index de boucle (variable i) est un entier signé. Par conséquent, la comparaison i <myArray.size () et l'index de tableau myArray présentent des incohérences de type.
Chose intéressante, size_type n'est pas un type global (comme int ou std :: size_t). Au contraire, il est défini dans la définition de std :: array (C ++ autorise les types imbriqués). Cela signifie que lorsque nous voulons utiliser size_type, nous devons le préfixer avec le type de tableau complet (pensez à std :: array agissant comme un espace de noms à cet égard). Dans notre exemple ci-dessus, le type de préfixe "size_type" est: std :: array <int, 5> :: size_type!
Par conséquent, la manière correcte d'écrire le code ci-dessus est la suivante:
Ce n'est pas très lisible. Un alias de type peut aider un peu:
C’est un peu mieux et cette solution offre probablement la meilleure combinaison de correction technique et de lisibilité.
Dans toutes les implémentations courantes de std :: array, size_type est un typedef pour std :: size_t. Il est donc assez courant de voir les développeurs utiliser plutôt size_t. Bien que techniquement non correct, dans presque toutes les implémentations, cela fonctionnera:
Une meilleure solution consiste à éviter l'indexation manuelle de std :: array en premier lieu. Au lieu de cela, utilisez si possible des boucles for (ou des itérateurs) basées sur la plage.
Résumé
std :: array est un excellent remplacement pour les tableaux fixes intégrés. C’est efficace car il n’utilise pas plus de mémoire que les baies fixes intégrées. Le seul inconvénient réel de std :: array par rapport à un tableau fixe intégré est une syntaxe légèrement plus compliquée, dans laquelle vous devez spécifier explicitement la longueur du tableau (le compilateur ne le calculera pas à partir de l'initialiseur), et problèmes signés / non signés avec la taille et l'indexation. Mais ce ne sont que des petits inconvénients - nous vous recommandons d’utiliser std :: array plutôt que des tableaux fixes intégrés pour toute utilisation de tableau non triviale.
Pour résoudre ces problèmes, la bibliothèque standard C ++ inclut des fonctionnalités facilitant la gestion des tableaux, std :: array et std :: vector. Nous allons examiner std :: array dans cette leçon et std :: vector dans la suivante.
Une introduction à std :: array en C ++ 11
Introduit dans C ++ 11, std :: array fournit des fonctionnalités de tableau fixes qui ne s’affaiblissent pas lorsqu’elles sont transmises à une fonction. std :: array est défini dans l'en-tête du tableau, à l'intérieur de l'espace de noms std.
Déclarer une variable std :: array est simple:
Code:
#include <array>
std::array<int, 3> myArray; // declare an integer array with length 3
Tout comme l'implémentation native des tableaux fixes, la longueur d'un std :: array doit être définie au moment de la compilation.
std :: array peut être initialisé en utilisant une liste d'initialisation ou une initialisation uniforme:
Code:
std::array<int, 5> myArray = { 9, 7, 5, 3, 1 }; // initialization list
std::array<int, 5> myArray2 { 9, 7, 5, 3, 1 }; // uniform initialization
Contrairement aux tableaux fixes intégrés, avec std :: array, vous ne pouvez pas omettre la longueur du tableau lorsque vous fournissez un initialiseur:
Code:
std::array<int, > myArray = { 9, 7, 5, 3, 1 }; // illegal, array length must be provided
Vous pouvez également affecter des valeurs au tableau à l'aide d'une liste d'initialisation.
Code:
std::array<int, 5> myArray;
myArray = { 0, 1, 2, 3, 4 }; // okay
myArray = { 9, 8, 7 }; // okay, elements 3 and 4 are set to zero!
myArray = { 0, 1, 2, 3, 4, 5 }; // not allowed, too many elements in initializer list!
L'accès aux valeurs de std :: array à l'aide de l'opérateur subscript fonctionne exactement comme prévu:
Code:
std::cout << myArray[1];
myArray[2] = 6;
Tout comme les tableaux fixes intégrés, l'opérateur en indice ne vérifie pas les limites. Si un index non valide est fourni, de mauvaises choses vont probablement arriver.
std :: array supporte une seconde forme d'accès à un élément de tableau (la fonction at ()) qui vérifie les limites:
Code:
std::array<int, 5> myArray { 9, 7, 5, 3, 1 };
myArray.at(1) = 6; // array element 1 valid, sets array element 1 to value 6
myArray.at(9) = 10; // array element 9 is invalid, will throw error
Dans l'exemple ci-dessus, l'appel à array.at (1) vérifie que l'élément de tableau 1 est valide et, ce qui est vrai, renvoie une référence à l'élément de tableau 1. Nous lui affectons ensuite la valeur 6. Cependant, l'appel à array.at (9) échoue car l'élément de tableau 9 est hors limites pour le tableau. Au lieu de renvoyer une référence, la fonction at () génère une erreur qui termine le programme (remarque: elle lève en fait une exception de type std :: out_of_range - nous traitons des exceptions dans le chapitre 15). Comme il vérifie les limites, at () est plus lent (mais plus sûr) que l'opérateur [].
std :: array nettoiera lui-même quand il sortira de sa portée, il n’a donc pas besoin d’être nettoyé.
Taille et tri
La fonction size () peut être utilisée pour récupérer la longueur du std :: array:
Code:
std::array<double, 5> myArray { 9.0, 7.2, 5.4, 3.6, 1.8 };
std::cout << "length: " << myArray.size();
Cela imprime:
length: 5
Std :: array ne se décomposant pas en pointeur lorsqu'il est transmis à une fonction, la fonction size () fonctionnera même si vous l'appelez de l'intérieur d'une fonction:
Code:
#include <iostream>
#include <array>
void printLength(const std::array<double, 5> &myArray)
{
std::cout << "length: " << myArray.size();
}
int main()
{
std::array<double, 5> myArray { 9.0, 7.2, 5.4, 3.6, 1.8 };
printLength(myArray);
return 0;
}
Cela imprime:
length: 5
Notez que la bibliothèque standard utilise le terme «taille» pour désigner la longueur du tableau. Ne confondez pas ce résultat avec les résultats de sizeof () sur un tableau natif fixe, qui renvoie la taille réelle du tableau en mémoire (la taille d'un fichier). élément multiplié par la longueur du tableau). Oui, cette nomenclature est incohérente.
Notez également que nous avons passé std :: array par référence (const). Cela empêche le compilateur de faire une copie du std :: array lorsque le std :: array a été passé à la fonction (pour des raisons de performances).
Règle: toujours passer std :: array par référence ou par référence const
Comme la longueur est toujours connue, les boucles for-each (rangeed for) fonctionnent avec std :: array:
Code:
std::array<int, 5> myArray { 9, 7, 5, 3, 1 };
for (auto &element : myArray)
std::cout << element << ' ';
Vous pouvez trier std :: array en utilisant std :: sort, qui réside dans l'en-tête de l'algorithme:
Code:
#include <iostream>
#include <array>
#include <algorithm> // for std::sort
int main()
{
std::array<int, 5> myArray { 7, 3, 1, 9, 5 };
std::sort(myArray.begin(), myArray.end()); // sort the array forwards
// std::sort(myArray.rbegin(), myArray.rend()); // sort the array backwards
for (const auto &element : myArray)
std::cout << element << ' ';
return 0;
}
Cela imprime:
1 3 5 7 9
La fonction de tri utilise des itérateurs, concept que nous n’avons pas encore abordé. Vous pouvez donc traiter les paramètres comme suit: std :: sort () est un peu magique. Nous allons les expliquer dans la leçon sur les itérateurs.
Indexer manuellement std :: array via size_type
Pop quiz: Quel est le problème avec le code suivant?
Code:
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> myArray { 7, 3, 1, 9, 5 };
// Iterate through the array and print the value of the elements
for (int i{ 0 }; i < myArray.size(); ++i)
std::cout << myArray[i] << ' ';
return 0;
}
La réponse est qu’il ya probablement une incompatibilité signée / non signée dans ce code! En raison d’une décision curieuse, la fonction size () et le paramètre d’index de tableau de l’opérateur [] utilisent un type appelé size_type, défini par le standard C ++ en tant que type intégral non signé. Notre compteur / index de boucle (variable i) est un entier signé. Par conséquent, la comparaison i <myArray.size () et l'index de tableau myArray présentent des incohérences de type.
Chose intéressante, size_type n'est pas un type global (comme int ou std :: size_t). Au contraire, il est défini dans la définition de std :: array (C ++ autorise les types imbriqués). Cela signifie que lorsque nous voulons utiliser size_type, nous devons le préfixer avec le type de tableau complet (pensez à std :: array agissant comme un espace de noms à cet égard). Dans notre exemple ci-dessus, le type de préfixe "size_type" est: std :: array <int, 5> :: size_type!
Par conséquent, la manière correcte d'écrire le code ci-dessus est la suivante:
Code:
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> myArray { 7, 3, 1, 9, 5 };
for (std::array<int, 5>::size_type i{ 0 }; i < myArray.size(); ++i) // std::array<int, 5>::size_type is the return type of size()!
std::cout << myArray[i] << ' ';
return 0;
}
Ce n'est pas très lisible. Un alias de type peut aider un peu:
Code:
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> myArray { 7, 3, 1, 9, 5 };
using index_t = std::array<int, 5>::size_type;
for (index_t i{ 0 }; i < myArray.size(); ++i)
std::cout << myArray[i] << ' ';
return 0;
}
C’est un peu mieux et cette solution offre probablement la meilleure combinaison de correction technique et de lisibilité.
Dans toutes les implémentations courantes de std :: array, size_type est un typedef pour std :: size_t. Il est donc assez courant de voir les développeurs utiliser plutôt size_t. Bien que techniquement non correct, dans presque toutes les implémentations, cela fonctionnera:
Code:
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> myArray { 7, 3, 1, 9, 5 };
for (std::size_t i{ 0 }; i < myArray.size(); ++i)
std::cout << myArray[i] << ' ';
return 0;
}
Une meilleure solution consiste à éviter l'indexation manuelle de std :: array en premier lieu. Au lieu de cela, utilisez si possible des boucles for (ou des itérateurs) basées sur la plage.
Résumé
std :: array est un excellent remplacement pour les tableaux fixes intégrés. C’est efficace car il n’utilise pas plus de mémoire que les baies fixes intégrées. Le seul inconvénient réel de std :: array par rapport à un tableau fixe intégré est une syntaxe légèrement plus compliquée, dans laquelle vous devez spécifier explicitement la longueur du tableau (le compilateur ne le calculera pas à partir de l'initialiseur), et problèmes signés / non signés avec la taille et l'indexation. Mais ce ne sont que des petits inconvénients - nous vous recommandons d’utiliser std :: array plutôt que des tableaux fixes intégrés pour toute utilisation de tableau non triviale.