Programmierkurs für absolute Anfänger
 Listen und Arrays
Caren Brinckmann
Sommersemester 2005
http://www.coli.uni-saarland.de/~cabr/teaching.php
Wh.: for-Schleife

Syntax:





for (Init; Bedingung; Aktualisierung) {
Anweisungsblock
}
Initialisierung: Zu Anfang wird die Zählvariable auf einen
bestimmten Wert gesetzt.
Bedingung: Wenn die Bedingung wahr ist, wird der
Anweisungsblock ausgeführt.
Aktualisierung: Nach jeder Ausführung des Anweisungsblocks
wird der Aktualisierungsausdruck ausgewertet (meistens wird die
Zählvariable verändert).
Anweisungsblock wird ausgeführt, solange Bedingung wahr ist.
for-Schleife als Flussdiagramm
Programmierkurs für absolute Anfänger – Sitzung 8
1
Wh.: Schachtelung von for-Schleifen


gewünschte Ausgabe:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
Lösung: Schachtelung zweier for-Schleifen
$maximum = 5;
for ($zeile=1; $zeile<=$maximum; $zeile++) {
for ($spalte=1; $spalte<=$zeile; $spalte++) {
print "$spalte ";
}
print "\n";
}
Programmierkurs für absolute Anfänger – Sitzung 8
2
Listen (1)



Liste: geordnete Ansammlung von skalaren Werten (d.h.
Einzelwerten)
Jedes Element einer Liste enthält einen von den anderen Elementen
unabhängigen skalaren Wert, z.B. eine Zahl, eine Zeichenkette oder
undef.
Die Elemente sind indiziert (d.h. nummeriert) mit ganzzahligen
Werten. ACHTUNG: Die Indizierung beginnt immer mit 0 und wird in
Einerschritten hochgezählt.
Werte
Beispiel: Liste mit 5 Elementen
Nummern der
Elemente (Indizes)

35
0
12.4
1
undef
2
"Hallo"
3
4 "Ciao!\n"
Programmierkurs für absolute Anfänger – Sitzung 8
3
Listen (2)

Anzahl der Elemente: beliebig!



kleinste Liste: leere Liste (gar keine Elemente)
größte Liste: füllt den gesamten Hauptspeicher
Listenliterale: Durch Kommata getrennte Werte, die von runden
Klammern umschlossen werden. Diese Werte stellen die einzelnen
Elemente der Liste dar.
(1, 2, 3)
("Fred", 4.5)
("Fred", "Barney", "Betty", "Wilma", "Dino")
( )
# leere Liste
($a, 17)
# zwei Elemente: der gegen# wärtige Wert von $a und 17
($b + $c, "Antwort: $a")
Programmierkurs für absolute Anfänger – Sitzung 8
4
Bereichsoperator ..

Der Bereichsoperator .. erzeugt eine Liste von Werten, indem er in
Einerschritten vom linken bis zum rechten Skalar hochzählt.
(1..5)
# das gleiche wie (1, 2, 3, 4, 5)
(1.7..5.7)
# das gleiche - beide Werte
# werden abgerundet
(5..1)
# leere Liste - .. funktioniert
# nur "bergauf"
(0, 2..6, 10, 12) # das gleiche wie
# (0, 2, 3, 4, 5, 6, 10, 12)
($a..$b)
# Bereich, der durch die gegenwärtigen
# Werte von $a und $b definiert wird.
Programmierkurs für absolute Anfänger – Sitzung 8
5
Listenzuweisung

Listen können bestimmten Variablen zugewiesen werden:
($fred, $dino, $barney) =
("Feuerstein", undef, "Geroellheimer");

Die Werte zweier Variablen können in Perl daher einfach miteinander
vertauscht werden:
($fred, $barney) = ($barney, $fred);

Was passiert, wenn die Anzahl der Variablen (links vom
Gleichheitszeichen) und die Anzahl der Werte (auf der rechten Seite)
unterschiedlich groß sind?


