?
Ich wollte zwar nur ein kurzes, illustratives Beispiel posten, aber, ihr wisst schon, Feature Creep und so …
#include <vector>
#include <string>
#include <random>
#include <chrono>
#include <iostream>
#include <cstddef>
struct ArrayMitBeschreibung
{
std::vector<double> Werte;
//Für Simulationsdaten vermutlich geeignet
std::string Beschreibung;
};
ArrayMitBeschreibung DatenErzeugen(std::size_t Anz_Werte, unsigned Startwert)
{
class Datenquellentyp
{
std::default_random_engine Zahlenquelle;
std::normal_distribution<> Verteilungsumformer;
public:
Datenquellentyp(unsigned Startwert)
:Zahlenquelle(Startwert), Verteilungsumformer(6, 5)
{}
double WertErzeugen()
{
double Wert;
do
Wert = Verteilungsumformer(Zahlenquelle);
while(Wert < 0 || Wert > 12);
return Wert;
}
}
Datenquelle(Startwert);
ArrayMitBeschreibung Daten;
Daten.Beschreibung = "Bewertung des Geschmacks der Tofuburger";
for(unsigned AnzBisher = 0; AnzBisher < Anz_Werte; ++AnzBisher)
Daten.Werte.push_back(Datenquelle.WertErzeugen());
return Daten; //NRVO wird's richten
}
void DatenMischen(ArrayMitBeschreibung& Daten)
{
auto& Werte = Daten.Werte;
//Jede Operation auf Werte wirkt nun auf Daten.Werte
//Also in diesem Fall direkt auf das Array aus der Main,
//da es per Referenz übergeben wird
double Puffer;
//Besser wäre es, den Typ automatisch bestimmen zu lassen
std::size_t Idx_A = 0;
std::size_t Idx_B = Werte.back();
for(unsigned Zlr = 0; Zlr < 5*Werte.size(); ++Zlr)
{
//Werte annähernd zufällig durchtauschen
Idx_A = static_cast<std::size_t>((Werte[Idx_A] + 1) *
Werte.size()) % Werte.size();
Idx_B = static_cast<std::size_t>((Werte[Idx_B] + 1) *
2 * Werte.size()) % Werte.size();
//Beschwert euch bei dem Typen, der meinte, es wäre total
//toll Casts per Textsuche finden zu können ...
Puffer = Werte[Idx_A];
Werte[Idx_A] = Werte[Idx_B];
Werte[Idx_B] = Puffer;
}
}
int main()
{
unsigned Startwert_Simulation =
std::chrono::system_clock::now().time_since_epoch().count();
unsigned Anzahl_Werte = ((Startwert_Simulation % 419) + 13) / 15;
ArrayMitBeschreibung Daten =
DatenErzeugen(Anzahl_Werte, Startwert_Simulation);
DatenMischen(Daten);
//Die Daten sind zwar schon zufällig, aber so wird's
//sicherlich besser ;)
//Die Daten rausschreiben
std::cout << Daten.Beschreibung << ": " << '\n';
for(std::size_t Idx = 0; Idx < Daten.Werte.size(); ++Idx)
std::cout << Daten.Werte[Idx] << '\n';
}
Da wird eigentlich alles gezeigt, was du brauchst.
Generell, und kürzer:
std::vector<int> T; //Ein Array von Ints
T.push_back(17); //Element hinzufuegen
std::vector<std::vector<int>> B; //Ein Array aus Arrays von Ints
B.push_back(T); //Und dasselbe, Element dazu (diesmal natürlich ein Array)
Wenn der Compiler keinen Speicher für Variablen reservieren kann (z.B. weil zur Übersetzungszeit noch gar nicht bekannt ist, wie viele Elemente die Arrays haben werden), dann muss man sich selbst darum kümmern, dass es irgendwo Speicherplatz für sie gibt. Das ist bei Matlab vielleicht anders (ich kenne Matlab nicht, aber es ist bei vielen Skriptsprachen so).
Der Vector übernimmt das für einen – es fordert automatisch genug Speicher an (wenn man push_back verwendet, nicht bei Zugriffen mit dem Indexoperator (den eckigen Klammern)!), gibt ihn sicher wieder frei und hält den Zeiger auf die Elemente, verwaltet also die Information, wo sie im Speicher liegen.
Schau dir auch mal in einer C++-Referenz deiner Wahl die Beschreibungen der Funktionen reserve und resize des vectors an, die könnten dir noch helfen.