int
-Elementen erzeugt. Danach werden die einzelnen Array-Elemente mit Werten versehen. In eckigen Klammern wird der Null-basierte Index des jeweiligen Array-Elements angegeben.
int[] zahlen = new int[10]; for(int i = 0; i < 10; i++) zahlen[i] = (i+1) * (i+1);
[]
an. Im Gegensatz zu anderen Programmiersprachen muss das Klammerpaar immer direkt hinter dem
Datentyp angegeben werden.
new
erzeugt werden. Geben Sie dazu den Datentyp und in eckigen Klammern die Größe des Arrays an. Die Größe kann auch über den
Wert einer Variablen festgelegt werden. In dieser Hinsicht wird die Größe eines Arrays also auch dynamisch festgelegt.
null
initialisiert.
Array
aus dem Namespace System
erweitert, implementieren das Interfaces IEnumerable
und können deshalb über eine
foreach
-Schleife durchlaufen werden (mehr dazu auch im Kapitel zu den Auflistungen). Von der Klasse Array
können Sie keine eigenen Klassen ableiten, dies ist nur dem Compiler erlaubt.
Array
geerbt hat. So lässt sich z.B.
die Länge eines Arrays ermitteln oder die Anzahl der Dimensionen bestimmen.
Eigenschaft / Methode | Beschreibung |
IsFixedSizeIsReadOnly | Die Eigenschaft IsFixedSize liefert bei Arrays immer den Wert true , während IsReadOnly immer false liefert. Das heißt, ein Array hat immer
eine feste Größe und seine Elemente können immer bearbeitet werden. Beide Eigenschaften müssen aufgrund der von der Klasse Array implementierten Schnittstelle IList bereitgestellt werden. |
Length | Liefert die Länge eines Arrays aller Dimensionen. Erzeugen Sie ein zweidimensionales Array der Größe 3 x 4 erhalten Sie z.B. 12 als Rank. |
Rank | Liefert die Anzahl der Dimensionen zurück. |
Clone() | Erstellt eine so genannte flache Kopie eines Arrays. Dabei werden die Elemente kopiert, unabhängig davon, ob es Wert- oder Referenztypen sind. Dies hat die Konsequenz, dass die Referenzen auf die gleichen Objekte wie die des ersten Arrays zeigen. |
GetLength() | Liefert die Größe der im Parameter angegebenen Dimension zurück. Damit können Sie gegenüber der Eigenschaft Length auch die Größe von einzelnen Dimensionen in
mehrdimensionalen Arrays bestimmen. |
zahlen1
wird in einer Zeile deklariert und erzeugt. Es kann drei int
-Werte
aufnehmen. Auf die Elemente eines Arrays wird über den Index zugegriffen und ein passender Wert wird zugewiesen.
Die Arrays zahlen2
und zahlen3
verwenden einen (Array-)Initialisierer, der die Größe vorgibt und die Elemente auch gleich initialisiert. Die Verwendung eines Initialisierers ist nur
auf diese Weise möglich. Bei einer getrennten Deklaration und Erzeugung wie beim Array zahlen4
können Sie bei der Erzeugung keine Initialisierung mehr vornehmen.
Zum Durchlaufen eines Arrays können Sie in einer for
-Schleife die Eigenschaft Length
als obere Grenze verwenden. Die Verwendung einer for
-Schleife hat den Vorteil,
dass Sie den Index des Elements weiterverwenden können. Verwenden Sie die foreach
-Schleife, geht die Indexinformation verloren.
Zum Abschluss wird noch die Anzahl der Dimensionen zurückgegeben, die hier 1 ist.
using System; namespace CSharpBuch.Kap10 { public class EindimensionaleArrays { static void Main(string[] args) { int[] zahlen1 = new int[3]; zahlen1[0] = 2; zahlen1[1] = 3; zahlen1[2] = 5; int[] zahlen2 = { 2, 3, 5 }; int[] zahlen3 = new int[] { 2, 3, 5 }; int[] zahlen4; zahlen4 = new int[3]; for(int i = 0; i < zahlen1.Length; i++) Console.WriteLine("Zahl {0}: {1}", i, zahlen1[i]); foreach(int zahl in zahlen1) Console.WriteLine("Zahl: {0}", zahl); Console.WriteLine("Dimensionen: {0}", zahlen1.Rank); } } }Listing 10.1: EindimensionaleArrays.cs
INFO
Da die hier vorgestellten Arrays immer nur den Datentypint
, also einen Werttyp, verwendet haben, wurde im Array auch Platz für einen solchen Typ bereitgestellt.
Wenn Sie dagegen ein Array von Referenztypen erstellen, z.B. Person[]
, wird nur Platz für die Referenzen bereitgestellt. Die Objekte müssen Sie für jedes Element separat erstellen. Dazu folgt noch
ein Beispiel.{}
an.
Trennen Sie die Klammerpaare mit einem Komma.
object
-Elementen erzeugen und diese beim Entnehmen
wieder in den korrekten Datentyp casten.
matrix3
sind auch dynamische Größenangaben
über Variablen möglich. Damit Sie die Größen der Dimensionen dynamisch ermitteln können, verwenden Sie die Methode GetLength()
unter Angabe der Dimension.
Zum Abschluss werden die Größen der einzelnen Dimensionen des Arrays ausgegeben.
using System; namespace CSharpBuch.Kap10 { public class MehrdimensionaleArrays { static void Main(string[] args) { int[,] matrix1 = new int[2,3]; int[,] matrix2 = new int[2, 3] { {2, 4, 6}, {1, 3, 5} }; int zeilen = 3; int spalten = 10; int[,] matrix3 = new int[zeilen, spalten]; for(int i = 0; i < matrix2.GetLength(0); i++) for(int j = 0; j < matrix2.GetLength(1); j++) Console.WriteLine("{0},{1}: {2}", i, j, matrix2[i, j]); for(int dim = 0; dim < matrix2.Rank; dim++) Console.WriteLine("Größe der Dimension {0}: {1}", dim, matrix2.GetLength(dim)); } } }Listing 10.2: MehrdimensionaleArrays.cs
INFO
Auch bei mehrdimensionalen Arrays lässt sich dieforeach
-Schleife verwenden. Diese liefert aber einfach alle Elemente des Arrays, unabhängig von
ihrer Position, zurück. Wenn Sie die konkreten Indizes benötigen, ist eine verschachtelte for
-Schleife wie im Beispiel vorzuziehen.int[][] verzw = new int[3][]; verzw[0] = new int[] { 1, 2, 3};Alternativ können Sie auch alle Dimensionen initialisieren. Dazu muss pro Dimension wieder
new int[]
angegeben werden, gefolgt von den konkreten Werten.
int[][]verzw = new int[][] { new int[] {1, 2, 3}, new int[] {4, 5} };Die Angabe
new int[][]
kann auch weggelassen werden.
int[][] verzw = { new int[] {1, 2, 3}, new int[] {4, 5} };
int[][,] = new int[4][,];
Length
zur Größenbestimmung heranziehen. Der Zugriff auf die Elemente erfolgt pro Dimension über ein eigenes rechteckiges
Klammerpaar und der Angabe eines Null-basierten Index.
using System; namespace CSharpBuch.Kap10 { public class VerzweigteArrays { static void Main(string[] args) { int[][] dreieck = new int[3][]; for(int i = 1; i <= 3; i++) dreieck[i - 1] = new int[i]; for(int i = 0; i < dreieck.Length; i++) for(int j = 0; j < dreieck[i].Length; j++) dreieck[i][j] = j + 1; for(int i = 0; i < dreieck.Length; i++) { for(int j = 0; j < dreieck[i].Length; j++) Console.Write("{0}\t", dreieck[i][j]); Console.WriteLine(); } } } }Listing 10.3: VerzweigteArrays.cs Ausgabe:
1 1 2 1 2 3
ref
- oder out
-Parameter können Sie dem Parameter in der Methode z.B. ein neues Array
zuweisen. Außerdem können Sie ein Array direkt beim Aufruf der Methode erzeugen und initialisieren, wenn Sie später keinen Zugriff mehr darauf benötigen.
Summe()
erwartet ein Array von int
-Werten als Parameter. Zum Aufruf der Methode kann nun ein konkretes Array wie Werte verwendet werden oder Sie
kombinieren die Erstellung und Initialisierung bei der Parameterübergabe wie beim zweiten Aufruf von Summe()
.
int Summe(int[] werte) { int ergebnis = 0; foreach(int summand in werte) ergebnis += summand; return ergebnis; } ... int[] werte = new int[] {1, 2, 3, 4, 5}; int ergebnis = Summe(werte); int ergebnis = Summe(new int[] {1, 2, 3, 4, 5});
Init()
, Ausgabeparameter), die Werte zu modifizieren (Change()
, Wertübergabe)
und die Reihenfolge zu vertauschen (Reverse()
, Referenzparameter). Zum Abschluss werden die Werte aus dem Array noch auf der Konsole ausgegeben.
using System; namespace CSharpBuch.Kap10 { public class ArrayParameter { static void Main(string[] args) { int[] daten; Init(out daten); Change(daten); Reverse(ref daten); for(int i = 0; i < daten.Length; i++) Console.WriteLine("Wert {0}: {1}", i, daten[i]); } static void Init(out int[] daten) { daten = new int[] { 1, 2, 3 }; } static void Change(int[] daten) { for(int i = 0; i < daten.Length; i++) daten[i] = daten[i] * 2; } static void Reverse(ref int[] daten) { Array.Reverse(daten); } } }Listing 10.4: ArrayParameter.cs
Array
erben, besitzt diese Klasse noch einige sehr nützliche statische Methoden, die auf ein Array angewendet werden können. Die
Methoden besitzen zum Teil zahlreiche Überladungen, so dass ein Blick in die Hilfe empfohlen wird, wenn Sie diese nutzen möchten.
Einige dieser Methoden nutzen die Funktionalität von Generics, andere benötigen einen Delegaten, um eine bestimmte Operation auszuführen. Beide Themen werden später noch in eigenen Kapiteln
behandelt - das bekannte Problem mit dem Huhn und dem Ei.
Eigenschaft / Methode | Beschreibung |
BinarySearch() | Durchsucht ein sortiertes Array nach einem Objekt. Zum Vergleich wird die Methode CompareTo() verwendet. |
Clear() | Setzt den angegebenen Bereich auf 0 bzw. null . |
Copy() | Kopiert einen Teil eines Arrays in ein anderes Array. |
ForEach() | Führt eine Operation mit jedem Array-Element aus. |
IndexOf() LastIndexOf() | Liefert den Index des ersten/letzten Vorkommens eines Wertes im Array. |
Resize() | Erstellt ein neues Array und überträgt die Elemente des Ausgangs-Arrays. Wird das Array verkleinert, fallen überflüssige Elemente unter den Tisch. |
Reverse() | Kehrt die Reihenfolge der Elemente im Array um. |
Sort() | Sortiert die Elemente im Array. |
TrueForAll() | Prüft, ob alle Array-Elemente eine bestimmte Bedingung erfüllen. |
Person
verwaltet den Namen und das Alter einer Person. Außerdem besitzt sie eine Methode CompareTo()
, um zwei Person
-Objekte miteinander vergleichen
zu können (hier nur über den Namen). Von dieser Klasse wird jetzt ein Array erzeugt und mit vier Objekten initialisiert. Diese werden gleich bei der Erzeugung des Arrays mit angegeben.
Über die Methode ForEach()
der Klasse Array
werden die Urlaubsansprüche der Personen ausgegeben. Diese Funktionalität ließe sich natürlich auch direkt implementieren.
Durch die Verwendung der Methode ForEach()
können Sie aber sehr einfach die Methode austauschen (durch Übergabe eines anderen Delegaten - siehe Kapitel 13), welche auf die Array-Elemente
angewandt wird. Im konkreten Fall heißt dass, Sie können die Methode austauschen, die den Urlaubsanspruch berechnet (z.B. bei neuen Tarifverträgen).
Über die Methode Sort()
werden dann die Elemente des Arrays sortiert. Aus diesem Grund wurde in der Klasse Person
auch das Interface IComparable
implementiert,
da die Sortierung sonst nicht auf diese Weise möglich wäre.
Beachten Sie, dass die Daten in der Klasse Person
nur aus Gründen der Einfachheit als public
deklariert wurden. Verwenden Sie sonst besser Eigenschaften und private Variablen.
using System; namespace CSharpBuch.Kap10 { public class ArrayFunktionen { static void Main(string[] args) { Person[] personen = new Person[] { new Person("Meier", 25), new Person("Schulze", 35), new Person("Krause", 45), new Person("Duck", 30) }; Array.ForEachListing 10.5: ArrayFunktionen.cs(personen, AlterFilter); Array.Sort(personen); foreach(Person p in personen) Console.WriteLine(p.Name); } private static void AlterFilter(Person p) { if(p.Alter < 35) Console.WriteLine("{0} hat 28 Tage Urlaub", p.Name); else Console.WriteLine("{0} hat 30 Tage Urlaub", p.Name); } } public class Person: IComparable { public string Name; public int Alter; public Person(string name, int alter) { Name = name; Alter = alter; } public int CompareTo(object obj) { return Name.CompareTo((obj as Person).Name); } } }
MaxWert()
, der ein Array von int
-Werten übergeben wird. Die Methode liefert als Ergebnis den größten gefunden Wert aus dem Array zurück. Testen Sie Ihre Anwendung.
int
-Werten, das in der ersten Dimension aus drei Elementen besteht. Initialisieren Sie diese drei "Unterarrays" mit verschiedenen
Längen und initialisieren Sie diese. Übergeben Sie jetzt diese Unterarrays der Methode MaxWert()
aus Aufgabe 1. Auf diese Weise können Sie verschiedene Testreihen für diese Methode erzeugen,
die nicht immer dieselbe Länge besitzen.
1
und 5
(Klasse Random
, Methode Next()
) in einem Array abgelegt werden
sollen. Prüfen Sie über die Methode TrueForAll()
der Klasse Array
, ob alle drei Zahlen den Wert 3
besitzen. Zählen Sie die Anzahl der Testreihen, bis TrueForAll()
das Ergebnis true
liefert, und geben Sie diese Anzahl aus.