2. Übung

Werbung
SS 2004
Technische Universität Darmstadt
FB Mathematik, AG 7, Diskrete Optimierung
Prof. Dr. Alexander Martin
Daniel Junglas
Lars Schewe
2. Übung
Computerorientierte Mathematik
Abgabe der Hausübungen am 10. Mai vor der Übung
Praxis
P1.
Quoting
Besetzen Sie die Umgebungsvariable INHALT mit dem Text ,,Inhalt des Verzeichnisses: ” und führen
Sie nacheinander die folgenden Befehle aus:
fb04305:~ > echo $INHALT *
fb04305:~ > echo "$INHALT *"
fb04305:~ > echo ’$INHALT *’
Was tun diese Befehle und was ist der Unterschied zwischen einfachen, doppelten bzw. gar keinen
Anführungszeichen?
P2.
ASCII-Tabelle
Schreiben Sie ein Programm, das eine Tabelle ausgibt, in der alle Zahlen von 32 bis 255 (einschließlich) zusammen mit dem jeweiligen Buchstaben der ASCII-Tabelle dargestellt sind.
Die ausgegebene Tabelle soll acht Spalten haben.
P3.
Eingabe von Zahlen
Mit Hilfe der Funktion scanf() (siehe auch man scanf) kann wie folgt eine Zahl von der Tastatur
eingelesen werden:
#include <stdio.h>
...
int zahl;
...
printf("Eine Zahl, bitte:");
scanf("%d", &zahl);
(was ,,&zahl” genau bedeutet ist dabei zunächst nicht wichtig). Nach der Ausführung dieses Codefragments ist die eingegebene Zahl in der Variablen zahl gespeichert.
Schreiben Sie ein Programm, das eine Zahl einliest und für diese Zahl ausgibt, ob sie positiv oder
negativ bzw. ob sie gerade oder ungerade ist. Dieser Schritt soll so lange wiederholt werden, bis 0
eingegeben wird.
Hinweis: Um zu testen, ob eine Zahl gerade oder ungerade ist, kann man sich einen der beiden
folgenden Operatoren zunutze machen (probieren Sie ruhig einmal beide aus):
% Der %-Operator liefert den Rest einer ganzzahligen Division, d.h. 4 % 3 liefert 1.
/ Dies ist der Divisionsoperator. Sind beide Argumente des Operators ganzzahlig, dann wird ganzzahlige Division durchgeführt. Dies entspricht einer Division mit Rest, bei der der Rest ignoriert
wird. Demnach liefert 4 / 3 den Wert 1.
P4.
Austausch von Ziffern
Schreiben Sie ein Programm, das vom Benutzer zunächst zwei ganze Zahlen a und b verlangt. Danach soll noch eine weitere Zahl c eingelesen werden. Das Programm vertauscht dann die (dezimalen)
Ziffern an der c-ten Stelle von a und b und gibt das Ergebnis auf dem Bildschirm aus.
P5.
Prä- und Postinkrement
Betrachten Sie das folgende Programm:
#include <stdio.h>
int main (void)
{
int x = 5;
printf("%d, %d\n", ++x, x--);
return 0;
}
Was für eine Ausgabe erwarten Sie? Was wird tatsächlich ausgegeben?
Hinweis: Aufgrund dieses Ergebnisses, sollte man möglichst nicht mehrere Prä- und PostinkrementOperatoren in einem Statement kombinieren, erst recht nicht für ein und dieselbe Variable.
Theorie
T1. Nochmal 2-Komplement
Betrachten Sie den folgenden 32 Bit langen Auszug aus dem Hauptspeicher:
11000100011010000111001001100101.
Welche Zahlen/Buchstaben werden definiert, wenn man ihn als
(a) vier Buchstaben vom Typ unsigned char,
(b) eine Zahl vom Typ unsigned long,
(c) eine Zahl vom Typ long,
(d) zwei Zahlen vom Typ unsigned short oder
(e) zwei Zahlen vom Typ short
betrachtet? (Alle Zahlen sollen als Zahlen im 2-Komplement betrachtet werden.)
T2. Bitoperationen
Nehmen den arithmetischen Operatoren ,,+”, ,,-” usw. gibt es auch Operatoren, mit denen man Zahlen/Variablen bitweise verknüpfen kann. Bei diesen Operationen werden die beteiligten Variablen
Bit für Bit miteinander verknüpft und das Ergebnis wird ebenfalls Bit für Bit in der entsprechenden
Variablen gespeichert.
Die Operatoren zur Bitverknüpfung sind bitweises Und (&-Operator), bitweises Oder (|-Operator),
bitweises Exklusiv-Oder (^-Operator) und bitweise Negation (~-Operator):
&
0
1
0
0
0
1
0
1
|
0
1
0
0
1
1
1
1
^
0
1
0
0
1
1
1
0
~
0
0
1
1
0
Betrachten wir uns beispielsweise die Anweisung
unsigned short a = 4 | 3;
Die binäre Darstellung von 4 im 2-Komplement ist 100 und die von 3 ist 11 (führende Nullen sind
hier weggelassen, sind aber trotzdem wichtig!). Nun wird Bit für Bit die Oder-Operation ausgeführt:
Ist ein Bit in der binären Darstellung von 3 oder 4 gesetzt, dann wird das entsprechende Bit auch
im Ergebnis gesetzt. Ist ein Bit in keiner der beiden Binärdarstellungen gesetzt, dann wird das Bit
auch im Ergebnis nicht gesetzt.
Die Anweisung oben sorgt also dafür, dass in a das Bitmuster 111 gespeichert wird.
(a) Welches Bitmuster ist in a nach den folgenden Anweisungen gespeichert? (a soll vom Typ
unsigned short sein)
i.
ii.
iii.
iv.
a
a
a
a
=
=
=
=
5 | 3
5 & 3
5 ^ 3
~5
(b) Wie kann man testen ob ein bestimmtes Bit (z.B. bit5) gesetzt ist oder nicht?
(c) Wie kann man testen, ob eine Variable gerade/ungerade ist?
(d) Wie kann man bit5 in einer Variablen löschen/setzen?
(e) Möchte man die Werte zweier Variablen x und y vertauschen, dann verfährt man normalerweise
so
{
int z = x;
x = y;
y = z;
}
Man kann aber auch ohne z auskommen:
Wie kann man die Werte zweier Variablen nur mit dem ^-Operator vertauschen, ohne eine
zusätzliche Variable zu verwenden? (Dazu sind nicht mehr als drei Anweisungen nötig) Was
passiert, wenn man eine Variable auf diese Art mit sich selbst vertauscht?
T3. Überlauf
Wieso führt das folgende Code-Fragment zu einer Endlosschleife?
short i;
unsigned short j = 40000;
for (i = 0; i < j; i++) {
printf("%d\n", i);
}
T4.
Schleifen
Grundsätzlich kann man jede for-Schleife auch als while-Schleife schreiben und ungekehrt.
(a) Was berechnet das folgende Code-Fragment (x und n sind vom Typ int)?
x = -1;
while (n > 0 ) {
n = n / 3;
x++;
}
Schreiben Sie die while-Schleife als eine for-Schleife.
(b) Schreiben Sie die Schleife
for (i = 0; i < 10; i++) printf("%d, i);
als while-Schleife.
Herunterladen