Array oder vector
-
Hi Experten,
ich möchte gerne zu Übungszwecken folgende Aufgabe bearbeiten:
Programmieren Sie eine einfache Stundenplanung (Klasse stundenplan).
Eine Veranstaltung besteht nur aus einem Titel.
Implementieren Sie für die Klasse stundenplan diese Methoden:start
: zum Zuweisen der 8 Veranstaltungstitel. Damit Sie dafür keine
unnötige Schreibarbeit haben, wird Ihnen eine Textdatei (
A1-hilfe.txt ) mit 8 Veranstaltungstiteln bereit gestellt, aus der Sie sich diese heraus kopieren können.zuteilung
: zur zufälligen Verteilung der Veranstaltungen auf freie Blöcke im
Stundenplan. Kein Block darf dabei doppelt belegt werden.ausgabe
: zur Ausgabe des Stundenplans auf dem Bildschirm.Da ich mich noch nicht solange mit Programmieren befasse, wollte ich mir erstmal den Stundenplan leer ausgeben lassen.
Ich dachte da spontan an ein Zwei-Dimensionales Array.
Das heir habe ich bisher gemacht:
stundenplan.h
/* * File: stundenplan.h * Author: * * Created on 11. Juni 2014, 17:25 */ #ifndef STUNDENPLAN_H #define STUNDENPLAN_H #include "declarations.h" class Stundenplan { public: //konstuktor //Stundenplan(); //Funktionen void start(); void zuteilung(); void ausgabe(); //Membervariablen // static const int tage_limit = 6; // static const int block_limit= 6; static string tage[]; static int block[]; static string multi[][]; private: //string tage[]; }; #endif /* STUNDENPLAN_H */
Und hier die stundenplan.cpp
#include "declarations.h" #include "stundenplan.h" using namespace std; string Stundenplan::tage[] = {" ", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag"}; int Stundenplan::block[] = {1, 2, 3, 4, 5, 6}; string Stundenplan::multi[3][3] = { {"Dies ", "ist ", "ein ", "test "}, {"Mal ", "schun ", ", ", "obs ", "klappt"} }; void Stundenplan::ausgabe() { for (int i = 0; i <= 5; i++) { cout << tage[i] << " "; } cout << endl; for (int j = 0; j <= 5; j++) { cout << block[j] << endl; } cout << endl; for (int k = 0; k <= 5; k++) { cout << endl; for (int l = 0; l <= 5; l++) cout << multi[k][l]; } }
Der Copiler wirft wir dann diesen Fehler:
In file included from stundenplan.cpp:2:0: stundenplan.h:29:27: error: declaration of ‘multi’ as multidimensional array must have bounds for all dimensions except the first static string multi[][]; ^ stundenplan.cpp:9:31: error: ‘std::string Stundenplan::multi [3][3]’ is not a static member of ‘class Stundenplan’ string Stundenplan::multi[3][3] = { ^ stundenplan.cpp:12:1: error: too many initializers for ‘std::string [3] {aka std::basic_string<char> [3]}’ }; ^ stundenplan.cpp:12:1: error: too many initializers for ‘std::string [3] {aka std::basic_string<char> [3]}’ stundenplan.cpp: In member function ‘void Stundenplan::ausgabe()’: stundenplan.cpp:26:21: error: ‘multi’ was not declared in this scope cout << multi[k][l];
Irgendwie sthe ich da heute total auf dem Schlauch.
Ist da ein Array überhaupt eine gute Idee, oder ist das mit einem Vector einfacher.
Danke euch schon mal für die Hilfe.
Greetz
Tobmes
-
...
-
Ist die Größe zur Compilezeit bekannt, dann ist ein Array (oder oft besser: std::array) die bessere Wahl. Steht dir Größe erst zur Laufzeit fest oder ist gar veränderlich, dann geht ein Array nicht mehr und es muss std::vector oder ein anderer Container sein (in ein paar Jahren mag dieser Ratschlag eventuell nicht mehr aktuell sein, das wird dir sicher gleich ein C++17-early-adopter erklären).
Zum Fehler: Nun, was soll man noch sagen, was der Compiler nicht schon gesagt hat? Bei Arrays muss man bei der Deklaration zwar nicht unbedingt die Größe angeben, aber man muss den Datentyp genau angeben. Und der Datentyp ist hier wieder ein Array und um dessen Typ genau zu kennen, ist die Größe nötig.
Der spätere Fehler bei der Initialisierung ist doch auch klar beschrieben. Du sagst, das sollen 3x3 strings sein, gibst aber einmal 4 und einmal 5 Initialisierer an. Mehrdimensionale Arrays sind immer "rechteckig". Ist dies nicht erwünscht, dann muss man eine andere Datenstruktur wählen (Oft ist es erwünscht und dann wäre es falsch, etwas anderes zu wählen). Dann muss der innere Typ irgendetwas sein, was seine Größe selber kennt (bei einem Array geht die Größeninformation beim Array to pointer decay verloren). Das kann vieles sein. std::vector kennt beispielsweise seine eigene Größe. Aber auch ein Zeiger auf ein Feld kann seine eigene Größe "kennen", wenn diese per Konvention aus den gespeicherten Daten ersichtlich ist, zum Beispiel bei C-Strings.Allgemein: Warum ist alles static? Bei den Wochentagen sehe ich das ja noch ein (wobei ich bezweifle, ob ein Stundenplan auch etwas über die Namensgebung von Wochentagen wissen muss. Das gehört eigentlich woanders hin), aber block ist doch nichts anderes als ein umständliches index + 1. Bei multi habe ich gar keine Ahnung, wozu es da ist.
Sollen das eigentlich alles Konstanten sein? Falls ja: Mach sie auch konstant! Die Bezeichnung der Wochentage ändert sich sicherlich nicht im Programmverlauf. Dann kann man sich auch den std::string sparen und stattdessen const char const* als Datentyp nehmen, der dann auf das Zeichenkettenliteral verweist. Das ist ein Stück effizienter.