Fragenkatalog Programmieren 1 Stand: Februar 2013 1. Was ist eine Entwicklungsumgebung: Eine Entwicklungsumgebung ist eine Software, Software – Projekte zu erstellen. Sie umfassen alle notwendigen Werkzeuge und Methoden, um Software planen, entwickeln und verwalten zu können. Entwicklungsumgebungen gibt es in verschiedenen Ausführungen: Speziell für eine Programmiersprache oder ein Betriebssystem Allgemein gehalten und an verschiedene Programmiersprachen anpassbar 1.1.Mindestausstattung einer Entwicklungsumgebung: Projektverwaltung Programmierumgebung (Editor) Übersetzer (Compiler) Testumgebung 2. Printf / Scanf: 2.1. Printf: Die Ausgabefunktion der Standardbibliothek unterstützt nur Textausgaben. Diese Funktion printf erwartet mindestens ein Argument oder eine Zeichenkette und gibt diese am Bildschirm aus. Grundsätzlich ist diese Funktion wie folgt aufgebaut: printf(„Hallo Welt!“); Es gibt für die unterschiedlichen Datentypen verschiedene Platzhalter: Datentyp Eingabeformat Platzhalter long dezimal oktal hexadezimal beliebig dezimal beliebige Gleitpunktnotation beliebige Gleitpunktnotation Einzelnes Zeichen String %ld %lo %lx %li %d %f %lf %c %s int float double char char* 1 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 2.2.Scanf: Die Eingabefunktion der Standardbibliothek ist ähnlich der Ausgabefunktion zu verwenden. Der Befehl scanf liest Werte von der Tastatur ein und schreibt sie in Variablen. Diese Funktion gibt entweder die Anzahl der gelesenen Werte zurück oder die Konstante EOF (end of file), wenn ein Fehler ausgetreten ist. Auch bei der scanf – Funktion sind Platzhalter notwendig, damit die Funktion weiß, welcher Datentyp eingelesen werden soll. Anders als beim printf – Befehl muss beim Einlesen vor dem Variablennamen der & Operator gesetzt werden, damit der gelesene Wert auf die Variable geschrieben werden kann. Zum Einlesen von Werten gelten folgende Platzhalter: Datentyp Eingabeformat Platzhalter long dezimal oktal hexadezimal beliebig dezimal beliebige Gleitpunktnotation beliebige Gleitpunktnotation %ld %lo %lx %li %d %f %lf %c %s int float double char char* 3. Unterschied zwischen & und && Operator: & - Operator: Der & - Operator wird als bitweise UND - Verknüpfung verwendet. Ausdruck & Ausdruck && - Operator: Dieser Operator wird als logische UND – Verknüpfung verwendet. Er liefert 1, wenn beide Ausdrücke 1 sind, ist ein Ausdruck 0, so liefert der Operator 0. Der zweite Ausdruck wird nur dann ausgewertet, wenn der erste ungleich 0 ist. & - Operator: Verwendung als unärer Adressoperator. &LValue liefert die Adresse der Variable. Dies wird benötigt um einem Zeiger die Adresse einer Variablen zuzuweisen. Außerdem wird er bei der Funktion scanf benötigt. 2 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 4. Zeiger – Feld – Dualität: Der Name eines Feldes steht auch für die Adresse, an der sich das Feld im Speicher befindet. Der Feldname könnte somit direkt einem Zeiger zugewiesen werden, was allerdings zu schlechtem Programmierstil und Unübersichtlichkeit führt. long feld[10]; long *ptr; ptr = feld; ptr = &feld[0]; //gültig, aber unübersichtlich //korrekt Hier wird der Zeiger auf das erste Feldelement gesetzt. Von Zeiger-Feld-Dualität kann auch gesprochen werden, wenn ein Feld als Parameter an eine Funktion übergeben wird. Wie in Kapitel 13.5 erwähnt, wird ein Feld nicht als Kopie an eine Funktion übergeben. Es wird nur die Adresse des Feldes übergeben. Dies kann mit der sizeof– Anweisung überprüft werden. Adresse Objekt Zeigerschreibweise ptr + n *(ptr + n) Feldschreibweise &feld[n] feld[n] Softwaretechnisch gesehen sind Felder und Zeiger total verschiedene Konstrukte. Felder sind beim Übergeben an eine Funktion ein Zeiger auf das Feld (Call by Reference). Der Feldname kann wie ein Zeiger verwendet werden. 5. Erklären sie den Switch-Case Befehl: Diese Anweisung ermöglicht es mehrere Programmteile selektiv auszuführen. switch(Ausdruck) { case Marke1:Anweisungen: break; case Marke2:Anweisungen: break; ... default: Anweisungen; break; } In der übergebenen Variable Ausdruck, ist die für den aktuellen Programmdurchlauf benötigte Sprungmarke gespeichert. Ist eine übergebene Marke nicht existent, so wird default ausgeführt. Ist auch diese default – Anweisung nicht vorhanden, so wird die gesamte switch – Anweisung übersprungen. Fehlt am Ende einer Sprungmarke nach den Anweisungen das break, so wird auch die nächste Sprungmarke ausgeführt, ohne dass sie aufgerufen wurde. Dies passiert solange, bis das Programm zu einem break kommt. Sprungmarken können nur Zahlen oder Zeichen sein. 3 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 6. Was ist ein Zahlensystem? Welche Zahlensysteme unterstützt C? Ein Zahlensystem wird zur Darstellung von Zahlen verwendet. Eine Zahl wird dabei nach den Regeln des jeweiligen Zahlensystems als Folge von Ziffern beziehungsweise Zahlzeichen dargestellt. Die moderne Forschung unterscheidet zwischen additiven, hybriden und positionellen (Stellenwert-) Zahlensystemen. In einem Additionssystem wird eine Zahl als Summe der Werte ihrer Ziffern dargestellt. Dabei spielt die Position der einzelnen Ziffern keine Rolle. In einem Stellenwertsystem (Positionssystem) bestimmt die Stelle (Position) den Wert der jeweiligen Ziffer. Die „niederwertigste“ Position steht dabei im Allgemeinen rechts. In C wird das Dezimalsystem, Binärsystem, Oktal- und Hexadezimal. Mit jeder beliebigen Basis lassen sich mit m Stellen Zahlen darstellen. Ein Zahlensystem mit der Basis hat Zeichen zum Darstellen von Zeichen. Binärsystem: zwei Zustände ( ) 7. Was ist der Präprozessor: Der Präprozessor ist ein simpler Textersetzer. Er ist ein nützliches Werkzeug, das für den Programmierer größtenteils unsichtbar, vor dem kompilieren automatisch aufgerufen wird. Es werden Modifikationen am Programmquelltext vorgenommen. Der Präprozessor entfernt auch die Kommentare im Quelltext. Alle Präprozessoranweisungen beginnen mit #. #include<headerdatei.h>: Dient zum Einfügen von Headerdateien in den Quelltext. #define HALLO „Hallo Welt“: Damit werden sogenannte Präprozessorkonstanten definiert. #if: Wird verwendet, um Textpassagen im Quelltext Ein- und Auszublenden. #if 0 Quelltext #endif bei #if 0 wird der Text zwischen #if und #endif ausgeblendet, bei #if !0 wird der Text eingeblendet. #if 0/1 Quelltext 0 #else Quelltext 1 #endif Die Quelltexte werden alternativ ausgeführt. 4 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 8. Anweisungen: Operator Regel Elementselektion Zeigerselektion Indizierung Funktionsaufruf Postinkrement Postdekrement Objektgröße Typgröße Präinkrement Postinkrement Komplement Nicht Unäres Minus Unäres Plus Adresse Dereferenzierung Cast (Typumwandlung) Multiplikation Division Modulo Addition Subtraktion Linksschieben Rechtsschieben Kleiner Kleiner Gleich Größer Größer Gleich Gleichheit Ungleich Einfach Zuweisung Multiplikation und Zuweisung Division und Zuweisung Modulo und Zuweisung Subtraktion und Zuweisung Bedingte Zuweisung Komma Objekt . Element Objekt -> Element Zeiger [Ausdruck] Ausdruck(Ausdrucksliste) Lvalue++ Lvalue-Sizeof(Objekt) Sizeof(Typ) ++Lvalue --Lvalue ~Ausdruck !Ausdruck -Ausdruck +Ausdruck &Lvalue *Ausdruck (Typ) Ausdruck Ausdruck * Ausdruck Ausdruck / Ausdruck Ausdruck % Ausdruck Ausdruck + Ausdruck Ausdruck – Ausdruck Ausdruck << Ausdruck Ausdruck >> Ausdruck Ausdruck < Ausdruck Ausdruck <= Ausdruck Ausdruck > Ausdruck Ausdruck >= Ausdruck Ausdruck == Ausdruck Ausdruck != Ausdruck Lvalue = Ausdruck Lvalue *= Ausdruck Lvalue /= Ausdruck Lvalue %= Ausdruck Lvalue -= Ausdruck Ausdruck ? Ausdruck : Ausdruck Ausdruck , Ausdruck 5 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 9. Unterschied Deklaration / Definition, Initialisierung: 9.1. Deklaration: Hierbei handelt es sich lediglich um die Bekanntgabe des Namens und des Typs von Variablen oder Funktionen. Es können nur globale Variable deklariert werden. Dabei existiert die Variable oder Funktion nicht und es wird kein Speicherplatz für sie reserviert. Die Codezeile wird mit einem Semikolon „;“ beendet. Deklarationen stehen oft in Headerdateien bzw. am Programmanfang. Beispiel: long ergebnis(long wert1, long wert2); 9.2. Definition: Eine Definition von Variablen oder Funktionen ist eine vollständige Beschreibung dieser. Die Definition einer Funktion enthält sowohl Funktionskopf als auch Funktionsrumpf. Definitionen sind auch in Bibliotheken bzw. im Programmtext zu finden. Parameter müssen mit Name und Typ beschrieben werden. Beispiel: long wert; double ergebnis; long ergebnis(long wert1, long wert2) { return wert1+wert2; } 9.3. Initialisierung: Unter Initialisierung versteht man das Zuweisen von Werten direkt bei der Variablendefinition. Dies ist nicht immer sinnvoll bzw. notwendig. Beispiel: char text[5] = „DADA“; long a=10; long feld[2][2] ={[1,2],[3,4]}; 10. Unterschied von lokalen und globalen Variablen: Lokale Variable sind nur in jenem Block sichtbar, in dem sie definiert wurden. Sie können nur in diesem Block modifiziert werden. Globale Variable werden außerhalb von Funktionen definiert und sind während der gesamten Programmlaufzeit gültig. Sie werden automatisch mit 0 initialisiert. Außerdem können sie von jeder Funktion manipuliert werden. 11. Was bewirkt die continue-Anweisung: Die continue – Anweisung wird verwendet, um vorzeitig einen nächsten Schleifendurchlauf auszulösen. 6 Blauensteiner Fragenkatalog Programmieren 1 12. Stand: Februar 2013 Was ist ein (Daten)Strom? Ströme sind Objekte, in welche Informationen geschrieben oder aus denen Informationen gelesen werden können. Will man in eine Datei schreiben oder aus ihr lesen, so wird ein Strom benötigt, über welchen die gesamte Kommunikation und auch die Positionierung innerhalb der Datei erfolgen. Es gibt gepufferte und ungepufferte Ströme. Gepufferte Datenströme geben die Informationen erst weiter, wenn eine bestimmte Anzahl gespeichert wurde. Mit dieser Art von Strömen wird standardmäßig gearbeitet. Die Standardbibliothek erlaubt den Zugriff auf Dateien über Datenströme. Um mit diesen Strömen arbeiten zu können, ist es notwendig die Header-Datei „stdio.h“ einzubinden. Standardmäßig geöffnete Ströme: Strom Beschreibung stdout stdin stderr Standardstrom für Ausgabe (z.B.: printf) Standardstrom für Eingabe (z.B.: scanf) Standardstrom für Fehlermeldungen 13. Was sind Literale? 14. Was sind Selektionen? Selektionen werden eingesetzt und verschiedene Programmteile in Abhängigkeit von Bedingungen auszuführen. Es gibt zwei verschiedene Arten von Selektionen: If – Else – Anweisung Switch – Case – Anweisung 14.1. If – Else – Anweisung: Diese Anweisung ermöglicht ein alternatives ausführen von zwei oder auch mehreren Programmteilen in Abhängigkeit einer Bedingung („wahr“, „falsch“). if(Bedingung) { Anweisungen; } else { Anweisungen; } Ist die Bedingung „wahr“, also liefert die Bedingungsabfrage eine „1“, so wird der Programmteil innerhalb der if - Anweisung ausgeführt und der Programmteil in der else - Anweisung wird weggelassen. 7 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 Wird die Bedingung nicht erfüllt, also wenn sie „falsch“ ist wird jener Programmteil innerhalb der if – Anweisung übersprungen und der Teil innerhalb der else – Anweisung ausgeführt. Es ist nicht nur möglich zwischen zwei Programmteilen zu entscheiden, es ist auch möglich zwischen mehr als 2 zu entscheiden. 14.2. Switch – Case – Anweisung: Diese Anweisung ermöglicht es mehrere Programmteile selektiv auszuführen. switch(Ausdruck) { case Marke1:Anweisungen: break; case Marke2:Anweisungen: break; ... default: Anweisungen; break; } In der übergebenen Variable Ausdruck, ist die für den aktuellen Programmdurchlauf benötigte Sprungmarke gespeichert. Ist eine übergebene Marke nicht existent, so wird default ausgeführt. Ist auch diese default – Anweisung nicht vorhanden, so wird die gesamte switch – Anweisung übersprungen. Fehlt am Ende einer Sprungmarke nach den Anweisungen das break, so wird auch die nächste Sprungmarke ausgeführt, ohne dass sie aufgerufen wurde. Dies passiert solange, bis das Programm zu einem break kommt. Sprungmarken können nur Zahlen oder Zeichen sein. 15. Speicherklassen in C: 15.1. Lokale Variable: 15.1.1. Variablen der Speicherklasse auto: Automatische Variable werden automatisch zu Beginn eines Blockes erzeugt und am Blockende automatisch zerstört. Standardmäßig sind alle Variablen automatische Variable, sofern keine Schlüsselwörter, wie register oder static angegeben werden. 15.1.2. Variablen der Speicherklasse register: Variablen dieser Speicherklasse werden nicht im Speicher abgelegt. Ihnen wird ein Register des Prozessors zugeordnet. Daher können für diese Speicherklasse nur die Datentypen long, double (float) und char verwendet werden. Da diese Variablen dann im Prozessor direkt „gespeichert“ sind wird das Programm beschleunigt. Diese Speicherklasse kann beispielsweise für Zähler oder Zeiger in Schleifen verwendet werden. 8 Blauensteiner Fragenkatalog Programmieren 1 15.1.3. Stand: Februar 2013 Variablen der Speicherklasse static: static – Variablen sind wie automatische Variablen zu verwenden und werden ebenso wie diese definiert. Es gibt nur den Unterschied, dass vor dem Datentyp das Schlüsselwort static vorhanden sein muss. Die Variablen der Speicherklasse static werden beim Einsprung in die Funktion sichtbar und beim Verlassen der Funktion wieder unsichtbar. Sie sind nur lokal definiert. Sie können, wie auch die automatischen Variablen initialisiert werden, dieser Initialisierungsvorgang wird allerdings nur zum Programmstart ausgeführt. Wird kein Initialwert angegeben, wird die Variable automatisch mit „0“ (Null) initialisiert. 15.2. Globale Variable: 15.2.1. Variablen der Speicherklasse extern: Grundsätzlich sind globale Variablen, welche nicht mit dem Schlüsselwort static definiert sind externe Variablen. Externe globale Variablen sind innerhalb der Datei in der sie definiert wurden, sichtbar. Sie können auch exportiert werden. Das bedeutet, ihr Datentyp und ihr Name wird in anderen Dateien, welche zum selben Projekt gehören bekannt gemacht und kann dort verwendet werden. Hierfür muss die Variable explizit mit extern deklariert werden. Unter der Deklaration einer Variable versteht man die Bekanntmachung ihres Namen und ihres Datentyps. Nur externe Variablen können deklariert werden. Variablen anderer Speicherklassen müssen definiert werden! 16. Syntax und Semantik: 16.1. Syntax: Die Syntax einer formalen Sprache ist ein System von Regeln, nach denen erlaubte Konstruktionen bzw. wohlgeformte Ausdrücke aus einem grundlegenden Zeichenvorrat gebildet werden. Dabei wird von der inhaltlichen Bedeutung der Zeichen abgesehen. 16.2. Semantik: Die Semantik ist die Lehrer der Bedeutung der Zeichen. Zeichen könne in diesem Fall Wörter, Phrasen oder Symbole sein. Aufbauend auf der Syntax umfasst die Semantik die Bedeutung der Zusammenhänge von Wörtern in einem Text. Damit der Computer die Befehle versteht, benötigt man eine präzise Syntax und Semantik. 17. Vergleichsoperatoren: Es existiert kein eigener Datentyp für Wahrheitswerte in C, daher wird der Datentyp int dafür verwendet. „0“ bedeutet „falsch“ 9 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 Jede Zahl ungleich „0“ bedeutet „wahr“ Erhält man „wahr“ als Ergebnis einer Auswertung von Vergleichsoperatoren und logischen Operatoren, so erhält man „1“. In C existieren folgende Vergleichsoperatoren: 18. Operator Erklärung < <= >= > == != Kleiner Kleiner gleich Größer gleich Größer Gleich Ungleich Wie schreibe ich in einen Datenstrom? Ströme werden durch sogenannte Filehandles – Objekte vom Typ FILE – repräsentiert. FILE *datei; datei=fopen(beispiel.txt, „r“); Es wird ein Zeiger vom Type FILE erstellt. Anschließend wird dieser mit der Anweisung fopen() auf die Datei gerichtet. Der Strom ist hergestellt, die Datei kann jetzt gelesen werden. Mit der Anweisung fclose() wird der Strom wieder geschlossen. Beim Befehl fopen() ist zusätzlich zum Dateinamen auch noch der Zugriffsmodus anzugeben. Modus Beschreibung „r“ „r+“ Öffnen nur zum Lesen Öffnen zum Lesen und Schreiben Öffnen zum Schreiben. Eventuell überschreiben einer bestehenden Datei. Öffnen zum Schreiben und Lesen. Sonst wie „w“. Öffnen zum Schreiben. Bei vorhandenen Dateien wird angehängt Öffnen zum Schreiben und Lesen. Sonst wie „a“. „w“ „w+“ „a“ „a+“ fopen() liefert einen Zeiger auf filehandle zurück, konnte der Strom nicht geöffnet werden, so wird „0“ zurückgegeben. fclose() löst die Verbindung zur Datei und schließt den Datenstrom. Vor dem Beenden werden die gepufferten Daten in die Datei geschrieben. fflush() wird in C implizit durch \n, Eingabefunktionen, durch fclose() oder mit dem Programmende aufgerufen. fopen(), fclose(), fflush() liefern für korrekte Ausführung „0“ und für den Fehlerfall „1“ zurück. 10 Blauensteiner Fragenkatalog Programmieren 1 Funktion Stand: Februar 2013 Beschreibung Rückgabewert Wie printf() nur Anzahl der erfolgt die Ausgabe in geschriebenen den Strom F. Zeichen Wie scanf() nur wird Anzahl der fscanf(F,f,..) aus dem Strom F zugewiesenen gelesen. Werte Liest eine Zeile aus dem Strom F und schreibt sie fgets(s,n,F) nach s, aber nicht mehr als n Zeichen. Liest ein Zeichen aus fgetc(F) dem Strom F. Schreibt das Zeichen c in fputc(c,F) den Strom F. Für das Schreiben von Strukturen oder binären Daten werden die Funktionen fwrite() und fread() verwendet. fprintf(F,f,...) Diese Strukturen dürfen keine Zeiger enthalten, da sonst die in den Zeigern enthaltenen Adressen in den Strom geschrieben werden. Diese sind nur zur Laufzeit des Programms aktuell. 19. Können Parameter einer Funktion als Call by Reference übergeben werden? 20. Was ist ein Algorithmus? Ein Algorithmus ist eine Menge von Regeln für ein Verfahren, welche aus gewissen Eingabegrößen bestimmte Ausgabegröße herleitet. Folgende Bedingungen müssen erfüllt sein: Finitheit der Beschreibung: Das Verfahren muss in einem endlichen Text beschreibbar sein. Die Bestandteile der Beschreibung nennt man Schritte. Effektivität: Jeder einzelne Schritt des Verfahrens muss tatsächlich ausführbar sein. Terminiertheit: Das Verfahren kommt in endlich vielen Schritten zu einem Ende. Determiniertheit: Der Ablauf des Verfahrens ist zu jedem Punkt eindeutig vorgeschrieben. 11 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 21. Wie man eine Konstante verändern kann? 22. Was ist eine Variable? Variablen, sind Objekte, in denen Daten gespeichert werden können. Algorithmen werden immer auf Daten angewandt. Um diese Daten in einem Computerprogramm bearbeiten und speichern zu können, werden Variablen und Konstanten benötigt. Variablen haben gewisse Eigenschaften: 23. Name: Damit werden Variablen und Konstanten eindeutig identifiziert. Ort: Variablen müssen gespeichert werden und haben somit einen Ort (Hardwareregister oder Speicheradresse). Datentyp: Gibt darüber Auskunft welche Daten in einer Variable gespeichert werden können und welche Methoden darauf definiert sind. Wert: Da Variablen einen Ort im Speicher haben, haben diese zu jeder Zeit einen bestimmten Wert (Wert des Bitmusters im Speicher). Gültigkeitszeitraum: Eine Variable muss vor Gebrauch „angefordert“ bzw. „erschaffen“ (instanziert) werden und kann bis zur ihrer Zerstörung verwendet werden. Sichtbarkeitsbereich: Existierende Variable können in bestimmten Programmteilen unsichtbar sein. Dies passiert vor allem bei der Verwendung von lokalen Variablen. Was sind Wahrheitswerte? In C sind Wahrheitswerte nicht typorientiert. In C wird hierfür der Datentyp int verwendet. „0“ wird als logisch „falsch“ interpretiert, alle anderen Zahlenwerte sowohl positive als auch negative werden als logisch „wahr“ interpretiert. 12 Blauensteiner Fragenkatalog Programmieren 1 24. Stand: Februar 2013 Was ist eine Konstante? Konstanten sind nicht veränderlich, sie müssen jedoch initialisiert werden. Es ist Konvention, dass Konstanten Namen in Großbuchstaben geschrieben werden. Eine Konstante muss definiert und initialisiert werden, wie eine Variable, kann aber vom Programm nur gelesen und nicht verändert werden. Const Typ Name = Wert; 25. Was steht in Headerdateien drinnen bzw. was darf nicht drinnen stehen? Headerdateien beinhalten Bekanntmachungen (Deklarationen) und Informationen über den strukturellen Aufbau von neu definierten Datentypen. Headerdateien werden zur Übersetzung von Quelltextdateien benötigt. Des Weiteren enthalten Headerdateien Definitionen von Präprozessorkonstanten, Typ- und Strukturdefinitionen und Funktionsdeklarationen. Sie haben das Suffix .h und heißen so, weil sie zur Übersetzungszeit im Kopf des Programms dazugeladen werden. Sie enthalten in C keine Funktionen! 26. Der Kommaoperator: Der Kommaoperator wird eher selten verwendet. Sein Haupteinsatzgebiet ist innerhalb der for – Schleife. Dieser Operator gleicht dem Semikolon „;“. Beide Operatoren dienen zum Trennen von Ausdrücken. Der ist Unterschied ist nur, dass das Komma ein Operator ist und das Semikolon nicht. Wie jeder Operator hat auch das Komma einen Rückgabewert. Dieser ist der Wert des letzten Ausdruckes. Die Auswertung erfolgt von links nach rechts. a=0, b=1 Der Rückgabewert ist somit 1; 27. Mehrdimensionale Felder: Da C auch mehrdimensionale Felder unterstützt, kann jedes Feldelement auch mehr als nur ein Indizes haben. So können beispielsweise Matrizen realisiert werden. Feldtyp feldname [Feldhöhe] [Feldlänge]; long matrix[3][4]; Damit wird ein 2 – dimensionales Feld mit 3x4 Elementen erzeugt. Es können beliebig viele Indizes angegeben werden, allerdings begrenzen das Betriebssystem und die Rechnerarchitektur den tatsächlichen Speicherplatz. Bei 2 – dimensionalen Feldern gibt der erste Indizes die Zeile und der zweite Indizes die Spalte der Matrix an. 13 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 Beide Indizes laufen von „0“ bis N-1. matrix[1][2]=27; In diesem Beispiel wird dritte Element in der zweiten Zeile auf den Wert „27“ gesetzt. 28. Unterschied Interpreter-Compiler: 28.1. Compiler: Die einzelnen Module eines Software – Projekts werden kompiliert und zu einem Lauffähigen Programm zusammengefügt. Wird ein einzelnes Modul verändert, so muss das gesamte Projekt neu kompiliert werden. Da das Programm anschließend fertig vorliegt, so kann das Programm schnell ausgeführt werden. 28.2. Interpreter: Das Software – Projekt liegt in Form von Quelltextdateien vor und wird erst dann in Maschinensprache übersetzt (kompiliert) wenn es ausgeführt wird. Diese Methode hat den Vorteil, dass bei Änderungen in nur einem Programmteil nicht das gesamte Projekt vor dem Ausführen kompiliert werden muss, da es beim Ausführen sowieso immer wieder kompiliert wird. Die Ausführungsgeschwindigkeit ist dadurch etwas langsamer als beim Compiler. 29. Welche Datentypen kennen Sie? Datentyp Bits Wertebereich short int 16 32 16 0…65535 0…4294967295 -32768…+32767 16 0…+65535 2147483648…+2147483647 0…+4294967295 long int signed short int unsigned short int Signed long int 32 unsigned long int 32 float double long double 32 64 ≥64 1.9E-4951 .. 1.1E4932 char 8 ein Zeichen 1.5E-45 .. 3.4E38 5.0E-324 .. 1.7E308 14 Blauensteiner Genauigkeit 7-8 Stellen 15-16 Stellen 19-20 Stellen Fragenkatalog Programmieren 1 Stand: Februar 2013 30. Kann man unterschiedliche Datentypen miteinander vergleichen? Was ist mit 2 Doubles? 31. Regel vom Testen Durch Testen kann nur die Anwesenheit von Fehlern, jedoch nicht die Abwesenheit dieser nachweisen. In komplexeren Programmen können nicht alle möglichen Konfigurationen von Eingabedaten getestet werden. Werden alle Eingaben getestet, so spricht man von einem erschöpfenden Test. Empfehlung: Einzelne Funktionalitäten einzeln während der Implementierung testen. Man sollte immer Testprogramme schreiben und diese Beibehalten. (Nachvollziehung) 32. Erklärung snprintf: Die Funktion snprintf funktioniert genauso wie die Funktion printf. Sie schreibt den auszugebenden Text allerdings nicht in den Ausgabestrom, sondern in ein Feld. Es werden n Zeichen in das Feld s geschrieben. snprintf(s, n, f, …) Wird diese Funktion verwendet, so darf der zweite Parameter nicht größer als die Feldlänge sein. Wird dieser größer als die Feldlänge gewählt, so kann werden lange Zeichenketten über die Feldgrenzen hinaus geschrieben, was zu einem Fehlverhalten oder Absturz des Programmes führen kann. 33. Wie werden Punktzahlen in C dargestellt? Punktzahlen werden entweder im Festpunkt- oder als Gleitpunkt-Zahlensystem dargestellt. Punktzahlen werden folgendermaßen dargestellt: Die Zahl wird Mantisse genannt, ist die Basis und der Exponent. In C sind Gleitpunktzahlen mit der Basis 2 implementiert, daher wird anstatt der Basis Vorzeichen der Zahl gespeichert. Eine Gleitpunktzahl kann in C aussehen wie folgt: Einfach langes Format (float): 15 Blauensteiner das Fragenkatalog Programmieren 1 Stand: Februar 2013 v…Vorzeichen e…Exponent M…Mantisse (Zahl) 33.1. Doppelt langes Format (double): Gleitpunktzahlensysteme in C: Das einfach genaue Zahlenformat mit 32 Bit Länge ist als Datentyp float in C implementiert. Das doppelt genaue Zahlen Format von 64 Bit Länge ist durch den Datentyp double implementiert. Datentyp Bits Genauigkeit kleinste darstellbare Zahl float 32 6 Stellen double 64 12 Stellen long double ≥64 18 Stellen 34. Wozu gibt es Funktionen? Funktionen werden verwendet um: 35. Programme zu strukturieren Wiederkehrende Programmteile als eigene Funktionen wieder verwenden zu können In sich abgeschlossene definierte Teilaufgaben zu programmieren Die Funktionalität zu erweitern Welche Schleifen gibt es - wozu, wann verwende ich welche? for – Schleife: Ist in C die komplexeste Schleife. Die for – Schleife ist eine vorprüfende Schleife. for(Initialisierung; Bedingung; Inkrement) { Anweisungen; } 16 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 Bei der for – Schleife wichtig sind die Strichpunkte zum Trennen der Ausdrücke. Wird ein Ausdruck weggelassen, so müssen die Strichpunkte trotzdem entsprechend gesetzt werden. Die for-Schleife ist eine zählende Schleife und wird für Aufgaben verwendet, bei denen bekannt ist, wie viele Schleifendurchläufe notwendig sind. while – Schleife: Die while– Schleife ist die mächtigste Schleife in C und ist ebenso wie die for – Schleife eine Vorprüfende. Alle anderen Schleifenarten können durch diese ausgedrückt werden. while(Bedingung) { Anweisungen; } Bevor die Anweisungen im inneren der Schleife ausgeführt werden, wird die Bedingung überprüft. Liefert diese „falsch“ zurück, so wird der Anweisungsblock in der Schleife übersprungen. Liefert die Prüfung „wahr“ zurück, so wird die Schleife durchlaufen und anschließend wieder die Bedingung geprüft. Die while – Schleife wird solange wiederholt, bis die Bedingung nicht mehr erfüllt ist. Ändert sich die Schleifenbedingung während eines Schleifendurchlaufes, so wird dies von der Schleife erst bei der nächsten Bedingungsprüfung bemerkt. while – Schleifen werden dort verwendet, wo der Programmablauf (die Schleifenbedingung) vom Anweisungsblock in der Schleife abhängig ist. do – while – Schleife: Diese Schleife ist eine nachprüfende. Der Anweisungsblock im inneren der Schleife wird also mindestens einmal ausgeführt. Erst nach dem ersten Schleifendurchlauf wird die Bedingung zum ersten Mal geprüft. do { Anweisungen; } while(Bedingung); Wichtig bei der do-while – Schleife ist das Semikolon am Ende der Schleife! 36. Zeichenketten: Literale von Zeichenketten sind Zeichenfolgen, welche in doppelte Anführungszeichen gesetzt sind. „Hallo Welt!“ Zeichenketten in C sind „nullterminierte“ Folgen von Zeichen, welche in Feldern von Zeichen gespeichert werden. 17 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 „Nullterminiert“ bedeutet, dass eine Zeichenkette mit einer ‚\0‘ abgeschlossen wird. Das bedeutet weiter, dass eine Zeichenkette mit 5 Zeichen 6 Speicherplätze benötigt. ‘H‘ ‘A‘ ‘L‘ ‘L‘ ‘O‘ ‘\0‘ Das Null-Byte ist das Zeichen mit dem ASCII-Code 0. Es ist also die Zahl „0“ (\0), nicht zu verwechseln mit dem Zeichen „0“ (Null). Dieses Null-Byte wird automatisch an Text angehängt. Dies hat den Vorteil, dass beliebig lange Texte abgespeichert werden können. Der Text endet immer mit dem Null-Byte. Zum Feststellen der Länge einer Zeichenkette wird die Funktion strlen() verwendet. 37. Umrechnung Dezimal – Binär und Binär - Dezimal? Warum ist das so? 37.1. Umwandlung von Dualzahlen in Dezimalzahlen Zur händischen Umwandlung von Dualzahlen in Dezimalzahlen, bedient man sich einer Tabelle. Die Dualzahl wird in die Tabelle (Zeile Dualzahl) eingetragen. Wenn der Dualwert eine 1 ist, wird der Dezimalwert dieses Dualwertes darunter gesetzt. Bei 0 wird die Stelle frei gelassen. Daraus ergibt sich die Summe des Dezimalwertes der Dualzahl. Die Stellenwerte in der Tabelle können nach links beliebig erweitert werden. Stellenwerte 29 28 27 26 25 24 23 22 21 20 Stellenwerte als Dezimalwert 512 256 128 64 32 16 8 Dualzahl 1 Summe: 915 37.2. 1 1 0 0 512 256 128 1 16 0 4 2 1 0 1 1 2 1 Umwandlung von Dezimal in Dualzahlen: Eine Methode zur Umwandlung einer Dezimalzahl in eine Dualzahl ist das Teilen der Dezimalzahl durch die Basis (2). Nach der Teilung wird der Rest zur "1". Gibt es keinen Rest, wir die Dualstelle zur "0". Nun teilt man das Ergebnis solange durch die Basis, bis das Ergebnis 0 wird. Das Ergebnis muss dann von unten nach oben gelesen werden, damit die Dualzahl stimmt. Zur Kurzprüfung der Dualzahl muss diese an der letzten Stelle eine "1" haben, wenn die Dezimalzahl ungerade war. Aus Dezimal 637 wird Dual 1001111101. 637 : 2 = 318,5 --> 1 318 : 2 = 159,0 --> 0 18 Blauensteiner Fragenkatalog Programmieren 1 38. Stand: Februar 2013 159 : 2 = 79,5 --> 1 79 : 2 = 39,5 --> 1 39 : 2 = 19,5 --> 1 19 : 2 = 9,5 --> 1 9:2= 4,5 --> 1 4:2= 2,0 --> 0 2:2= 1,0 --> 0 1:2= 0,5 --> 1 Erklärung typedef: Mittels typedef können neue Typnamen für Variablen, Funktionen und Strukturen selbst definiert werden. Dies bringt eine Vereinfachung, wenn längere Datentypbezeichnungen öfter verwendet werden. 38.1. Abgeleitete Datentypen: Mit der typedef – Vereinbarung können neue Typnamen erzeugt werden. Diese sind äquivalent mit der Bezeichnung wofür sie stehen. typedef char *string; Damit wurde ein neuer Typname string definiert. Dieser Typname ist identisch zu handhaben wie alle anderen Datentypen. char *text1 = “Hallo“; string text2 = „Welt“; Beide Variablendefinitionen sind vollkommen identisch. 38.2. Strukturen: Typedef kann auch bei Strukturen verwendet werden. typedef struct Punkt_s { struct Punkt_s *naechster; double x, y; }Punkt_t; Hier kann jetzt anstatt der Struktur eine neu Variable einfach über den Typnamen Punkt_t erstellt werden. 19 Blauensteiner Fragenkatalog Programmieren 1 38.3. Stand: Februar 2013 Funktionen: Mit typedef können auch Typnamen für Zeiger auf Funktionen generiert werden. typedef long Funktion_t(long, long); Hier wird allgemein eine Funktion Funktion_t erzeugt, welche als Parameter zwei long – Variable erwartet. Eine Funktionsdefinition sieht wie folgt aus: Funktion_t *function; 39. Was sind Literale? Mit Literal bezeichnet man in Programmiersprachen eine Zeichenfolge, die zur direkten Darstellung der Werte von Basistypen (z. B. Ganzzahlen, Gleitkommazahlen, Zeichenketten) definiert bzw. zulässig sind. Man unterscheidet logische (wahr, nicht wahr), numerische und Zeichenliterale. Je nach Programmiersprache gibt es weitere und detailliertere Kategorisierungen für Literale. Damit Literale vom Compiler identifiziert werden können, müssen sie bestimmten syntaktischen Regeln genügen, z. B. (sprachenabhängig und in bestimmten Fällen) in Anführungszeichen eingeschlossen sein. 40. Was ist ein Linker? Der Linker fügt nach dem Kompilieren und Optimieren die Objektdateien und Bibliotheken zu einem Ausführbaren Programm zusammen. 41. Zusammenspiel Headerdateien – Bibliotheken: Headerdateien können einerseits in Bibliotheken vorhanden sein, oder können selbst geschrieben werden. Um Funktionen aus Bibliotheken zu verwenden, müssen die entsprechenden Headerdateien in das Programm inkludiert werden. Zum Beispiel: #include<stdio.h> (Standard Ein- und Ausgabefunktionen) aus der CStandardbibliothek (libc.a oder libc.so) #include <math.h> (Mathematische Funktionen) aus der Mathematikbibliothek (libm.a oder libm.so) #include“myheader.h“ Selbst erzeugte Headerdatei, wird im Projektordner gespeichert. 20 Blauensteiner Fragenkatalog Programmieren 1 42. Stand: Februar 2013 Was sind Bitfelder? Bitfelder werden für speicherkritische Anwendungen verwendet. Diese können zum Beispiel zum Speichern von Maschinenwörtern verwendet werden. struct Bitfeld_s { unsigned int a:1; //Bitfeld mit Länge 1 unsigned int b:2; //Bitfeld mit Länge 2 unsigned int c:3; //Bitfeld mit Länge 3 }; In diesem struct sind 3 Bitfelder mit den Längen 1 Bit, 2 Bit und 3 Bit definiert worden. Bitfelder dürfen nur als int vereinbart werden, wobei signed oder unsigned aus Gründen der Portabilität angegeben werden muss. Bitfelder können mit den Bitoperatoren „&“, „|“, „^“, „~“ bearbeitet werden. Bitfelder haben keine Adresse, es können daher keine Zeiger definiert werden. 43. Was macht der Operator ->? 44. Was heißt Dereferenzieren? Dereferenzieren bedeutet auf den Inhalt der in einem Zeiger gespeicherten Daten zuzugreifen. 45. Was ist ein Zeiger? Ein Zeiger ist ein Objekt (! KEINE VARIABLE!), welches eine Adresse enthält. Zeiger können auf die Adresse von Objekten gesetzt werden. Dazu wird der Adressoperator & verwendet. ptr = &a Adresse von a. Mit Hilfe des Dereferenzierungsoperators „*“ kann man dann über den Zeiger auf das Objekt zugreifen. wert = *ptr Wert, welcher an der in ptr gespeicherten Adresse steht. Wird ein Zeiger auf „0“ (Null) gesetzt, so wird dieser dadurch ungültig gemacht. (ptr = 0;) Soll eine Funktion mehr als einen Rückgabewert haben, so übergibt man der Funktion Zeiger als Parameter (Call by Reference). Zeiger auf Funktionen: Typ (*Funktionsname) (Parameterliste) Ist das „*“ außerhalb der Klammer, dann ist der Ausdruck eine Funktionsdeklaration (Rückgabewert: Zeiger vom Typ long). 21 Blauensteiner Fragenkatalog Programmieren 1 46. Stand: Februar 2013 Was ist ein Qualifizierer? Werden dem Datentyp int Qualifizierer vorangestellt, so wird der Wertebereich verändert. Datentyp Bits Wertebereich short int long int signed short int unsigned short int Signed long int unsigned long int 16 32 0…65535 0…4294967295 16 -32768…+32767 16 0…+65535 32 2147483648…+2147483647 32 0…+4294967295 Diese Angaben gelten bei 32 Bit Architektur! 47. Was sind Escape – Sequenzen? Mit Hilfe der Escape – Sequenzen kann ein Text bei der Ausgabe besser formatiert werden: Escape-Sequenz \n \t \\ \“ \a \b 48. Auswirkung Neue Zeile Tabulator Back-Slash (\) Doppelhochkomma Klingelton (beep) Rücksetzt Zeichen (backspace) Der Kompiliervorgang: Der Quelltext wird vom Präprozessor auf für ihn bestimmte Anweisungen durchsucht. (Präprozessoranweisungen) Der Präprozessor ist ein einfacher Textersetzter, welcher durch die für ihn bestimmten Anweisungen den Quelltext modifiziert. Der Quelltext wird auf syntaktische Fehler überprüft. Es wird geprüft ob der Text den Regeln der Programmiersprache C entspricht. Der Quelltext kann gegebenenfalls noch optimiert werden. Dabei werden die Befehle so umsortiert, das die Programmlogik nicht verändert wird, jedoch die Ausführung beschleunigt wird. Der Compiler wird gestartet. Der Quelltext wird in Assemblersprache übersetzt. Jeder Assemblerbefehl ist direkt einem Maschinenbefehl zugeordnet. Der Quelltext kann als Assemblerdatei ausgegeben werden. Der Assemblercode wird in Maschinensprache übersetzt. Die ausführbare Datei wird erzeugt. 22 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 Zwischen Compiler und Assembler kann noch ein Optimierungsschritt eingefügt werden, welcher durch umsortieren der Befehle die Programmgeschwindigkeit und die Codegröße optimiert, ohne die Programmlogik zu verändern. 49. Was ist der ASCII – Code? Der ASCII – Code legt die Codierung der im englischen Sprachraum gebräuchlichen Buchstaben fest. Hierbei handelt es sich um einen 7-bit – Code. Der Wertebereich liegt zwischen 0 und 127. Er enthält im Bereich 1 bis 32 Steuercodes. Die nächsten 96 Codes beinhalten Buchstaben des englischen Sprachraums sowie diverse Sonderzeichen. Dieser Bereich ist genormt. Die Umlaute des deutschen Sprachraumes sowie zusätzliche Sonderzeichen sind im erweiterten ASCII-Code im Bereich von 128 bis 255 enthalten. Dieser Bereich ist nicht genormt. 50. Zeichen ASCII-Code - Bereich 0…9 A…Z a…z 48…57 65…90 97…122 Wie funktioniert die Typumwandlung? 50.1. Implizite Typumwandlung: Implizite Typumwandlung findet statt, wenn ein bestehender Datentyp in einen anderen bestehenden Datentyp umgewandelt werden soll. char zu long long zu double Funktioniert ohne Datenverlust Funktioniert ohne Datenverlust Kann mit Datenverlust verbunden sein (long =32Bit, char =8Bit) Immer mit Datenverlust verbunden Nachkommastellen werden abgeschnitten long zu char double zu long 50.2. Explizite Typumwandlung: Explizite Typumwandlung findet statt, wenn ein Zieldatentyp angegeben ist. long x = 12; long y = 5; double e = x/y; Hier kommt es zu Datenverlust, da eine Ganzzahldivison ausgeführt wird, weil Divisor und Dividend Ganzzahlvariable sind. Der Datenverlust kann verhindert werden, indem eine der Variablen durch einen Cast in eine double – Variable umgewandelt wird. double e = (double)x/y; 23 Blauensteiner Fragenkatalog Programmieren 1 Stand: Februar 2013 (double) … Cast – Operator x wird in double umgewandelt kein Datenverlust 51. Was bewirkt die break-Anweisung? Die break – Anweisung wird verwendet um Schleifen vorzeitig zu beenden oder bei der switch – case – Anweisung um nach dem Ausführen der Befehle einer Sprungmarke die Selektion zu verlassen. Wird am Ende der Sprungmarke ein break weggelassen, so wird auch die Nächste ausgeführt ohne das die Sprungmarke ausgewählt wurde. Dies passiert, bis es zu einem break kommt. 24 Blauensteiner