remplir - tableau dynamique c++ vector




Pouvez-vous expliquer le but du tableau+5 dans ce programme? (4)

Le array variables est comme un pointeur vers le début de la mémoire qui contient les données.

La longueur du array est 5 , donc ajouter 5 au début donne la position de l'un après la fin.

start --|  
       10, 20, 29, 200, 2, (out of array)
        |--- +5 -----------^

La condition it != end vérifie si la boucle n'est pas hors limites.

Je comprends comment cela fonctionne la plupart du temps, à l’exception de la deuxième ligne de la fonction main : int* end = array+5; . Comment fonctionne cette ligne?

#inlcude <iostream>
int main()
{
    int array[] = {10, 20, 29, 200, 2};

    int* end = array+5;
    for(int* it = array; it != end; ++it)
    {
        std::cout << *it << std::endl;
    }
}

Il est supposé imprimer tous les éléments de la liste.


Pour comprendre int* end = array+5; , il faut savoir comment la mémoire a été aménagée pour int array[] = {10, 20, 29, 200, 2} . Ont représenté la même chose ci-dessous pour une meilleure compréhension. Les adresses sont données en décimal et en hexadécimal pour faciliter les opérations arithmétiques.

               Address table 
          -----------------------------------------------------------
array ===>|   100   |   104   |   108   |   112   |   116  |   120  |  -----> DECIMAL
          |  0x100  |  0x104  |  0x108  |  0x10C  |  0x110 |  0x114 |  -----> HEXADECIMAL
          -----------------------------------------------------------
               |         |         |         |         |        
              10        20        29        200        2

'array' will be pointing to 0x100

L'instruction int* end = array + 5; est compilé en un code équivalent à int* end = (array + (sizeof(int) * 5));

Donc, il est évalué comme int* end = (0x100 + (4 * 5)) = 0x114(decimal equivalent 120); qui est l'adresse à côté du dernier élément. Donc, end sera pointé vers l'avant dernier élément.

Il est important de se rappeler que la valeur à ajouter ou à soustraire de l'adresse de base du tableau dépend toujours du type de données qui est int dans votre cas et que la sizeof(int) est supposée être de 4 bytes .

Sur une note, datatype arr [index]; est évalué comme *(arr + (sizeof(datatype) * index)) .


array + 5 est équivalent à &array[5] .

Depuis array dans votre exemple de code est un tableau de cinq éléments.

int array[] = {10, 20, 29, 200, 2};

l'initialisation

int* end = array+5;

fait en sorte que end soit un pointeur sur l'un après la fin du tableau, et la condition de fin dans la boucle

for(int* it = array; it != end; ++it)
{
    std::cout << *it << std::endl;
}

signifie que la boucle se termine une fois it pointe au-delà de la fin du tableau (dans votre exemple, elle pointe vers le array[5] ). Cela convient parfaitement en C ++, puisqu’un pointeur sur une extrémité passée d’un tableau peut être calculé ou comparé avec d’autres pointeurs sur des éléments de ce tableau. Toutefois, le déréférencement d'un tel pointeur (par exemple, dans votre exemple, son utilisation pour accéder à la valeur de array[5] ) provoque un comportement indéfini.

Dans C ++ 11 et std::begin() ultérieures, les fonctions std::begin() et std::end() (à partir de l'en-tête standard <iterator> ), si un argument de tableau leur est attribué, renvoient les adresses du premier élément et one-past-the -last element respectivement. Donc votre code est fonctionnellement équivalent, pour un array ayant cinq éléments, à;

int *end = std::end(array);
for(int *it = std::begin(array); it != end; ++it)
{
    std::cout << *it << std::endl;
}

C'est aussi l'équivalent du plus concis et souvent préféré, car il est moins sujet aux erreurs;

for (const auto &element : array)    // const since the loop body doesn't change the array
{
    std::cout << element << std::endl;
}

it != end;

signifie qu'il a atteint la position [5], qui est un après le dernier (4).

int* end = array + 5; 

crée simplement une variable pointant vers cette position [5].

Cela fonctionne, mais une version beaucoup plus propre et sûre est:

for(int i = 0 ; i < 5 ; i++)
{
    std::cout << it[i] << std::endl;
}

Bien sûr, vous pouvez remplacer le 5 codé en dur par sizeof(array)/sizeof(int) , ou, mieux encore, utiliser un std :: array.

std::array arr<int,5> = {10, 20, 29, 200, 2};
for(int i = 0 ; i < arr.size() ; i++)
{
    std::cout << arr[i] << std::endl;
}

ou

 std::array arr<int,5> = {10, 20, 29, 200, 2};
 for(auto& it : arr)
 {
    std::cout << it << std::endl;
 }

Ces dernières formes sont aussi rapides que le tableau brut brut, mais beaucoup plus sûres.





pointer-arithmetic