====== Arrays ====== Bisher haben wir alle Variablen einzeln definiert. Das kann aber ziemlich aufwendig werden, wenn man eine größere Anzahl von Variablen benötigt: int x1,x2,x3,x4,x5; /* Die Definition von 1000 Variablen wäre sinnvoll nicht mehr zu verwalten.*/ Auch die Arbeit mit diesen Variablen ist recht umständlich: Da jede nur unter ihrem Namen angesprochen werden kann, ist es nicht möglich, sie alle in einer Schleife zu durchlaufen. Diese Nachteile lassen sich vermeiden, wenn die Variablen nicht einzeln, sondern gemeinsam als **Array** definiert werden. Ein Array ist eine Zusammenfassung von Variablen desselben Datentyps unter einem einzigen Namen. Die einzelnen Variablen können über den Namen des Arrays und einen **Index** angesprochen werden und werden auch als Elemente des Arrays bezeichnet. Der Index kann ein Ausdruck und damit insbesondere eine Variable sein. ====== Eindimensionale Arrays ====== ===== Grundlagen ===== Ein Feld ist ein strukturierter Datentyp mit einer bestimmten Anzahl von Elementen, die alle vom selben Typ sein müssen. In der %%C++%%-Literatur werden Felder auch als Vektoren bezeichnet. Mit der Typvereinbarung werden eigene Typnamen für Felder vergeben. Diese neuen Namen können wie Standard-typenbezeichner verwendet werden. Beispiele: #define max 7 typedef float Vektor[4]; typedef char Zeile[80]; typedef int Besetzt[max]; typedef int Zaehler[26]; Die Vereinbarung eines Feldtyps enthält die **Anzahl** der Elemente und den **Elementtyp**. Die Anzahl muss eine **Konstante** sein und wird in eckige Klammern [] eingeschlossen. Wird ein Feldtyp beispielsweise mit ''float Vektor[4];'' vereinbart, bedeutet dies, dass dieses Feld 4 Elemente (jedes vom Typ ''float'') hat. Mit diesen Feldtypen können (wie mit jedem anderen Typ) Variablen vereinbart werden. Vektor v; Zeile satz; Besetzt besetzt; Zaehler anz; Auf ein einzelnes Feldelement wird über den Namen der Variablen, die mit einem Index versehen wird, zugegriffen. Der Index kann jeder beliebige int-Ausdruck sein. Der Wert des Indexausdrucks muss innerhalb der Indexgrenzen liegen. Die Untergrenze ist immer 0, die Obergrenze ist gleich der Anzahl minus 1. Der Index wird in eckige Klammern eingeschlossen. **Der Index wird nicht überprüft.** Beispiele: v[0]=25.2; v[l]=37.1; v[2]=66.3; v[3]=97.7; ch=satz[i*2]; if (zimmer[i]) ...; anz[ch-'A']=anz[ch-'A']+l; /* besser: */ anz[ch-'A']++; Da Indizes nicht überprüft werden, kann beispielsweise die folgende Zuweisung vom Compiler nicht als fehlerhaft erkannt werden: v[4]=99.0; Wird diese Anweisung ausgeführt, kann die Reaktion des Programms nicht vorhergesagt werden. Da die Variablenspeicherplätze nacheinander vergeben werden, //kann eine andere Variable verändert werden// - ein Fehler, der nur sehr schwer zu finden ist. Oft stürzt auch das Programm ab! Dieser Fehler kann auch bei zu klein dimensionierten Zeichenketten auftreten. Ein expliziter Name für einen Feldtyp darf auch fehlen, das heißt, der Feldtyp kann direkt in der Variablenvereinbarung stehen. Beispiele (diese Vereinbarungen entsprechen den schon verwendeten Vereinbarungen): #define max 7 int main() {float v[4]; char satz[80]; int zimmer[max]; int anz[26]; } Die erste Schreibweise ist aber bei längeren Programmen übersichtlicher und daher zu bevorzugen. ===== Beispiel 1 ===== 10 Zahlen sollen eingelesen werden. Es ist das arithmetische Mittel zu berechnen. Die Anzahl der Zahlen, die größer als das Mittel sind, ist auszugeben. {{:inf:cpp:adim-68-1.jpg?300|}} ++++ CPP Code| /* Berechnet die Anzahl der Zahlen, die größer als das arithmetische Mittel der Zahlenfolge sind */ #include const int anz=10; int main () { float zahl[anz],summe=0,mittel; int i,groesser=0; cout << "Bestimmt die Anzahl der Zahlen > arithm. Mittel\n"; cout << anz << " Zahlen:\n"; for (i=0;i> zahl[i]; } for (i=0;imittel) ++groesser; cout << groesser << " Zahlen sind größer als das arithmetische Mittel(" << mittel << ")\n"; system("PAUSE"); return EXIT_SUCCESS; } ++++ ===== Beispiel 2 ===== Ein beliebiger Text soll eingelesen und die absolute und relative Häufigkeit der einzelnen Großbuchstaben in Tabellenform ausgegeben werden. Der Text wird durch einen Punkt abgeschlossen. {{:inf:cpp:adim-68-2.jpg?300|}} ++++ CPP Code| /* Absolute und relative Häufigkeit der Buchstaben in einem beliebigen Text bestimmen */ #include #include #include using namespace std; int main () { char i,j,zeichen; int anz=0,zaehler[26]; for (i='A';i<='Z';++i) zaehler[i-'A']=0; printf("Häufigkeit von Großbuchstaben.\n" "Text ? ('.' = Abbruch)\n"); while ((zeichen=getche())!='.') { ++anz; if (isupper(zeichen)) ++zaehler[zeichen-'A']; } if (anz==0) anz=1; printf ("\nBuchstabe Abs.H. Rel.H. " "Buchstabe Abs.H. Rel.H.\n" "============================= " "=============================\n"); for (i='A';i<='M';++i) { if (anz==0) anz++; printf("%4c: %10d %10.1f%% ", i,zaehler[i-'A'], zaehler[i-'A']*100.0/anz); j=i+13; printf("%4c: %10d %10.1f%%\n", j,zaehler[j-'A'], zaehler[j-'A']*100.0/anz); } system("PAUSE"); return EXIT_SUCCESS; ++++ ===== Übergabe von eindimensionalen Feldern an Unterprogramme ===== Die Übergabe von Feldern an Unterprogramme erfolgt * über Typdefinition (''typdef'') oder * über Angabe der Adresse auf das betreffende Feld oder * über allgemeine Typangabe. Programmbeispiel 1 sieht mit Unterprogrammen so aus: ++++ CPP Code| /* Berechnet die Anzahl der Zahlen, die größer als das arithmetische Mittel der Zahlenfolge sind */ #include const int anz=10; typedef float Feld[anz]; // nur bei erster Variante notwendig void lesen(Feld z) { int i; for (i=0;i> z[i]; } } float mittel(Feld z) { int i; float summe=0; for (i=0;im) ++groesser; return groesser; } /* Alternative Variante der Parametervereinbarung: mit Hilfe von Zeigern void lesen(float *z) { int i; for (i=0;i> *(z+i); } } float mittel(float *z) { int i; float summe=0; for (i=0;im) ++groesser; return groesser; } */ /* Alternative Variante der Parametervereinbarung: Angabe, dass z ein eindimensionales Array von float-Werten ist void lesen(float z[]) { int i; for (i=0;i> z[i]; } } float mittel(float z[]) { int i; float summe=0; for (i=0;im) ++groesser; return groesser; } */ int main () { float zahl[anz]; float m; cout << "Bestimmt die Anzahl der Zahlen > arithm. Mittel\n"; cout << anz << " Zahlen:\n"; lesen(zahl); m=mittel(zahl); cout << zaehlen(zahl,m) << " Zahlen sind groesser als das arithmetische Mittel(" << m << ")\n"; system("PAUSE"); return EXIT_SUCCESS; } ++++ ===== Grundaufgaben ===== Erstelle unter Verwendung eines eindimensionalen Arrays ein Programm, dass * (a) ein Array mit 20 Zufallszahlen im Bereich von 1 - 100 belegt und dieses ausgibt;\\ Unterprogramme: ''erstelle'', ''ausgabe'' * (b) die Summe aller Zahlen des Arrays ausgibt;\\ Unterprogramm: ''summe'' * %%(c)%% das arithmetische dieses Zufallsarrays berechnet; * (d) nach Eingabe eines Index angibt, wie die zugeörige Zahl lautet;\\ Unterprogramm: ''index2zahl'' * (e) nach Eingabe einer Zahl angibt, ob diese im Array vorkommt oder nicht;\\ Unterprogramm: ''suche'' * (f) nach Eingabe einer Zahl angibt, an welcher Stelle diese Zahl vorkommt (wenn sie im Array enthalten ist); \\ Unterprogramm:''zahl2index'' * (g) dieses Zufallsarray verkehrt ausgibt;\\ Unterprogramm: ''invertiere'' * (h) das nach Eingabe zweier Positionen, die Werte an diesen Positionen tauscht;\\ Unterprogramm: ''tausche'' * (i) das Minimum, das Maximum und die Spannweite dieses Arrays ausgibt; \\ Unterprogramm: ''minmax'' * (j) das ein zweites Array anlegt, in dem die Werte in steigender Reihenfolge eingetragen werden; [[inf:arrays:eindimensionale-arrays:grundaufgaben|Grundaufgaben]] - Zwischenstand ===== Aufgaben ===== * [[:inf:vis-c:grundlagen:eindimensionale-arrays:Aufgaben|Aufgaben]]