FACHHOCHSCHULE RAVENSBURG -WEINGARTEN PROF. DR.-ING. S. KELLER ANGEWANDTE INFORMATIK PROGRAMMIEREN 1/2 AUFGABEN ZUR KLAUSURVORBEREITUNG AUFGABE 1 Gegeben ist die Funktion ausgabe(). Die Funktion gibt die ersten n Zeichen einer mit '\0' abgeschlossenen Zeichenfolge aus. Ist n größer als die Anzahl der Zeichen in der Zeichenfolge, so gibt die Funktion die komplette Zeichenfolge ( bis zum '\0'Zeichen ) aus. Die Funktion erwartet als Parameter die Zeichenfolge ( Import-Parameter: text ) und die Anzahl der auszugebenden Zeichen ( Import-Parameter: n ). int ausgabe(char *text, unsigned short n) { unsigned short zaehler=n; if ( n>0) while ( text || n ) { putchar(*text++); n--; } printf("\n"); return zaehler-n; } a) Die Funktion arbeitet fehlerhaft. Wo liegt der/die Fehler. Korrigieren Sie die Funktion. b) Definieren Sie ein Makro mit dem Namen AUSGABE. Das Makro soll analog der Funktion ausgabe() die ersten n Zeichen einer Zeichenfolge bzw. die komplette Zeichenfolge ausgeben. Das Makro AUSGABE( text, n ) hat kein Ergebnis. Das Makro entspricht daher der Funktion ausgabe(), jedoch realisiert als void Funktion. Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Programmieren 1/2 Prof. Dr.-Ing. Silvia Keller AUFGABE 2 Gegeben ist die Funktion hobbit(). Herr K., Programmierer dieser Funktion, liebt es möglichst kompakte Programme zu schreiben und hat daher möglichst viele Anweisungen in die for-Schleife gepakt. Dieser Programmierstil gefällt seinem Vorgesetzten Herr M, der vorwiegend in Pascal programmiert nicht. In Pascal werden for-Schleifen ausschließlich als Zählschleifen verwendet. Herr M. weist daher Herr K. an die for-Schleife durch eine äquivalente while-Schleife zu ersetzen. Wie sieht die Funktion hobbit() nach der Änderung aus ? void hobbit( int delta ) { int a,b; for (a=getchar(), b=0; a != EOL; b++, putchar(a), a=getchar() ) if ( b%delta == 0 ) printf("\n"); } AUFGABE 3 Gegeben ist die folgende korrekte Funktion bs(): int *bs( int liste[], int n, int x ) { int anf=0,end=n-1,m,*ptrm; while (1) { m=(anf+end)/2; ptrm=&liste[m]; if (x > *ptrm) anf = m+1; else end = m-1; if ( anf > end ) return (int *) 0; if (*ptrm == x) return ptrm; } } Schreiben Sie die Funktion bs() so um, daß anstatt der Endlosschleife eine Schleife mit echter Wiederholungsbedingung verwendet wird. Wählen Sie den Bedingungsausdruck so, das die Schleife nur aufgrund dieser Bedingung(en) verlassen wird und nicht durch break oder return im Rumpf der Schleife. Entscheiden sie sich für ein Schleifen-Konstrukt while oder do...while , so daß die gegebene Schleife am einfachsten realisiert werden kann. Begründen Sie Ihre Entscheidung. -2- Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Prof. Dr.-Ing. Silvia Keller Programmieren 1/2 AUFGABE 4 Gegeben sind die beiden Funktionen FF() und Clock(). unsigned char FF( unsigned int j, unsigned int k) { static unsigned char q=0; if ( !j && !k ) ; if (!j && k ) q=1; if ( j && !k ) q=0; if ( j && k ) q=!q; return q; } unsigned int clock( unsigned char tick) { static unsigned int count=0; return count = count + tick; } Diese beiden Funktionen werden in folgendem Programm verwendet: #include <stdio.h> #define N 4 unsigned int clock(unsigned char); unsigned char FF( unsigned int , unsigned int ); int main() { unsigned int count=0; while ( count < N ) count = clock(FF(1,1)); printf("count= %iu\n",count); return 0; } Wie oft wird die while-Schleife in main() durchlaufen ? Begründen Sie Ihre Antwort. -3- Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Programmieren 1/2 Prof. Dr.-Ing. Silvia Keller AUFGABE 5 In ANSI-C gibt es den dreistelligen Operator a1 ? a2 : a3 ist identisch mit : ? ( bedingter Ausdruck ) mit folgender Bedeutung: if (a1== TRUE) a2; else a3; Der Wert des Ausdruckes ( a1 ? a2 : a3 ) ist entweder a2 oder a3. Gegeben ist folgendes Programm: #include <stdio.h> main() { int nx,nzahl, nmax=100 ; for ( nx=2,nzahl=2; nzahl<=nmax; nx=nx*nx<=nzahl ? nzahl % nx ? ++nx : 2 + ! ++ nzahl : 2 + ! printf ( "%8i",nzahl++)); return 0; } Analysieren Sie die Funktion main(). Welche Ausgabe erzeugt das Programm ? Können Sie erkennen welchen Algorithmus das Programm realisiert ? -4- Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Programmieren 1/2 Prof. Dr.-Ing. Silvia Keller AUFGABE 6 Gegeben sind folgende Definitionen: static int vektor[]={10,15,4,25}; int dasist,*stelle; struct knoten { char titel[6]; int index; } goethe = { "Faust",5}; struct knoten *dichter; char *text,**pfeil; Welche der folgenden Ausdrücke / Anweisungsfolgen sind korrekt, welche sind falsch ? Geben Sie für alle korrekten Ausdrücke /Anweisungsfolgen das Ergebnis entweder als Wert oder in Form einer Grafik an, falls das Ergebnis ein Zeiger ist. Die Grafik beschreibt die Datenstruktur auf die der Zeiger verweist. 1. dichter = goethe; 2. text = (&goethe)->titel; 3. text=stelle; 4. text=goethe.titel + 4; 5. dasist=&vektor[2]-vektor; 6. stelle = vektor+3; dasist=vektor[*stelle++]; 7. pfeil= &text; *pfeil="Hesse"; (&goethe)->titel[0]=**pfeil; -5- Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Programmieren 1/2 Prof. Dr.-Ing. Silvia Keller AUFGABE 7 Gegeben sind folgende Definitionen und Ausdrücke static int matrix[2][3] = { { -3, 14, 5 }, {1, -10, 8 } }; static int *liste[] = { matrix[0], matrix[1] }; int *p = liste[1]; Welche Werte ergeben die folgenden Ausdrücke, unter der Annahme das jeder Ausdruck direkt nach obiger Definition ausgeführt wird. Erklären Sie, wie Sie zu Ihrem Ergebnis kamen d.h. welche Wirkung der Ausdruck bezüglich obiger Datenstruktur hat. Ausdruck Ergebniswert Erklärung zur Wirkung des Ausdruckes *liste[1]; *(*(matrix+1)+1 )); *(matrix[0]+2); *(++p); *(--p-2); -6- Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Programmieren 1/2 Prof. Dr.-Ing. Silvia Keller AUFGABE 8 Das folgende Bild beschreibt eine Datenstruktur, in der Prüfungen, Anzahl der Teilnehmer an der Prüfung, sowie die Namen der Prüfungsteilnehmer gespeichert werden. Tabelle "Prüfung" Anzahl der Verweis auf Teilnehme Teilnehmerlist Bezeichnun r e g Prog. 3 3 ----------- Multimedia 2 Namen Teilnehmerliste -------> ------> "sowieso" | ------> "mitmacher" | ------> "witzkopf" ------> "nachbrenner" ------> "glasklar" | |----------- -------> Eine Prüfung wird in der Tabelle "Prüfung"durch eine Zeile (Datensatz) repräsentiert. Zu jeder Prüfung wird ein Text, der die Prüfung bezeichnet und die Anzahl der Teilnehmer abgelegt. Für jeder Prüfung existiert zusätzlich eine Teilnehmerliste, in der für jeden Teilnehmer ein Eintrag abgelegt ist, der auf den Namen des Prüfungsteilnehmers verweist. Über einen Zeiger, der auf die Teilnehmerliste verweist wird die Verbindung Prüfung/Prüfungsteilnehmer geschaffen. Gegeben sind folgende Typdeklarationen: typedef char STRING[16]; typedef char *TEXT; typedef TEXT *TEILNEHMERLISTE; a) Definieren Sie einen Datentyp PRUEFUNG, der einen Datensatz (Zeile) der Tabelle "Prüfung" im Bild repräsentiert. Verwenden Sie dazu die vordefinierten Datentypen. b) Deklarieren Sie eine Variable pruefungsliste, die oben angebene Tabelle bestehend aus zwei Datensätzen aufnimmt, sowie zwei Variablen liste1 und listet2 zur Aufnahme der Teilnehmerlisten. Alle Variablen sollen modulglobal vereinbart werden. -7- Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Programmieren 1/2 Prof. Dr.-Ing. Silvia Keller AUFGABE 9 Gegeben sind folgende Datentypen und Funktionen #define NIL 0 typedef struct kn { kn *erster; kn *zweiter; } STRUKTUR; typedef STRUKTUR *ZEIGER; STRUKTUR *gebilde(int groesse) { ZEIGER top; top=(ZEIGER) malloc ( sizeof(STRUKTUR) ); wachstum(top,groesse); return top; } void wachstum(ZEIGER gabel, int tiefe) { ZEIGER knospe; if (tiefe==0) { gabel->erster=NIL; gabel->zweiter=NIL; } else { knospe= (ZEIGER) malloc( sizeof(STRUKTUR) ); gabel->erster=knospe; wachstum(knospe,tiefe-1); knospe= (ZEIGER) malloc( sizeof(STRUKTUR) ); gabel->zweiter=knospe; wachstum(knospe,tiefe-1); } } Stellen sie das Gebilde aus Zeigern und Variablen grafisch dar, das durch die Funktion gebilde()erzeugt wird, wenn die Funktion mit aktuellem Parameter "2" ( d.h. gebilde(2) ) aufgerufen wird. -8- Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Programmieren 1/2 Prof. Dr.-Ing. Silvia Keller AUFGABE 10 Welche Ausgabe produziert das folgende C-Programm. Da sie die Ausgaben nicht auf einer Seite dokumentieren können sollten Sie die Aktionen des Programms und dessen Ausgabe durch einen kurzen Text beschreiben. #include <stdio.h> #define ANZAHL 2 int Welcher(int); int Was(int); main() { int i,k,tag=0; int (*JobListe[ANZAHL])()={Welcher,Was}; for ( i=1;i<=365;i++) for(k=0;k<ANZAHL;k++) tag=(*JobListe[k])(tag); return 0; } int Welcher(int tag ) { tag=(tag+1)%7; return tag; } int Was(int tag) { switch (tag) { case 0: printf("sonntag ist Ruehetag\n" ); break; case 1: printf("Montag ist leichter Arbeitstag\n"); break; case 2: printf("Dienstag ist normaler Arbeitstag\n");break; case 3: printf("Mittwoch ist langer Arbeitstag\n"); case 4: printf("Donnerstag ist kurzer Arbeitstag\n") break; case 5: printf("Freitag ist Freizeit\n"); break; case 6: printf("Samstag ist Hobbytag\n"); break; break; } return tag; } -9- Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Programmieren 1/2 Prof. Dr.-Ing. Silvia Keller AUFGABE 11 In einem größeren Softwareprojekt sollen Sie ein Modul implementieren, welches drei Funktionen exportiert. Für den Import der Funktionen in anderen Modulen sollen die Prototypen in einer Headerdatei zu Verfügung gestellt werden. Zur Realisierung der Funktionen wurde Ihnen eine logische Schnittstelle vorgegeben. In einer globalen Headerdatei typen.h sind alle projektspezifischen Datentypen deklariert. Schnittstellenbeschreibung: Funktionsname: FKT_E Importparameter: Struktur vom Typ S Exportparameter: Liste von Zeigern auf Funktionen, die als Ergebnis int-Werte zurückliefern Ergebnis: Zeiger auf ein zweidimensionales array mit Komponenten vom Typ float Funktionsname: FKT_Z Importparameter: Zeiger auf eine Funktion, die als Ergbnis ein unsigned long zurückliefert Exportparameter: Liste von int-Werten Ergebnis: Zeiger auf eine Strukur vom Typ S Funktionsname: FKT_D Importparameter: Zeiger auf einen string Exportparameter: Struktur vom Typ S Ergebnis: Zeiger auf eine Liste von Zeigern, die auf int-Werte verweisen Geben Sie für diese drei Funktionen die Prototypen in der Headerdatei an. Bitte beachten Sie , das Sie eine logische Beschreibung der Schnittstelle bekommen haben. Für die Realisierung von Exportparametern müssen Sie sich daher eine konkrete Realisierung ausdenken. - 10 - Hochschule für Technik und Sozialwesen, Fachhochschule Ravensburg-W eingarten Angewandte Informatik Programmieren 1/2 Prof. Dr.-Ing. Silvia Keller AUFGABE 12 Das Programm QUATSCH besteht aus vier Programmodulen QUATSCH, SCHERZ, WITZ und RIPU: Modul QUATSCH Modul SCHERZ Import-Objekte: Import-Objekte : Export-Objekte Export-Objekte : int main(void) int DoWi(int Do) { int a,b=5; { b=DoWi( InPu(b) ); witz=OutPu()%(Do+3); printf("%i %i",a,b); return witz; return 0; } } Modul WITZ Modul RIPU Import-Objekte : Import-Objekte : Export-Objekte : Export-Objekte : static char Pu[20]; int witz=0; static int wo=0; int InPu(int was) { if ( wo==19 ) wo=0; Pu[wo++]= (char) was; return was; } int OutPu(void) { if ( wo==0 ) return -1; return (int) Pu[--wo]; } a) Geben Sie im obigen Bild in den Modulköpfen zu jedem Modul Import- und Exportobjekte an. Ergänzen Sie im obigen Bild die Module QUATSCH und SCHERZ mit den Prototypen der importierten Objekte. b) Beschreiben Sie die Modulhierarchie des Programms durch einen Modulhierarchiegraphen ( beachten Sie den Modultyp ) c) Geben Sie zu obigem Programm den Inhalt des MAKEFILES an, so daß bei Änderung eines Quellmodule nur der betroffene Pfad neu erzeugt wird. Erläutern Sie Ihre Regeln. - 11 -