überzählige Werte werden ignoriert
überzähligen Variablen wird undef zugewiesen
($fred, $barney) =
("Feuerstein", "Geroellheimer", "Schiefer");
($wilma, $dino) = ("Feuerstein");
Programmierkurs für absolute Anfänger – Sitzung 8
6
Arrays

Array: Variable, die eine Liste enthält

In Perl beginnen skalare Variablen mit $
Arrayvariablen beginnen mit @
@meinarray = (1, 3, "a", 20.5);

Der Wert einer Arrayvariablen, der noch nichts
zugewiesen wurde ist (), die leere Liste.
@meinarray = @uninitarray;

Achtung: @meinarray und $meinarray sind zwei
verschiedene Variablen!
Programmierkurs für absolute Anfänger – Sitzung 8
7
Zugriff auf einzelne Elemente




Jedes Element eines Arrays enthält einen skalaren Wert.
Auf ein einzelnes Element eines Arrays wird über seinen Index und
den Subskript-Operator [] zugegriffen:
@meinarray = (1, 3, "a", 20.5);
print "$meinarray[1]\n";
$meinarray[0] = "hallo";
$meinarray[2] .= "ber";
Index: Jeder beliebige Ausdruck, der einen numerischen Wert zum
Ergebnis hat. Etwaige Nachkommastellen werden abgeschnitten.
$zahl = 1.756;
print $meinarray[$zahl + 2];
Weist der Index auf ein Element, das hinter dem Ende eines Arrays
liegen würde, wird der entsprechende Wert automatisch als undef
angesehen.
$wert = $meinarray[6];
Programmierkurs für absolute Anfänger – Sitzung 8
8
Automatische Arrayerweiterung



Wenn man versucht, etwas in einem Arrayelement zu
speichern, das hinter dem Ende des Arrays liegt, so wird
das Array je nach Bedarf automatisch erweitert.
Dabei neu erzeugte Elemente werden mit undef belegt.
Beispiel:
$steine[0]
$steine[1]
$steine[2]
$steine[99]


=
=
=
=
"feuerstein";
"schiefer";
"lava";
"basalt";
Wieviele Elemente hat @steine ?
Welchen Wert hat $steine[50] ?
Programmierkurs für absolute Anfänger – Sitzung 8
9
Spezielle Arrayindizes

