1
votes

Quelle est la différence entre begin () et rend ()?

J'ai une question dans les itérateurs sur la différence entre begin () et rend().

#include <iostream>
#include <array>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    vector<int> v1;
    v1 = {9,2,6,4,5};
    cout<<*v1.begin();
    cout<<*v1.rend();
    return 0;
}

cout renvoie 9

mais cout renvoie un nombre différent de 9

Pourquoi y a-t-il des résultats si différents?


6 commentaires

rend (). base () == begin () .


rend () renvoie "passé- l'itérateur de la fin, tout comme le fait end () . Le déréférencer est un comportement indéfini. (enfin, rend () est plus "avant-le-début", mais vous voyez l'idée).


rend est l'itérateur inverse la fin (début du vecteur d'origine) et begin est l'itérateur jusqu'au début


Voici une question connexe: Pourquoi utiliser rbegin () au lieu de end () - 1


v1.begin () <=> --v1.rend ()


Est-ce que cela répond à votre question? Que signifie "un-après-le-dernier-élément" dans les vecteurs?


4 Réponses :


5
votes

Le déréférencement de end () ou rend () a un comportement non défini.

begin () pointe vers le premier élément, rbegin () pointe vers le dernier élément. end () (dans la plupart des cas) pointe vers un après le dernier élément et rend () pointe effectivement vers un avant le premier élément (bien qu'il ne soit pas implémenté comme ça ).


4 commentaires

C'est "un après la fin" donc votre boucle peut se terminer sur la condition it == end () (ou rend () bien sûr) et obtenir chaque élément dans le gamme. (Dans une boucle bien sûr, la condition de fin est le négatif de ce que vous voulez donc il est écrit it! = End () mais c'est évident.)


"bien qu'il ne soit pas implémenté comme ça" Pourquoi pas?


@LightnessRacesinOrbit ne s'applique pas à tous les conteneurs, mais par exemple, vous ne pouvez pas utiliser l'arithmétique du pointeur pour obtenir l'adresse de l'élément avant le premier du tableau, comme vous pouvez faire passer le dernier, n'est-ce pas?


@eerorika Oh ouais: D



7
votes

En C ++, les plages sont marquées par une paire d'itérateurs marquant le début de la plage et une position après la fin de la plage. Pour les conteneurs, les fonctions membres begin () et end () vous fournissent une paire d'itérateurs vers les positions première et après la fin. La lecture depuis end () n’est pas sûre, car elle ne pointe pas vers un élément réel.

De même, les fonctions membres rbegin () et rend () renvoient des itérateurs inversés qui pointent respectivement vers la dernière et juste avant la première position. Pour la même raison qu'il n'est pas sûr de déréférencer l'itérateur end () (il a dépassé la fin de la plage), vous ne devriez pas déréférencer l'itérateur rend () , car il ne pointe pas vers un élément du conteneur.


0 commentaires

2
votes

vector :: rend () est une fonction intégrée dans la bibliothèque standard C ++ qui renvoie un itérateur inverse pointant vers l'élément théorique juste avant le premier élément du conteneur de tableau. mais vector :: begin () retourne un itérateur pointant vers le premier élément du vecteur.

Voir ce code:

5 4 6 2 9

Le vecteur les éléments dans l'ordre inverse sont:

for (auto it = v1.rbegin(); it != v1.rend(); it++) 
    cout << *it << " ";

Pour itérer dans le vecteur, choisissez toujours l'une de ces méthodes ensemble:

  • vector :: begin () et vector::end()
  • vector :: cbegin () et vector::cend()
  • vector :: crbegin () et vector::crend()
  • vector :: rbegin () et vector::rend()

Pour plus d'informations, consultez "Tutoriel vectoriel C ++ avec exemple" par Ankit Lathiya .

Essayez-le en ligne


1 commentaires

Des choses étranges se passent dans cet article lié. Comme: "Le vecteur :: assign () est un STL en C ++" o.O



4
votes

Quelle est la différence entre begin () et rend () ?

begin renvoie un itérateur au premier élément du conteneur.

rend code > renvoie un itérateur inverse à un avant le premier élément du conteneur (qui est un après le dernier élément dans la plage de l'itérateur inverse).

*v1.rend()

Le comportement de l’indirectage via l’itérateur rend n’est pas défini (il en va de même pour l’indirecteur via l’itérateur end ).

Pourquoi y a-t-il des résultats si différents?

Outre le comportement indéfini dans un cas et pas dans l'autre, car ils se réfèrent à différents éléments (l'un d'eux étant un élément qui n'existe pas), il y a peu de raisons de supposer que les résultats être la même chose.


0 commentaires