Praktikum 11: Bit-Operationen, 2D-Arrays

Werbung
INE1 – Informatik für Ingenieure 1
Praktikum 11:
Bit-Operationen, 2D-Arrays
Aufgabe 1: Bit-Operationen
In den Unterlagen finden Sie eine Funktion, die eine Zahl Binär auf die Konsole ausgibt. Entwikkeln Sie eine Funktion byte2binary mit folgendem Prototyp (der Prototyp wird oft auch als Signatur bezeichnet):
void byte2binary (int num, char * result);
Die Funktion bekommt eine Zahl, deren niederwertigste acht Bit sie in Binärdarstellung umwandelt. Die Binärdarstellung wird in einen Zeichenpuffer (*result) geschrieben, der als zweites Argument übergeben wird (ähnlich wie bei scanf erfolgt die Rückgabe hier also nicht über den return-Wert der Funktion, sondern über einen zuvor bereitgestellten Speicherbereich).
Hinweise
Die Zeile
*result = (mask & num) ? '1' : '0';
ist auf den ersten Blick etwas unübersichtlich, da sie den ternären Operator "?:" verwendet. Die
Zeile könnte man durch eine einfache Auswahlanweisung ersetzen:
if (mask & num) {
*result = '1';
} else {
*result = '0';
}
Die Anweisung mask >>= 1 könnte man schreiben als mask = mask >> 1.
Aufgaben
•
Machen Sie sich klar, wie byte2binary funktioniert. Testen Sie das Programm mit ein paar
Eingabewerten.
•
Erweitern Sie das Hauptprogramm so, dass zwei int-Zahlen m und n eingelesen werden.
Diese sollen dann wieder im Binärformat ausgegeben werden und ausserdem die Ergebnisse
der Operationen a & b, a | b, a >> 1, b << 2 und ~a.
Gerrit Burkert, Karl Rege 26.11.15
1
INE1 – Informatik für Ingenieure 1
Aufgabe2: Parity
Wenn auf einer Kommunikationsleitung Bytes mit 7-Bit-ASCII-Code übertragen werden, ist es
üblich, die einzelnen Bytes mit einem sogenannten achten Paritäts- Bit zu versehen; damit soll
die Übertragungssicherheit verbessert werden.
Das Parity-Bit “sagt“, ob die Anzahl der Bits (in einem Byte), die auf Eins gesetzt sind, gerade
oder ungerade ist.
Der Sender zählt somit die “Einer“-Bits im zu übertragenden Byte und ergänzt das Byte mit dem
berechneten Paritäts- Bit so, dass die Gesamtanzahl der Einser gerade oder ungerade ist.
Der Empfänger berechnet auf die gleiche Weise die Parität des empfangen Bytes und vergleicht
diesen mit dem übertragenen Paritäts-Bit.
Aufgabe
•
•
•
•
•
•
Bei der seriellen Übertragung werden manchmal nur 7 Bits für Nutzdaten (Bits 0..6) und ein
Parity-Bit (Bit 7) verwendet (vorderstes Bit = Parity)
Lesen Sie ein Byte als Dezimalzahl (0..127) ein: verwenden Sie den Datentyp unsigned char
(=unsigned Integer der Grösse eines Bytes).
Hinweis: Sie können mit scanf("%d",x) nur in eine Variable x von Typ Integer einlesen.
Mit scanf eine Zahl in eine Integer-Variable y einlesen und anschliessend einer char var
input zuweisen: input = (unsigned char) x;
Berechnung der Parität: gerade Anzahl Einser in Bits 0..6 -> Parität-Bit =0, ungerade Anzahl > Parität-Bit =1.
Schreiben Sie dafür eine Funktion addParity(unsigned char* input).Diese Parität
wird in der obigen Funktion als vorderstes Bit des übergebenen Byte gesetzt.
Schreiben Sie eine weitere Funktion bool checkParity(unsigned char input) das
die Parität überprüft
Testen Sie Ihre beiden Funktionen. Sie können dafür auch die Funktion aus der ersten Aufgabe verwenden.
Beispiel (even parity):
7 (Parity)
6
5
4
3
2
1
0
1
0
0
0
0
1
1
1
Gerrit Burkert, Karl Rege 26.11.15
2
INE1 – Informatik für Ingenieure 1
Aufgabe 3: Spaltensumme im Array
Für ein zweidimensionales Array soll in jeder Spalte die Summe berechnet werden. Das Ergebnis ist also ein eindimensionales Array. Beispiel:
1
2
3
5
6
4
sum7
8
9
10
11
15
18
21
24
12
In der ersten Variante des Programms wird das zweidimensionale Array an die Funktion summeSpalten übergeben. Dafür nehmen wir an, dass die zweite Dimension („Breite“ des zweidimensionalen Arrays) fest auf 4 gesetzt ist. Das Ergebnis soll ein ein Array erg geschrieben werden, das bereits in der passenden Grösse vorbereitet ist und ebenfalls als Parameter übergeben
wird.
Das Hauptprogramm sieht dann folgendermassen aus:
int main (void) {
int a[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12
}};
int erg[4];
summeSpalten(erg, a, 3);
druckeIntArray(erg, 4);
return 0;
}
Implementieren Sie die Funktion summeSpalten. Damit Sie nicht soviel Zeit verlieren, finden Sie
die Funktion druckeIntArray unten im Anhang zu dem Praktikum.
Dass die Funktion summeSpalten nur mit einer festen zweiten Dimension von 4 verwendet werden kann, ist unpraktisch. In der zweiten Variante summeSpalten2 soll das zweidimensionale
Array daher als eindimensionales Array übergeben werden. Nun müssen Sie auch die Zeilen und
Spalten als separate Parameter der Funktion übergeben. Der Prototyp der Funktion ist jetzt:
void summeSpalten2 (int *erg, int *a, int rows, int cols);
Wie muss die Funktion jetzt aufgerufen werden?
Das Ergebnis-Array haben wir bereits vor Aufruf der Funktion summeSpalten angelegt und als
Parameter übergeben. Könnten wir das Array auch in der Funktion anlegen mit
int erg[4]; und als return-Wert an das Hauptprogramm zurückgeben.
In der dritten Variante soll das Ergebnis-Array nun in der Funktion summe_spalten_3 selbst
angelegt werden, aber nicht auf dem Stack, sondern dynamisch auf dem Heap. Die Funktion gibt
dann einen Zeiger auf das Array zurück. Implementieren Sie auch diese Variante. Vergessen Sie
nicht, den dynamischen Speicher nach Benutzung wieder freizugeben. Der Funktionsprototyp ist
nun:
int * summeSpalten3 (int * a, int rows, int cols);
Gerrit Burkert, Karl Rege 26.11.15
3
INE1 – Informatik für Ingenieure 1
/**
* Ausgabe des int-Arrays
*/
void druckeIntArray (int zahlen[], int anz) {
int i;
printf("{ ");
if (anz>0) { printf("%d", zahlen[0]); }
for (i=1; i<anz; i+=1) {
printf(", %d", zahlen[i]);
}
printf(" }\n");
}
/**
* Hauptprogramm mit Testdaten
*/
int main (void) {
int i;
int a[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }};
int erg[4];
int * ergdyn;
int * b;
int * c;
b = a;
c = a;
//printf("a: %p\n", a);
//printf("c: %p\n", c);
//summe_spalten_1(erg, a, 3);
//drucke_int_array(erg, 4);
return 0;
}
Gerrit Burkert, Karl Rege 26.11.15
4
Herunterladen