Musterklausur: Grundlagen der Informatik
Hinweise zur Klausur
Die Klausur besteht aus drei Teilen:
· Im ersten Teil werden Multiple-Choice-Aufgaben gestellt. Dabei können ein oder mehrere Anworten richtig sein. Falsche Antworten führen zur kompletten Abwertung der jeweiligen Aufgabe (20 Punkte).
· Im zweiten Teil werden Programmteile vorgegeben, die zu analysieren sind (30 Punkte).
· Im dritten Teil sind Programme zu erstellen (konstruktiver Teil) (50 Punkte).
Es muß mindestens eine konstruktive Aufgabe gelöst werden, um die Klausur zu bestehen.
Insgesamt können 100 Punkte erzielt werden. Die Zeit beträgt 3 Zeitstunden!
Die zu erzielenden Punkte sind an jeder Aufgabe vermerkt.
Teil 1: Multiple-Choice-Aufgaben
Aufgabe M1 (2 Punkte)
Betrachten Sie folgenden Programmausschnitt:
char Zeichen = 'a';
switch (Zeichen)
{
case 'a':
System.out.println("a"); break;
default:
System.out.println("default");
}
Was passiert, wenn dieser Ausschnitt in einem Programm übersetzt und gestartet wird:
a Das Programm wird nicht übersetzt, da die switch-Anweisung keinen erlaubten Ausdruck enthält.
b Das Programm wird übersetzt und läuft. Es wird jedoch nichts in die Standardausgabe geschrieben.
c Das Programm wird übersetzt und läuft. Der Buchstabe 'a' wird in die Standardausgabe geschrieben.
d Das Programm wird übersetzt und läuft. Das Wort 'default' wird in die Standardausgabe geschrieben.
e Keine der Antworten ist richtig.
Aufgabe M1
Lösung: Antwort c ist richtig
Aufgabe M2 (1 Punkt)
Welcher Ausdruck ist in einer if-Anweisung erlaubt:
a Ausdruck vom Typ boolean.
b Ausdruck vom Typ int.
c Ausdruck vom Typ boolean oder vom Typ int.
d Keine der Antworten ist richtig.
Aufgabe M2
Lösung: Antwort a ist richtig. Ein if-Anweisung arbeitet nur mit boolean.
Aufgabe M3 (2 Punkte)
Betrachten Sie folgenden Programmausschnitt:
int eineZahl
= 4;
if (eineZahl < 6)
if (eineZahl < 4)
System.out.println("<
5");
else
if (eineZahl > 3)
System.out.println(">3");
else
System.out.println("Sonstiges");
Was wird in der Standard-Ausgabe ausgegeben?
a "< 4"
b "> 3"
c "Sonstiges"
d Nichts
e Keine der Antworten ist richtig.
Aufgabe M3
Lösung: Antwort b ist richtig. Dies erkennt man, wenn das Programm richtig strukturiert wird:
int eineZahl
= 4;
if (eineZahl < 6)
if (eineZahl < 4)
System.out.println("<
5");
else
if (eineZahl > 3)
System.out.println(">3");
else
System.out.println("Sonstiges");
Aufgabe M4 (2 Punkte)
Betrachten Sie folgendes Programm:
class Rechteck
{
}
class Quadrat extends Rechteck
{
public static void main(String[] args)
{
Quadrat einQuadrat = new Quadrat();
if (einQuadrat instanceof Quadrat)
System.out.println("einQuadrat ist ein Quadrat");
if (einQuadrat instanceof Rechteck)
System.out.println("einQuadrat ist ein Rechteck");
if (einQuadrat instanceof Object)
System.out.println("einQuadrat ist ein Objekt");
}
}
Was wird in der Standard-Ausgabe ausgegeben?
a "einQuadrat ist einQuadrat"
b "einQuadrat ist ein Rechteck"
c "einQuadrat ist ein Objekt"
d Nichts
e Keine der Antworten ist richtig.
Aufgabe M4
Lösung: Die Antwort a, b und c sind richtig, da der Operator instanceof für jeden Test true ergibt.
Aufgabe M5 (2 Punkte)
Welches Ergebnis wird ausgegeben, wenn das folgende Programm ausgeführt wird:
class
Objekte
{
public static void main(String[] args)
{
A einA = new B();
B einB = (B) einA; // Casting einer Objektreferenz
System.out.println(einB.Attribut);
System.out.println(einB.Operation());
}
}
class
A
{
int Attribut = 1;
int Operation()
{
return Attribut;
}
}
class
B extends A
{
int Attribut = 2;
int Operation()
{
return Attribut;
}
}
a 2
2
b 2
1
c 1
2
d 1
1
e Keine der Antworten ist richtig.
Aufgabe M5
Lösung: Antwort a ist richtig. Da die Objektreferenz einA vom Typ A explizit auf den Typ B gewandelt wird (casting), wird auf das Attribut und die Operation der Klasse B zugegriffen.
Aufgabe M6 (6 Punkte)
Wie viele Objekte sind Kandidaten für die Speicherbereinigung (garbage collection) am Ende des folgenden Programm-Ausschnitts:
String einText = "Bochum"; //1
einText = "Bochum" + "-Wattenscheid"; //2
int[] einFeld = {2, 5, 10, 75}; //3
einFeld[3] = 17; //4
einFeld = new int[4]; //5
einText
= null; //6
a 1
b 2
c 3
d 4
e Keine der Antworten ist richtig.
Aufgabe M6
Lösung: Richtig ist c.
Am Ende der Zeile 2 sind zwei Objekte erzeugt. Das erste Objekt enthält "Bochum", das zweite "Bochum-Wattenscheid". Da auf das erste Objekt nicht mehr referenziert wird, ist es das erste für die Speicherbereinigung.
Am Ende von Zeile 4 ist ein neues int-Feldobjekt erzeugt und es wurde auf ein Feldelement zugegriffen.
In Zeile 5 wird ein neues Feldobjekt erzeugt und der Objektreferenz einFeld zugewiesen. Das bisherige Feldobjekt mit {2, 5, 10, 75} unterliegt als zweites Objekt der Speicherbereinigung.
In Zeile 6 wird der Objektreferenz einText der Nullzeiger zugewiesen. Damit wird als drittes Objekt "Bochum-Wattenscheid" der Speicherbereinigung zur Verfügung gestellt.
Aufgabe M7 (2 Punkte)
Sie wollen über Ereignisse von zwei Druckknöpfen und der Tastatur informiert werden. Wieviele Abhörer (listener) benötigen Sie dazu?
a 0
b 1
c 2
d 3
e 4
Aufgabe M7
Lösung: Richtig ist Antwort c. Sowohl für die Druckknopfereignisse als auch für die Tastaturereignisse wird jeweils ein Abhörer benötigt.
Aufgabe M8 (3 Punkte)
Was versteht man in Java unter einer Adapterklasse?
a Dient zur Anpassung der applets an die jeweilige Betriebssystemumgebung.
b Stellt die Verbindung zwischen einer Ereignisquelle und einem Ereignisabhörer dar.
c Erlaubt die Unterklassenbildung auf der Abhörerseite zur Verarbeitung von elementaren Ereignissen.
d Implementiert eine elementare Ereignisschnittstelle mit leeren Operationsrümpfen.
e Stellt für Ereignisquellen die Ereignismitteilungen zur Verfügung.
Aufgabe M8
Lösung: c und d sind richtig.
Teil 2: Analytische Aufgaben
Aufgabe A1 (10 Punkte)
Betrachten Sie folgende zwei Klassen:
class
A
{
//Attribut
int A1 = 10;
//Konstruktor
A()
{
}
//Operationen
int getA1()
{
return A1;
}
void setA1(int A1)
{
this.A1=A1;
}
}
class
Haupt
{
public static void main(String[] args)
{
A einA = new A();
A nocheinA = new A();
System.out.println("einA= " +
einA.getA1() + " nocheinA= " + nocheinA.getA1());
einA.setA1(20);
nocheinA = einA;
System.out.println("nocheinA2= " + nocheinA.getA1());
einA = null;
System.out.println("einA2= " + einA.getA1());
}
}
a Geben Sie durch ein Klassen- und Objektdiagramm den dynamischen Ablauf an. Zeichnen Sie dabei für jedes Objekt das Objektdiagramm nach UML ergänzt um eine Speicherzelle, die auf das Objekt zeigt.
b Welche Ergebnisse werden durch die print-Anweisungen ausgegeben?
c Das Programm wird um folgende Klasse erweitert:
class
B extends A
{
//Attribut
int B1 = 25;
//Operationen
int getB1()
{
return B1;
}
}
Das Hauptprogramm wird wie folgt ergänzt:
class
Haupt
{
public static void main(String[] args)
{
A einA = new A();
A nocheinA = new A();
System.out.println("einA= " +
einA.getA1() + " nocheinA= " + nocheinA.getA1());
einA.setA1(20);
nocheinA = einA;
System.out.println("nocheinA2= " + nocheinA.getA1());
einA = null;
// System.out.println("einA2= " + einA.getA1());
//Ergänzung
B einB = new B();
System.out.println("einB:B1= " + einB.getB1() + " einB:A1: " + einB.getA1());
B nocheinB = new B();
einA = nocheinB;
System.out.println("einA:A1= " + einA.getA1());
}
}
Zeichnen Sie ein Objektdiagramm, das die dynamischen Abläufe zeigt.
Welche Ergebnisse geben die print-Anweisungen aus?
Teil 2: Analytische Aufgaben
Aufgabe A1
Hierzu gibt es leider noch keine Musterlösung. Vorschläge bitte an:
mielke@swt.ruhr-uni-bochum.de
Aufgabe A2 (5 Punkte)
Betrachten Sie folgende Klasse:
class
C
{
//Attribut
Object einObjekt;
//Konstruktor
C(Object einObjekt)
{
this.einObjekt = einObjekt;
}
}
a Was bewirkt dieser Konstruktor?
b Gehen Sie davon aus, daß ein aufrufendes Objekt eine Referenz auf sich selbst (this) an den Konstruktor von C übergibt. Wofür benötigt man dies? Geben Sie ein Beispiel an, wo in Java davon Gebrauch gemacht wird.
Aufgabe A2
Lösung:
a Der Konstruktor bewirkt, daß das Objekt, das diesen Konstruktor aufruft, eine Referenz, z.B. seine eigene Speicheradresse, an das neue Objekt übergibt. Diese Referenz wird in dem Attribut einObjekt gespeichert. Ein konkretes Beispiel zeigt folgendes Java-Programm:
class C
{
//Attribut
Haupt einObjekt;
//Konstruktor
C(Haupt einObjekt)
{
this.einObjekt = einObjekt;
}
//Operation
void rufeC()
{
einObjekt.setH1("Dies ist ein Aufruf von C aus");
}
}
class
Haupt
{
public static void main (String[] args)
{
Haupt einHaupt = new Haupt();
einHaupt.herstelleReferenz();
}
void herstelleReferenz()
{
C einC = new C(this);//Übergabe der eigenen Referenz
einC.rufeC();
}
void setH1(String einText)
{
System.out.println(einText);
}
}
b Die Referenz wird benötigt, damit das erzeugte Objekt seinen Erzeuger aufrufen kann. Dies wird in Java bei dem Ereigniskonzept verwendet. Der Abhörer registriert sich und übergibt dabei seine Referenz, so daß die Quelle beim Eintreten des Ereignisses den Abhörer aufrufen kann.
Aufgabe A3 (10 Punkte)
Betrachten Sie folgendes Programm:
class
Person{
public
void Person (StringName) { nachname =
Name };
public
void GetName()
{
return nachname;
}
String
nachname, String vorname;
public
void static main(String args[]) {
System.out.println(”Person: ”)
Person EineP;
EineP = new Person(”Mustermann”);
String x = EineP . GetName();System.out.println(x);
}};
a Markieren und verbessern Sie die Fehler im vorgegebenen Quellcode, so daß das Programm übersetzt und ausgeführt werden kann.
b In welchen Fällen wird gegen die Richtlinien und Konventionen für Bezeichner verstoßen? Verbessern Sie das Programm an den entsprechenden Stellen. Schreiben Sie dazu das Programm nocheinmal auf und formatieren Sie den Quellcode nach den in der Vorlesung vorgestellten Richtlinien.
Aufgabe A3
Lösung:
a
public
class Person{
public
Person (String Name) { nachname = Name;}
public
String GetName()
{
return nachname;
}
String
nachname;
public
static void main(String args[]) {
System.out.println("Person: ");
Person EineP;
EineP = new Person("Mustermann");
String x = EineP . GetName();System.out.println(x);
}};
b
public class Person // Überall Einrückungen beachten
{
private String Nachname; // Attribute zuerst aufführen und groß
// Attribute als private oder protected
// deklarieren
public Person(String Name) // Keine Leerzeichen zwischen
// Operationsnamen und und Klammern
{
Nachname = Name; // Attribute groß beginnen
}
public String getName() // Operationsnamen klein beginnen
{
return Nachname;
}
public static void main(String args[])
{
System.out.println("Person: ");
Person einePerson; // Anonyme Objektnamen
einePerson = new Person("Mustermann"); // beginnen mit ‚ein‘
String MerkeText = einePerson.getName();// Keine Leerzeichen
System.out.println(MerkeText); //bei der Punktnotation
} //Problemnahe Bezeichnernamen
};
Aufgabe A4 (5 Punkte)
Betrachten Sie folgendes Programm:
class A
{
int x = 5;
int berechne (int Zahl)
{
int Zahl1;
Zahl1 = Zahl + x;
{
int Zahl2;
Zahl2 = Zahl1 * 10;
Zahl2 = berechne2(Zahl2);
}
return Zahl2;
}
int berechne2(int Zahl)
{
return Zahl * Zahl;
}
}
In einer anderen Klasse findet man den Aufruf
Ergebnis = einA.berechne(10);
Welche Ausgabe erhalten Sie?
Begründen Sie Ihre Antwort!
Aufgabe A4
Lösung: Der Compiler meldet den Fehler: Error:
Undefined variable: Zahl2 in der Zeile return Zahl2.
Daher kann kein Lauf durchgeführt werden. Die Ursache liegt
darin, daß der Gültigkeitsbereich von Zahl2
auf den lokalen Block beschränkt ist.
Teil 3: Konstruktive Aufgaben
Aufgabe K1 (10 Punkte)
Schreiben Sie ein Java-Applet, das in einem Eingabefeld (textfield) einen Text einliest und auf Knopfdruck den Text in einem Ausgabefeld (textarea) ausgibt.
Lösung:
import
java.awt.*;
import
java.applet.*;
import
java.awt.event.*;
public
class Applet1 extends Applet
{
//Attribute
//{{DECLARE_CONTROLS
TextField einEingabefeld;
Button einDruckknopf;
TextArea einAusgabefeld;
//}}
//Operationen
public void init()
{
//{{INIT_CONTROLS
setLayout(null);
setSize(426,266);
einEingabefeld = new TextField();
einEingabefeld.setBounds(60,24,182,38);
add(einEingabefeld);
einDruckknopf = new Button();
einDruckknopf.setLabel("Kopiere");
einDruckknopf.setBounds(276,24,120,42);
//einDruckknopf.setBackground(new Color(12632256));
add(einDruckknopf);
einAusgabefeld = new TextArea();
einAusgabefeld.setBounds(60,108,181,79);
add(einAusgabefeld);
//}}
//{{REGISTER_LISTENERS
SymAction lSymAction = new SymAction();
einDruckknopf.addActionListener(lSymAction);
//}}
}
//Innere Klasse
class SymAction implements
ActionListener
{
public void
actionPerformed(ActionEvent event)
{
Object object =
event.getSource();
if (object == einDruckknopf)
einDruckknopf_ActionPerformed(event);
}
}
void
einDruckknopf_ActionPerformed(ActionEvent event)
{
//{{CONNECTION
// Append string in TextArea... Get
the contents of the TextField
einAusgabefeld.append(einEingabefeld.getText());
//}}
}
}
Aufgabe K2 (10 Punkte)
Betrachten sie folgende Aufrufe:
D.setA("Hallo");
....
einD.setB("Tschüss");
Schreiben Sie eine zugehörige Klasse, so daß diese Aufrufe gültig sind.
Ein mögliche Lösung sieht folgendermaßen aus:
class
D
{
//Objektattribut
String objektText;
//Klassenattribut
static String Text;
//Klassenoperation
public static void setA(String einText)
{
Text = einText; //this ist bei Klassenattributen nicht erlaubt
System.out.println("Klassentext: " + Text + "\n");
}
public void setB(String objektText)
{
this.objektText = objektText;
System.out.println("Objekttext:
" + objektText);
}
}
class
Haupt
{
public static void main(String[] args)
{
D.setA("Hallo");
D einD = new D();
einD.setB("Tschüss");
}
}
Aufgabe K3 (15 Punkte)
Ein Programm zur Bearbeitung von Bestellungen soll getestet werden. Das Programm erfaßt
die Bestellnummer, die Stückzahl, den Preis, die Farbe und die Angabe, ob die Bestellung per Nachnahme geliefert werden soll.
Die Bestellnummer ist eine 5-stellige Zahl.
Die Stückzahl ist auf 10.000 begrenzt und muß mindestens gleich 1 sein.
Der Preis liegt zwischen 0,01 DM und 10000,00 DM.
Gültige Farben sind rot, grün, blau, gelb, orange, weiß und schwarz.
Lieferung per Nachnahme kann als gültige Werte ja und nein annehmen.
a Stellen Sie alle Äquivalenzklassen auf.
b Bilden Sie Testfälle für die Grenzwertanalyse.
Aufgabe K3
Lösung
a Äquivalenzklassen
|
gültig |
ungültig |
Bestellnummer |
1: 0<=x<=99999 |
2: x<0 |
|
|
3: x>=100000 |
Stückzahl |
4: 1<=x<=10000 |
5: x<1 |
|
|
6: x>10000 |
Preis |
7: 0,01<=x<=10000 |
8: x<0,01 |
|
|
9: x>10000 |
Farbe |
10: rot |
17: lila |
|
11: grün |
|
|
12: blau |
|
|
13: gelb |
|
|
14: orange |
|
|
15: weiß |
|
|
16: schwarz |
|
per Nachnahme |
18: ja |
20: vielleicht |
|
19: nein |
|
b Testfälle für die Grenzwertanalyse
gültige Testfälle
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Bestellnummer |
0 (1u) |
99999 (1o) |
1000 |
1000 |
1000 |
1000 |
1000 |
Stückzahl |
1 (4u) |
10000 (4o) |
1000 |
1000 |
1000 |
1000 |
1000 |
Preis |
0,01 (7u) |
10000 (7o) |
1000 |
1000 |
1000 |
1000 |
1000 |
Farbe |
rot (10) |
grün (11) |
blau (12) |
gelb (13) |
orange (14) |
weiß (15) |
schwarz (16) |
per Nachnahme |
ja (18) |
nein (19) |
ja |
ja |
ja |
ja |
ja |
ungültige Testfälle
|
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Bestellnummer |
-1 (2o) |
100000 (3u) |
1000 |
1000 |
1000 |
1000 |
1000 |
1000 |
Stückzahl |
1000 |
1000 |
0 (5o) |
10001 (6u) |
1000 |
1000 |
1000 |
1000 |
Preis |
1000 |
1000 |
1000 |
1000 |
0 (8o) |
10000,01 (9u) |
1000 |
1000 |
Farbe |
rot |
rot |
rot |
rot |
rot |
rot |
lila (17) |
rot |
per Nachnahme |
ja |
ja |
ja |
ja |
ja |
ja |
ja |
vielleicht (20) |
Aufgabe K4 (15 Punkte)
a Programmieren Sie eine Klasse Matrix in Java. Die Klasse soll folgende Anforderungen erfüllen:
1 Bei der Erzeugung soll festgelegt werden, wieviel Zahlen und wieviel Spalten die Matrix enthält.
2 Bei den Matrixelementen handelt es sich um Fließkommazahlen einfacher Genauigkeit. Sie sollen mit 0 vorbelegt sein.
3 Es soll eine Operation zum lesenden Zugriff auf ein Matrixelement implementiert werden.
4 Es soll eine Operation zum schreibenden Zugriff auf ein Matrixelement realisiert werden.
5 Es soll eine Operation addiere(Matrix m) implementiert werden. Rückgabewert ist eine neue Matrix, die aus der Addition der im Operationsparameter übergebenen Matrix mit der Matrix, auf welche die Operation angewandt wird, ensteht.
Matrix a, b, c
...
c = a.addiere(b); // c = a
+ b, Ergebnis in c, a und b bleiben unveraendert
Hinweis: Verwenden Sie für die Matrixelemente ein zweidimensionales Feld. Initialisieren Sie das Feld bei der Erzeugung in der gewünschten Größe.
b Erstellen Sie eine Java-Applikation, die zwei 2x2 Matrixen erzeugt und mit folgenden Werten füllt:
Führen Sie die Addition a + b durch, und geben Sie das Ergebnis in folgender Form auf dem Standardausgabestrom aus:
Ergebnis:
1.0 3.0
4.0 2.0
c Erstellen Sie ein Java-Applet, das ebenfalls die oben aufgeführte Addition a + b durchführt.
Das Ergebnis soll in Form eines Gitters aus einem Druckknopf für jedes Matrixelement dargestellt werden!
Aufgabe K5
Lösung:
a b
public
class Matrix
{
// Attribute
float Elemente[][];
int ZeilenZahl, SpaltenZahl;
// Konstruktor
public Matrix(int Zeilen, int Spalten)
{
Elemente = new float[Zeilen][Spalten];
ZeilenZahl = Zeilen;
SpaltenZahl = Spalten;
}
//
// Zugriffsoperationen
//
public int getSpaltenZahl()
{
return SpaltenZahl;
}
public int getZeilenZahl()
{
return ZeilenZahl;
}
public float getElement(int zeile, int spalte)
{
return Elemente[zeile][spalte];
}
public void setElement(int zeile, int spalte, float wert)
{
Elemente[zeile][spalte] = wert;
}
//
// Rueckgabewert = diese Matrix + eineMatrix
//
public Matrix addiere(Matrix eineMatrix)
{
// Voraussetzung: Groesse dieser Matrix = Groesse von >eineMatrix<
if( (eineMatrix.getZeilenZahl() == ZeilenZahl)
&& (eineMatrix.getSpaltenZahl() == SpaltenZahl) )
{
Matrix ergebnis = new Matrix(ZeilenZahl, SpaltenZahl);
for(int y=0; y < ZeilenZahl; y++)
{
for(int x=0; x < SpaltenZahl; x++)
{
ergebnis.setElement(y,x, eineMatrix.getElement(y,x) + getElement(y,x));
}
}
return ergebnis; // Ergebnismatrix zurueckgeben
}
else
return null; // Voraussetzung nicht erfuellt
}
//
// Hauptprogramm einer Java-Anwendung
//
public static void main(String args[])
{
Matrix a = new Matrix(2,2);
a.setElement(0,0,1);
a.setElement(1,1,2);
Matrix b = new Matrix(2,2);
b.setElement(0,1,3);
b.setElement(1,0,4);
Matrix c = a.addiere(b);
System.out.println("Ergebnis:");
System.out.println(c.getElement(0,0) + " " + c.getElement(0,1));
System.out.println(c.getElement(1,0) + " " + c.getElement(1,1));
}
}
c
import java.applet.*;
import java.awt.*;
public class MatrixGUI extends Applet
{
public void init()
{
//
// wie bei der Anwendung
//
Matrix a = new Matrix(2,2);
a.setElement(0,0,1);
a.setElement(1,1,2);
Matrix b = new Matrix(2,2);
b.setElement(0,1,3);
b.setElement(1,0,4);
Matrix c = a.addiere(b);
//
// Grid-Layout setzen
//
setLayout(new GridLayout(c.getZeilenZahl(),c.getZeilenZahl()));
//
// Fuer jedes Matrixelement einen Druckknopf erzeugen
//
for(int y=0; y < c.ZeilenZahl; y++)
{
for(int x=0; x < c.SpaltenZahl;
x++)
{
Float il = new
Float(c.getElement(y,x));
add(new
Button(il.toString()));
}
}
}
}