Ein bisschen wirft die Frage auf, warum? Sie können als Array auf einen Vektor zugreifen. Was macht ein Array, was ein Vektor nicht macht?
Michael Dorgan
96
@ Michael Der typische Anwendungsfall, den ich habe, ist die Verwendung eines Vektors in meinem eigenen Code und das Aufrufen einer Drittanbieterfunktion, die ein Array benötigt
Michael Mrozek
7
Die herumgeworfene Terminologie ist verwirrend. Ein Zeiger ist kein Array. Wollen wir einen Zeiger auf das erste Element eines Arrays oder ein Array?
GManNickG
7
absolut eine echte Frage - auch eine recht einfache, leicht zu interpretierende. Bitte wieder öffnen.
dbliss
10
"Irgendwie wirft die Frage auf, warum?" - Erstens, Missbrauch dieses Satzes. Zweitens ist es offensichtlich, warum.
Jim Balter
Antworten:
533
Es gibt einen ziemlich einfachen Trick, da die Spezifikation jetzt garantiert, dass Vektoren ihre Elemente zusammenhängend speichern:
@ganuke Du kopierst nicht, du machst einen Zeiger, der auf das tatsächliche Array zeigt, das der Vektor intern verwendet. Wenn Sie GMans Antwort kopieren möchten, erklären Sie, wie
Michael Mrozek
4
@ganuke: Was ist "das Array"? Sie müssen weitere Informationen bereitstellen. Was ist das große Ganze?
GManNickG
6
@ganuke Das tust du nicht, du brauchst nur einen double*, der auf die gleichen Daten verweist. Diese Antwort funktioniert für genau diesen Fall
Michael Mrozek
6
@guneykayim Der Vektor besitzt diesen Speicher, Sie sollten ihn nicht freigeben
Michael Mrozek
23
std::vector<double> v; double* a = v.data();
SinoTrinity
148
Wozu? Sie müssen klarstellen: Benötigen Sie einen Zeiger auf das erste Element eines Arrays oder ein Array?
Wenn Sie eine API-Funktion aufrufen, die die erstere erwartet, können Sie Folgendes tun do_something(&v[0], v.size()): Dabei vhandelt es sich um einen Vektor von doubles. Die Elemente eines Vektors sind zusammenhängend.
Andernfalls müssen Sie nur jedes Element kopieren:
Hinweis: Verwenden Sie v.size (), um die Anzahl der Elemente für das neue Array abzurufen: double arr [v.size ()];
Rbaleksandar
7
@rbaleksandar: Arrays können keine nicht konstante Ausdrucksgröße haben.
GManNickG
@ GManNickG: Es funktioniert, aber ich denke, hier gibt es einige Missverständnisse. Stellen Sie sich Folgendes vor: Sie haben eine Klasse mit einer Reihe von Zeigern verschiedener Typen, die auf Arrays verweisen müssen, die zum Zeitpunkt der Definition Ihrer Klasse nicht bekannt sind und die später durch Leeren verschiedener Vektoren und Verwenden ihres Größenparameters erstellt werden um zu bestimmen, wie viel Platz verwendet werden soll. Ein weiteres Beispiel: eine einfache Funktion void arrayTest (unsigned int arrSize), die ein Array (short arr [arrSize];) darin erstellt, indem sie ihren Funktionsparameter für die Größe verwendet.
Rbaleksandar
1
@rbaleksandar Kein Missverständnis; In C ++ 11 und früheren Versionen müssen Arraygrößen integrale konstante Ausdrücke sein. Ihr Funktionsbeispiel wird häufig für VLAs in C verwendet, jedoch nur von der (nicht standardmäßigen) Erweiterung in C ++ unterstützt. Es kann jedoch zu C ++ 14 kommen: stackoverflow.com/a/17318040/87234 . Aber ab sofort ist es einfach keine Standardoption.
GManNickG
1
@GManNickG Ich denke, @Jet sagt, wenn Sie einen Vektor in ein Array konvertieren möchten und Sie beabsichtigen, die Größe des Arrays mithilfe der size()Funktion zu ändern, die std:vectorSie verwenden müssen newoder dies malloctun müssen. Wie bereits erwähnt (von Ihnen), double arr[v.size()]ist dies nicht gültig. Die Verwendung eines Vektors anstelle eines neuen ist eine gute Idee, aber der ganze Punkt der Frage ist, wie Sie einen Vektor in ein Array konvertieren können.
Dies funktioniert garantiert standardmäßig, es gibt jedoch einige Einschränkungen: Achten Sie insbesondere darauf, dass Sie das Gerät nur verwenden, thearraywenn thevectores im Umfang ist.
Wenn Sie eine Funktion haben, brauchen Sie wahrscheinlich diese : foo(&array[0], array.size());. Wenn Sie es geschafft haben, in eine Situation zu geraten, in der Sie ein Array benötigen, müssen Sie eine Umgestaltung vornehmen. Vektoren sind im Grunde genommen erweiterte Arrays. Sie sollten sie immer verwenden.
Antworten:
Es gibt einen ziemlich einfachen Trick, da die Spezifikation jetzt garantiert, dass Vektoren ihre Elemente zusammenhängend speichern:
quelle
double*
, der auf die gleichen Daten verweist. Diese Antwort funktioniert für genau diesen Fallstd::vector<double> v; double* a = v.data();
Wozu? Sie müssen klarstellen: Benötigen Sie einen Zeiger auf das erste Element eines Arrays oder ein Array?
Wenn Sie eine API-Funktion aufrufen, die die erstere erwartet, können Sie Folgendes tun
do_something(&v[0], v.size())
: Dabeiv
handelt es sich um einen Vektor vondouble
s. Die Elemente eines Vektors sind zusammenhängend.Andernfalls müssen Sie nur jedes Element kopieren:
Stellen Sie sicher, dass nicht nur
arr
das groß genug ist, sondern dass esarr
voll ist oder dass Sie nicht initialisierte Werte haben.quelle
size()
Funktion zu ändern, diestd:vector
Sie verwenden müssennew
oder diesmalloc
tun müssen. Wie bereits erwähnt (von Ihnen),double arr[v.size()]
ist dies nicht gültig. Die Verwendung eines Vektors anstelle eines neuen ist eine gute Idee, aber der ganze Punkt der Frage ist, wie Sie einen Vektor in ein Array konvertieren können.Für C ++ 11 ,
vector.data()
wird es tun.quelle
Dies funktioniert garantiert standardmäßig, es gibt jedoch einige Einschränkungen: Achten Sie insbesondere darauf, dass Sie das Gerät nur verwenden,
thearray
wennthevector
es im Umfang ist.quelle
empty()
, da sonst die gefürchtete UB aufgerufen wird.Vektoren sind effektiv Arrays unter der Haut. Wenn Sie eine Funktion haben:
Sie können es so nennen:
Sie sollten niemals einen Vektor in eine tatsächliche Array-Instanz konvertieren müssen.
quelle
f( &v[0] );
für Ihre letzte ZeileIn Bezug auf
std::vector<int> vec
, vec zu erhaltenint*
, können Sie zwei Methoden:int * arr = & vec [0];
int * arr = vec.data ();
Wenn Sie irgendeine Art konvertieren möchten
T
VektorT* array
, ersetzen Sie einfach die obenint
aufT
.Ich werde Ihnen zeigen, warum die beiden oben genannten zum besseren Verständnis funktionieren.
std::vector
ist im Wesentlichen ein dynamisches Array.Hauptdatenelement wie folgt:
Das
range (start_, end_of_storage_)
ist der gesamte Array-Speicher, den der Vektor zuweist;Das
range(start_, finish_)
ist der gesamte Array-Speicher, den der Vektor verwendet;Das
range(finish_, end_of_storage_)
ist der Backup-Array-Speicher.Zum Beispiel in Bezug auf einen Vektor vec. Das hat {9, 9, 1, 2, 3, 4} Zeiger kann wie folgt.
Also
&vec[0]
= start_ (Adresse) (start_ entspricht int * array head)In
c++11
derdata()
Member-Funktion geben Sie einfach start_ zurückquelle
Wir können dies mit der data () -Methode tun. C ++ 11 bietet diese Methode.
Code-Auszug
quelle
quelle
Wenn Sie eine Funktion haben, brauchen Sie wahrscheinlich diese :
foo(&array[0], array.size());
. Wenn Sie es geschafft haben, in eine Situation zu geraten, in der Sie ein Array benötigen, müssen Sie eine Umgestaltung vornehmen. Vektoren sind im Grunde genommen erweiterte Arrays. Sie sollten sie immer verwenden.quelle
Sie können so etwas tun
quelle