Index des letzten Elements des Arrays @steine ist
$#steine
@steine = ("schiefer", "lava", "basalt");
print $steine[$#steine];

Achtung: $#steine ist nicht identisch mit der Anzahl der
Elemente in @steine (da der erste Index 0 ist):
$anzahl_steine = $#steine + 1;

Negative Arrayindizes zählen rückwärts vom Ende des
Arrays nach vorn, beginnend mit Index -1 für das letzte
Arrayelement:
print $steine[-1];
print $steine[-3];
Programmierkurs für absolute Anfänger – Sitzung 8
10
Listenzuweisung mit Arrays

Ein Array in ein anderes kopieren:
@steine = ("schiefer", "lava", "basalt");
@kopie = @steine;

Da Arrays nur skalare Werte enthalten können, kann ein
Array selbst nicht als Listenelement benutzt werden.
Ggf. wird es durch die in ihm enthaltenen Elemente
ersetzt:
@leer = ();
$meinstein = "granit";
@steinbruch =
(@steine, "kies", @leer, $meinstein);
Programmierkurs für absolute Anfänger – Sitzung 8
11
Interpolation von Arrays in
Zeichenketten



Wie Skalare können auch Arrayvariablen in einer Zeichenkette in
doppelten Anführungszeichen interpoliert werden.
Die einzelnen Array-Elemente werden bei der Interpolation
automatisch durch Leerzeichen voneinander getrennt.
Vor und nach dem interpolierten Array werden keine zusätzlichen
Leerzeichen eingefügt.
@steine = ("schiefer", "lava", "basalt");
print "Drei Steine: @steine.\n";

Achtung: Wenn print direkt mit einem Array als Argument
aufgerufen wird, so werden die Arrayelemente ohne trennende
Leerzeichen ausgegeben!
print @steine;
Programmierkurs für absolute Anfänger – Sitzung 8
12
Funktion reverse


Die Funktion reverse nimmt eine Werteliste (die auch aus einem
Array kommen kann) und gibt sie in umgekehrter Reihenfolge wieder
zurück.
Wird der Rückgabewert nirgendwo zugewiesen, ist diese Funktion
nutzlos.
@steine = ("Basalt", "Schiefer", "Lava");
reverse @steine;
print "@steine\n";
@steine = reverse @steine;
print "@steine\n";
@zahlen = reverse 6..10;
print "@zahlen\n";
Programmierkurs für absolute Anfänger – Sitzung 8
13
Funktion sort



Die Funktion sort nimmt eine Werteliste (die auch aus einem Array
kommen kann) und gibt sie sortiert zurück.
Die Sortierung erfolgt nach der intern definierten ZeichenReihenfolge (ASCII-Sortierung: Zahlen vor Großbuchstaben vor
Kleinbuchstaben).
Wird der Rückgabewert nirgendwo zugewiesen, ist diese Funktion
nutzlos.
@steine = ("Basalt", "Schiefer", "Granit", "Lava");
@sortiert = sort(@steine);
print "sortiert: @sortiert\n";
@zurueck = reverse sort @steine;
print "zurueck: @zurueck\n";
@zahlen = sort 97..102;
print "zahlen: @zahlen\n";
Programmierkurs für absolute Anfänger – Sitzung 8
14
Skalarer Kontext vs. Listenkontext (1)

Ein gegebener Ausdruck kann verschiedene Dinge
bedeuten, je nachdem, in welchem Zusammenhang er
auftaucht.

Wenn Perl einen Ausdruck parst, erwartet es immer
entweder einen skalaren Wert oder einen Listenwert.
Dies nennt man den Kontext eines Ausdrucks:
5 + irgendetwas # irgendetwas muss ein skalarer Wert sein
sort irgendetwas # irgendetwas muss ein Listenwert sein

Selbst wenn es sich bei irgendetwas um die gleiche
Folge von Zeichen handelt, wird sie in ersten Fall als
Skalar interpretiert, im zweiten jedoch als Liste!
Programmierkurs für absolute Anfänger – Sitzung 8
15
Skalarer Kontext vs. Listenkontext (2)

Ausdrücke geben in Perl immer den ihrem Kontext
entsprechenden Wert zurück.

Array: Im Listenkontext werden die einzelnen Elemente
zurückgegeben, im skalaren Kontext jedoch die Anzahl
der Elemente:
@leute
= ("Fred", "Wilma", "Betty");
@sortiert = sort @leute;
$zahl
= 5 + @leute;

Auch eine Zuweisung (auf einen skalaren Wert oder
eine Liste) kann einen unterschiedlichen Kontext
bedeuten:
@liste = @leute;
$n = @leute;
Programmierkurs für absolute Anfänger – Sitzung 8
16
<STDIN> im Listenkontext

Im skalaren Kontext gibt <STDIN> jeweils die
nächste Zeile der Standardeingabe zurück.
$zeile = <STDIN>;

Im Listenkontext gibt <STDIN> alle verbleibenden
Zeilen bis zum Dateiende zurück. Jede Zeile wird
hierbei als eigenes Listenelement behandelt.
@zeilen = <STDIN>;
chomp(@zeilen);

# eine Zeile einlesen
# alle Zeilen einlesen
# alle \n entfernen
Vorsicht bei sehr großen Dateien: Grenzen des
Arbeitsspeichers!
Programmierkurs für absolute Anfänger – Sitzung 8
17
Funktion split (1)

Bisher: vereinfachte Syntax von split
split(/Trennzeichen/,Zeichenkette)
$zeile = "g-40";
($laut1,$dauer1) = split(/-/,$zeile);

Tatsächlich: split(/regulärer Ausdruck/, Zeichenkette)
liefert als Rückgabewert eine Liste, die in einem Array gespeichert
werden kann.
@silben = split(/[-_]/,"ap-fE_lIC");
print $silben[2];

Außerdem: Gruppierungen (in runden Klammern gesetzte Muster) im
regulären Ausdruck werden als Listenelement mit zurückgeliefert.
@silben = split(/([-_])/,"ap-fE_lIC");
print $silben[3];
Programmierkurs für absolute Anfänger – Sitzung 8
18
Funktion split (2)

Wenn zwei Trennmuster direkt aufeinander folgen, gibt split
an der Stelle als Element den Leerstring zurück:
@felder = split(/:/,"abc:de::fg:hi");
print $felder[2];
@felder = split(/:+/,"abc:de::fg:hi");
print $felder[2];

Leere Elemente zu Beginn der erzeugten Liste werden
zurückgegeben, leere Elemente am Ende nicht.
@felder = split(/:/,":::abc:de:fg:::");
print $felder[2];
print $#felder;
Programmierkurs für absolute Anfänger – Sitzung 8
19
Funktion join

Syntax: join(Kleber, Liste)

join verbindet die Elemente der Liste durch die "Kleber"Zeichenkette und gibt die resultierende Zeichenkette
zurück.
@zahlen = (1..10);
$kette = join ("-", @zahlen);
print $kette;
print join(":", split(/ */, "hallo du"));
print join("\t", reverse(split(/\s+/,"hallo du")));
Programmierkurs für absolute Anfänger – Sitzung 8
20
Funktionen: pop und push

pop entfernt das letzte Element aus einer Liste und gibt es zurück:
@zahlen = (5..9);
$zahl1 = pop(@zahlen);
$zahl2 = pop @zahlen;
pop @zahlen;
print "$zahl1, $zahl2, $zahlen[$#zahlen]\n";

Ist das Array leer, gibt pop statt eines Elements undef zurück.

push fügt ein Element (oder eine Liste von Elementen) am Ende
eines Arrays hinzu:
push(@zahlen, 0);
push @zahlen, 8;
push @zahlen, 1..5;
@andere = (9, 0, 2);
push @zahlen, @andere;
print "Zahlen: @zahlen\n";
Programmierkurs für absolute Anfänger – Sitzung 8
21
Funktionen: shift und unshift



shift entfernt das erste Element aus einer Liste und gibt es zurück.
Ist das Array leer, gibt shift statt eines Elements undef zurück.
unshift fügt ein Element (oder eine Liste von Elementen) am Anfang
eines Arrays hinzu.
@array = ("Dino", "Fred", "Barney");
$a = shift(@array);
$b = shift @array;
print "$a, $b, @array\n";
shift @array;
$c = shift @array;
unshift(@array, 4);
@andere = 1..3;
unshift @array, @andere;
print "Array: @array\n";
Programmierkurs für absolute Anfänger – Sitzung 8
22
Funktion splice (1)

Syntax:
splice(Array, Offset);
splice(Array, Offset, Länge);
splice(Array, Offset, Länge, Liste);

splice entfernt Elemente aus dem Array, beginnend mit dem
Element mit Index Offset, und hat als Rückgabewert die Liste
der entfernten Elemente.

Wenn nur Array und Offset angegeben sind, werden alle
Elemente ab Offset bis zum Ende des Arrays entfernt.
@steine = ("Basalt", "Schiefer", "Granit", "Lava");
@geloescht = splice(@steine, 1);
print "@steine\n";
print "@geloescht\n";
Programmierkurs für absolute Anfänger – Sitzung 8
23
Funktion splice (2)

Wenn Länge angegeben ist, werden ab Offset nur Länge Elemente
entfernt.
@steine = ("Basalt", "Schiefer", "Granit", "Lava");
@geloescht = splice(@steine, 1, 2);
print "@steine\n";
print "@geloescht\n";

Wenn Liste angegeben ist, werden ab Offset Länge Elemente entfernt
und durch die Elemente der Liste ersetzt.
@steine = ("Basalt", "Schiefer", "Granit", "Lava");
@mehrsteine = ("Marmor", "Sandstein", "Kies");
$offset = 2;
splice(@steine, $offset, 1, @mehrsteine);
print "@steine\n";

Übung: Das Element "Granit" aus @steine entfernen:
@steine = ("Basalt", "Schiefer", "Granit", "Lava");
Programmierkurs für absolute Anfänger – Sitzung 8
24
foreach-Schleife

Die foreach-Schleife geht eine Liste (ein Array) Element für Element
durch. Bei jedem Schleifendurchlauf wird der angegebene
Anweisungsblock für jedes Element jeweils einmal ausgeführt.
foreach $stein ("Basalt", "Schiefer", "Lava") {
print "$stein ist ein Stein.\n";
}
@steine = ("Basalt", "Schiefer", "Lava");
foreach $stein (@steine) {
$stein = "\t$stein";
$stein .= "\n";
}
print "Die Steine sind:\n";
print @steine;
Programmierkurs für absolute Anfänger – Sitzung 8
25
for-Schleife über Arrayindizes (1)

Beispiel: Nach kleinster Zahl in einer Datei suchen, in
der in jeder Zeile genau eine Zahl steht.
@zahlen = <STDIN>;
chomp(@zahlen);
$min = $zahlen[0];
for ($i=1; $i<=$#zahlen; $i++) {
if ($zahlen[$i] < $min) {
$min = $zahlen[$i];
}
}
print "Die kleinste Zahl ist: $min\n";

Übung: Dasselbe mit einer foreach-Schleife lösen!
Programmierkurs für absolute Anfänger – Sitzung 8
26
for-Schleife über Arrayindizes (2)

Beispiel: Array durchlaufen und Differenz zur jeweiligen
Nachbarzahl ausgeben.
@zahlen = (2, 999, 9, -45, 162, 5679, 0, -23);
for ($i=0; $i<$#zahlen; $i++) {
$diff = $zahlen[$i] - $zahlen[$i+1];
print "$diff ";
}
print "\n";
Programmierkurs für absolute Anfänger – Sitzung 8
27
for-Schleife über Arrayindizes (3)

Beispiel: Array durchsuchen, ob es eine negative Zahl
enthält.
@zahlen = (2, 999, 9, -45, 162, 5679, 0, -23);
$gefunden = 0;
for ($i=0; !$gefunden && $i<=$#zahlen; $i++) {
if ($zahlen[$i] < 0) {
$gefunden = 1;
}
}
if ($gefunden) {
print "Array enthält eine negative Zahl.\n";
} else {
print "Array enthält keine negative Zahl.\n";
}
Programmierkurs für absolute Anfänger – Sitzung 8
28
while-Schleife über ein Array

Beispiel: Alle Zahlen aus einem Array entfernen, die
größer als 100 sind.
@zahlen = (2, 999, 9, -45, 162, 5679, 0, -23);
$i = 0;
while ($i <= $#zahlen) {
if ($zahlen[$i] > 100) {
splice(@zahlen, $i, 1);
} else {
$i++;
}
}
print "@zahlen\n";
Programmierkurs für absolute Anfänger – Sitzung 8
29
Beispiel "Kiel Corpus of Read Speech"
kkos025.s1h
Ich mu~ nach M}nchen.
oend
Q I C+ m U s+ n a: x+
kend
c: &0 Q- -q I C+ &0
@- n . &2. &PGn
hend
8416 #c:
8416 #&0
8416 ##Q8416 $-q
8416 $I
9587 $C+
10691 #&0
10691 ##m
11797 $U
...
23260 $n
25211 #.
25211 #&2.
25211 #&PGn
m 'Y n C @ n
m U s+
&0
.
n a: x+
&2^
m 'Y n C
0.5259375
0.5259375
0.5259375
0.5259375
0.5259375
0.5991250
0.6681250
0.6681250
0.7372500
1.4536875
1.5756250
1.5756250
1.5756250
Programmierkurs für absolute Anfänger – Sitzung 8
30

ppt