Programmieren Fragen 1 Printf Headerdatei: stdio.h Printf(print formated): für Ausgabe, man schreibt in den stdout – Datenstrom, erwartet ein Argument (Zeichenkette mit Platzhalter( Parameter). Rückgabewert ist die Anzahl der ausgegebenen Zeichen. Es ist eine Kurzschreibweise von fprintf(stderr, „Zeichenkette %..“, Variable). 2 Scanf Scanf(scanf formatted): für Einlesen, es wird von stdin-Datenstrom gelesen. Liest Zeichen für Zeichen bzw. Zahl für Zahl. Scnaf erwartet ein Argument (Zeichenkette, Platzhalter ( Parameter). Einlesen mit <ENTER> abgeschlossen. Rückgabe wert ist die Anzahl der erfolgreich eingelesenen Zeichen, bzw. Zahlen. 3 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 4 Mindestausstattung einer Entwicklungsumgebung: • Projektverwaltung • Programmierumgebung (Editor) • Übersetzer (Compiler) • Testumgebung 1 ©CVD Vil 5 Printf / Scanf: 5.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: 5.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: 2 ©CVD Vil 6 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. 7 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. 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. 3 ©CVD Vil 8 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. 9 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 n lassen sich mit m Stellen n^m Zahlen darstellen. Ein Zahlensystem mit der Basis n hat n Zeichen zum Darstellen von Zeichen. Binärsystem: n = 2 → zwei Zustände (0,1 ) 4 ©CVD Vil 10Was 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. 5 ©CVD Vil 11Anweisungen in C 6 ©CVD Vil 12Unterschied Deklaration / Definition/ Initialisierung: 12.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); 12.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; } 12.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]}; 7 ©CVD Vil 13Unterschied 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. 14Was bewirkt die continue-Anweisung: Die continue – Anweisung wird verwendet, um vorzeitig einen nächsten Schleifendurchlauf auszulösen. 15Was 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: 8 ©CVD Vil 16Was 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. Zeichenfolge mit der Werte formuliert werden. 17Was 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 18If – 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 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 und mehr als zwei zu entscheiden. 9 ©CVD Vil 19Switch – 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. 20Speicherklassen in C: Man unterscheidet hier zwischen lokalen und globalen Variablen. 20.1 Lokale Variable: 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. 10 ©CVD Vil 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. 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. 20.2 Globale Variable: 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! 11 ©CVD Vil 21Syntax und Semantik: 21.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.(Die Syntax einer Sprache beschreibt die Regeln, nach denen Sprachkonstrukte gebildet werden.) 21.2 Semantik: Die Semantik ist die Lehrer der Bedeutung der Zeichen. Zeichen können 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. (Die Semantik beschreibt die Bedeutung der Sprachkonstrukte) 22Vergleichsoperatoren: Es existiert kein eigener Datentyp für Wahrheitswerte in C, daher wird der Datentyp int dafür verwendet. • „0“ bedeutet „falsch“ • 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: 12 ©CVD Vil 23Wie 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. 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. 24Welche Funktionen gibt es um in Strukturen oder binären Daten hinein zu schreiben? fwrite() und fread() 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. 13 ©CVD Vil 25Welche Funktionen gibt es um etwas in einen Datenstrom zu schreiben? 26Können Parameter einer Funktion als Call by Reference übergeben werden? Nur wenn der Parameter ein Feld ist bzw. ein Zeiger. zB void Ausgabe(long feld[]) würden die Kopien übergeben werden (call by value) kann schnell sehr viel Speicher verbraucht werden. (eigentlich wird hier genauer betrachtet auch ein call by value durchgeführt => es wird der Wert des Pointers auf das Feld übergeben – die Adresse ZeigerFeld-Dualität) 27Was 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. 14 ©CVD Vil 28Wie man eine Konstante verändern kann? Über Zeiger. Man ruft die Adresse auf, speichert sie in einen anderen Zeiger und ändert den Wert dann über den Dereferenzierungsoperator. 29Was 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: • 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. 30Was 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. 15 ©CVD Vil 31Was 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; 32Was 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! 33Der 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; Der Kommaoperator erlaubt es auch mehrere Ausdrücke auszuführen wo nur ein Ausdruck erlaubt wäre: for(i=0, j=1; i<10; j--, i++) 16 ©CVD Vil 34Mehrdimensionale 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. 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. 35Unterschied Interpreter-Compiler: 35.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. 35.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. 17 ©CVD Vil 36Welche Datentypen kennen Sie? 37Kann man unterschiedliche Datentypen miteinander vergleichen? Was ist mit 2 Doubles? Bei zwei Doubles muss man immer auf einem kleinen Bereich epsilon vergleichen da reelle Zahlen in der Form Mantisse - Exponent gespeichert werden und meistens nicht ganz genau gleich sind (float, double oder long double) Ja, weil auch char einen int Wert haben . (-128 bis 127) der Vergleich ist durchaus möglich. Ja, kann man, allerdings findet dabei mitunter eine automatische Typumwandlung statt. Die exakte Abfrage auf Gleichheit bei double ist aufgrund von Fehlern numerischer Verfahren nicht möglich vielmehr muss bestimmt werden, ob das Resultat hinreichend genau ist 38Regel vom Testen Durch Testen kann nur die Anwesenheit von Fehlern, jedoch nicht die Abwesenheit dieser nachgewiesen werden. 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) 18 ©CVD Vil 39Erklä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. 40Gleitpunktzahlensysteme 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. 41Wozu gibt es Funktionen? Funktionen werden verwendet um: • 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 19 ©CVD Vil 42Wie werden Punktzahlen in C dargestellt? Punktzahlen werden entweder im Festpunkt- oder als Gleitpunkt-Zahlensystem dargestellt. Punktzahlen werden folgendermaßen dargestellt: Die Zahl m wird Mantisse genannt, b ist die Basis und der Exponent. In C sind Gleitpunktzahlen mit der Basis 2 implementiert, daher wird anstatt der Basis b das Vorzeichen der Zahl gespeichert. Eine Gleitpunktzahl kann in C aussehen wie folgt: • Einfach langes Format ( float ): v...Vorzeichen e...Exponent M...Mantisse (Zahl) • Doppelt langes Format ( double ): 43Welche Schleifen gibt es - wozu, wann verwende ich welche? 43.1 for – Schleife: Ist in C die komplexeste Schleife. Die for – Schleife ist eine vorprüfende Schleife. for(Initialisierung; Bedingung; Inkrement) { Anweisungen; } 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. 20 ©CVD Vil 43.2 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. 43.3 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 Continue – Anweisung? ist wie die break-Anweisung eine Sprung-Anweisung. Im Gegensatz zum break wird die Schleife nicht verlassen, sondern der Rest der Anweisungen übersprungen und ein neuer Schleifendurchgang gestartet. Anwendung: do-while, while, for { Anweisungen; } while(Bedingung); Wichtig bei der do-while – Schleife ist das Semikolon am Ende der Schleife! 21 ©CVD Vil 44Zeichenketten: 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. „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. 45Umrechnung Dezimal – Binär und Binär - Dezimal? Warum ist das so? 45.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. 22 ©CVD Vil 45.2 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, wird 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 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 46 47Erklä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. 23 ©CVD Vil 47.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. 47.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 neue Variable einfach über den Typnamen Punkt_t erstellt werden. 47.3 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; 24 ©CVD Vil 48Was ist ein Linker? Der Linker fügt nach dem Kompilieren und Optimieren die Objektdateien und Bibliotheken zu einem Ausführbaren Programm zusammen. 49Zusammenspiel 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 C- Standardbibliothek (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. 50Was 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. 25 ©CVD Vil 51Was macht der Operator ->? Elementzugriff. Dieser Operator stellt eine Vereinfachung dar, um über einen Zeiger auf ein Element einer Struktur oder Union zuzugreifen. objZeiger->element entspricht (*objZeiger).element 52Was heißt Dereferenzieren? Dereferenzieren bedeutet auf den Inhalt der in einem Zeiger gespeicherten Daten zuzugreifen. 53Was 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). 26 ©CVD Vil 54Was ist ein Qualifizierer? Werden dem Datentyp int Qualifizierer vorangestellt, so wird der Wertebereich verändert. Diese Angaben gelten bei 32 Bit Architektur! 55Was sind Escape – Sequenzen? Mit Hilfe der Escape – Sequenzen kann ein Text bei der Ausgabe besser formatiert werden: 56Was 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. 27 ©CVD Vil 57Der 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. 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. 58Was 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. 28 ©CVD Vil 59Wie funktioniert die Typumwandlung? implizite Umwandlung, wird zur Zeit der Übersetzung festgestellt. char in long, double ok, long in double auch ok aber in char (Datenverlust außer liegt im Wertebereich!) double kann in keinen anderen eingebauten Datentyp umgewandelt werden explizite Umwandlung, von Literalen sinnlos ((double)2 oder (int)1.0) Cast-Operator: zB 1/3=0 weil Ganzzahldivision ( wendet man auf eine der Beiden Zahlen an (doubel)1/3=0,3333-> exakt (Datentypgenauigkeit)!) 59.1 Implizite Typumwandlung: Implizite Typumwandlung findet statt, wenn ein bestehender Datentyp in einen anderen bestehenden Datentyp umgewandelt werden soll. 59.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; (double) ... Cast – Operator → x wird in double umgewandelt → kein Datenverlust 29 ©CVD Vil 60Mindestanforderung (Ausstattung) einer Entwicklungsumgebung? >>Projektverwaltung verwaltet das Softwareprojekt (zB Projektbeschreibung, sourcefiles, headerfiles, Dokumentation, Schnittstellendefinitionen zw. Modulen, projektspez. Optionen, Makefiles [beschreiben Übersetzungsabfolge]) >>Programmierumgebung (Editor) zum Eingeben des Quelltextes (auch farbliche Gestaltung von Funktionen etc. wegen Übersichtlichkeit) auch einfache Syntaxüberprüfung während Eingabe >>Übersetzer generiert den source code vom Programmtext: Quelltextdatei => Präprozessor => Kontrolle => Compiler => └>präprozessierte Datei ╚>Optimierung>╝└> Assembler-Datei Assembler => Objektdatei Präprozessor: simpler Textersetzer (präprozessorkonstanten) Kontrolle: Syntaxüberprüfung (formale Regeln von C, auch einfache Fehler werden gesucht) Compiler: übersetzt C-Befehle in Assembler Assembler: assembliert ; übersetzt Assembler in Maschinencodes Optimierung: optimiert Assemblercode (zB nach Laufzeit, Codegröße); für verschiedene Prozessortypen (je nach pipelining der CPU werden Befehle umsortiert => Beschleunigung ohne Verändern der Logik) Linker: verknüpft dann die Objektdatei(en) mit entsprechender(n) Bibliothek(en) => ausführbare Datei 61Unterschied #if, if? #if: eine Präprozessoranweisung fürs Ein- und Ausblenden von Textpassagen (zB für Teile des Codes, die man kurzzeitig nicht implementieren will besser [professioneller] als Ausblenden mit /* */ oder // ) Verwendung: #if 0 // Programmtext // … #else // Programmtext 2 //… #endif kann auch ohne #else stehen; beim obigen bsp. wird programmtext ausgeblendet und programmtext 2 eingeblendet; wenn #if 1 dort steht ist es umgekehrt if: eine Selektion (Anweisung), um Programmteile in Abhängigkeit einer Bedingung auszuführen if ermöglicht das alternative Ausführen 2er Programmteile abhängig von der Bedingung (welche wahr oder falsch ergibt) if (Bedingung) Block else Block 30 ©CVD Vil 62Was passiert wenn man ein Feld von 0…9 mit -1 anspricht? Man kann theoretisch dem element -1 einen Wert zuweisen, aber man schreibt bzw. liest außerhalb der Feldgrenzen was fatale Folgen haben kann, keine Fehlermeldung. 63Wie können Felder doch kopiert werden? zwei gleich lange Felder in Funktion übergeben und dann mit for-schleife Elementweise kopieren (zuweisen) dst[i]=src[i]; 64Was ist der Unterschied zwischen „A“ und ‚A’? unter doppelten Anführungszeichen ist es ein string (Zeichenkette) es gibt eigene Funktionen hierzu, unter einfachen Anführungszeichen ist es ein Zeichen für den Typ char. 65Was heißt Spezifikation? Problembeschreibung (wesentliche Schritte zur Problemlösung) , was muss ich wirklich tun (lt. Buch Spezifikation) was ist gefragt ! Leistung zur Lösung von Aufgaben: Identifikation des Problems und Aufstellung der Spezifikation! 66Felder? Verwendung: Daten des selben Datentyps zu speichern (Gruppe, Aneinanderreihung von Variablen des gleichen Typs) und unter einem Namen + Index referenziert werden können. Der Feldname steht für die Adresse des Feldes es ist aber besser den Adressoperator (&) zu verwenden, dient zur besseren Lesbarkeit. Feldgrenzen sind starr und sollten nicht überschrieben werden: Fatale Folgen, kein Bemerken des falschen Speicherzugriffs Programm arbeitet nicht richtig 67Was ist der Unterschied zwischen Programm und Algorithmus? Programme sind spezielle Erscheinungsformen von Algorithmen, Programmiersprache ist letztlich ein formales Werkzeug zur Notation von Algorithmen. Algorithmus ist der Oberbegriff zu Programm, bei dem man die strengen syntaktischen Regeln der Programmiersprache nicht einhalten muss. Was sind ESCAPE-Sequenzen? Was macht der Assemblierer? Was für Rechenoperationen gibt es für ganze Zahlen bzw. für Punktzahlen? Was ist Modulo für eine negative Zahl? (-5%2, 5%-2, -5%-2….) Wann benötigt man Zeiger auf Zeiger? Wie übergibt man Parameter in eine Funktion? 31 ©CVD Vil 68Zeiger Feld Dualität? Softwaretechnisch gesehen total verschiedene Konstrukte (Zeiger ist ein Objekt das eine Adresse speichert(Merker), Feld ist ein Verbundtyp, der mehrere Daten des selben Typs speichert). Felder sind beim Übergeben in eine Funktion ein Zeiger auf das Feld (call by reference). Der Feldname kann wie ein Zeiger verwendet werden. Adresse: Objekt: Zeigerschreibweise ptr + n *(ptr + n) Feldschreibweise &feld[n] feld[n] 69„? :“ Operator? Verkürzte Version der if-else-Anweisung: Bedingung ? if-Ausdruck : else-Ausdruck zB: abfrage = (a>0) ? ‚j’ : ‚n’; 70Erkläre scanf(a,b) a muss ein Pointer auf einen String sein, b muss ein Pointer auf die Variable sein, wo es abgespeichert wird. 71Addition von Kommazahlen Exponenten ("Hochzahlen") werden angeglichen (zur grösseren Zahl), danach die Mantissen ("Basis", hat hier nichts mit der Basis des Zahlensystems zu tun) addiert. 72Datenstrom: 72.1 Zugriff auf Dateien Den von fopen gelieferten Filepointer in einem FILE * (Filepointer) speichern, 72.2 Positionierung Positionierung ist je nach Dateimodus entweder am Anfang oder am Ende (Append), Positionierung mittels fseek und Abfrage mittels ftell (edit: frewind vergessen) bei allen Operationen wird der Filepointer automatisch erhöht. 32 ©CVD Vil Unterschied zwischen gepuffert und ungepufferten Datenströmen Ungepuffert: Alles wird direkt und sofort geschrieben/gelesen, Gepuffert: es wird in Blöcken geschrieben gelesen, im Falle von Stdin/Stdout bei einem Newline (das Buffering man aber abschalten, wenn man sich auskennt!). 72.3 Die drei Standard-Ströme, und deren Eigenschaften Diese Ströme sind immer geöffnet außer man schließt sie absichtlich. Stdin = Standard Input (Terminal oder Piping von der Shell, Terminal-Eingabeeinheit kann in dem Fall meisten die Tastatur (meistens), das sendende Modem am anderen Ende der Leitung oder ein Fernschreiber sein) Stdout = Standard Output (Terminal oder Piping von der Shell, Terminal-Ausgabeeinheit kann in dem Fall ein Bildschirm (meistens), ein empfangendes Modem am anderen Ende der Leitung, ein Drucker oder auch ein Fernschreiber sein - je nach Konfiguration, ) Stderr = Das gleiche wie Stdout, nur ein anderer Strom, kann somit extra/getrennt in eine andere Datei umgeleitet werden 73Was darf in Headerdateien drinstehen und was nicht? Drinnen stehen darf prinzipiell alles, aber es sollte (laut Konvention) kein Programmcode sein. Drinnen stehen sollten Struct-Definitionen, Funktionsdeklarationen, Konstanten, ... - vielleicht auch grosse Arrays mit HEX-Werten (?). Sinn der Sache ist, dass man zu vorkompilierten Librarys die Deklarationen hat und somit die Funktionen aufrufen kann und dass Code und "Design" etwas getrennt sind. Kurz: In Headerdateien steht alles drin was keinen Speicherplatz verbraucht (Variablendeklarationen, Funktionendeklarationen aber keine Variablendefinition den die verbraucht ja Speicherplatz) 74Wie werden Gleitkommazahlen dargestellt 74.1 Welche Datentypen gibt es? float, double, long double "float" => Edit: Kleinster Fliesskomma-Datentype (meistens 32 Bit) "double" => Edit: Nächstgrösserer Fliesskomma-Datentyp (meistens 64 Bit) "long double" => Edit: Grösser oder gleich double. 33 ©CVD Vil 74.2 Wieviele Nachkommastellen haben die Datentypen genau? float >6 Nachkommastellen double >10 Nachkommastellen long double >10 Nachkommastellen 75Unterschied Programm / Algorithmus Das Programm ist eine Erscheinungsform des Algorithmus. Ein Algorithmus muss sich nicht genau an eine formale Programmier-Syntax halten, man kann einen Algorithmus auch in deutscher Sprache beschreiben. Ein Algo muss eine endlich lange Beschreibung (Akademiker-Speech: "Finitheit") haben, alle Schritte müssen auch ausführbar sein ("Effektivität"), er muss bei gleichen Eingaben auch gleiche Ausgaben liefern ("Deterministisch") und er muss nach einer bestimmten Zeit zu einem Ergebnis kommen ("Terminierung"). Syntax = Formale Vorschriften, also welche Keywords, welche Operatoren Semantik = Bedeutung, also wo welche Operatoren erlaubt sind, wo sie Sinn machen 76Was ist eine Spezifikation? Prinzipielle Antwort darauf: Eine Beschreibung des Problems/Aufgabenstellung bzw. des Projekts. Beschreibt das Programm/Projekt/System/Gerät/... von aussen (also die "Leistungen" des Projekts), ohne auf Realisierung einzugehen. Also nur "Bei welchen Eingaben in welcher Form von welchem System soll mein Projekt welche Ausgaben in welcher Form an welches System übergeben". 77Was ist ein Bitfeld und wofür wird es verwendet? Ein Bitfeld ist eine int festlegbarer Bitlänge und ist in einer Struktur drinnen. Man verwendet es um Speicherplatz zu sparen, oder wie im Buch steht um "Hardwareregister nachzubilden" (wo die Bits oft exakt angeordnet werden müssen), sag vielleicht noch dazu, dass es meistens in Mikrokontrollern verwendet wird. Ausserdem kannst du noch anführen, dass man so manchmal Flag-Variablen/Zustandsflags realisiert. 78Was ist ein Assembler? Ein Assembler übersetzt Mnemonics (Opcodes+Operand) in Maschinensprache. C-Compiler erzeugen mitunter Assembler-Zwischenausgaben (nicht alle, manche neueren erzeugen auch gleich direkt die Objektdatei) 34 ©CVD Vil 79Wenn Sie eine Funktion haben, und Sie möchten mehrere Objekte zurückgeben, zum Beispiel (a+B) und (a-B), wie machen Sie das? Die zwei Werte, oder auch wenn es ein Array ist das Array in ein Struct verpacken, da das Struct als ein Objekt zählt (und C kann nur 1 Objekt zurückgeben) 80Ein Operator der wie eine Funktion ausschaut? Sizeof: Ermittelt den Speicherbedarf von Variablen bzw Datentypen Ein operator, der eigentlich wie eine funktion verwendet wird 80.1 Woran man das es sich nicht um eine Funktion handelt? Man kann auch einen Datentyp selbst übergeben 81Wozu dient die Parameterliste in snprintf? wichtig war hier zu sagen, dass man snprintf und nicht strcpy verwendet, weil man 1. dort die anzahl der zeichen festlegen kann (und somit nicht über die feldgrenzen hinausgeschrieben wird) 2. da man eine formatierte ausgabe hat (weiß nicht, ob der ausdruck so stimmt, das hat ihm nicht ganz gefallen). gemeint ist, dass man wie bei printf platzhalter für variablen verwenden kann. 82Was muss das x in scanf("%ld",x) sein? 1. >> eine adresse 2. was ist das "%ld" (also das string-literal selbst, nicht der platzhalter) >> konstanter string auf ein anonymes feld von zeichen 83Wie kann man einen Pointer ausgeben? %pointer 35 ©CVD Vil 84Switch-case: was passiert, wenn im Ausdruck eine Punktzahl herauskommen kann? Compiler wird warnen, da nur ganze Zahlen und Zeichen als Labels bei den case-zweigen zulässig sind 85Wie errechnet sich die Genauigkeit bei Punktzahlen? log(2^(bitbreite der mantisse)) , zehnerlogarithmus bei float: log(2^23)) = 6,9 ~ 7 stellen, bei double: ~15 stellen 86Dreieckspointer Dreieckstausch mit Pointer. Man verwendet eine Hilfsvariable um die Werte zu tauschen. 87Was kann man mit struct besonderes machen? a=b. Der Zuweisungsoperator funktioniert bei Strukturen, d.h. du kannst mit z.B. s1=s2; eine Struktur direkt einer anderen zuweisen. Alle anderen Operatoren kannst du nur auf die Attribute von Strukturen anwenden. Man kann Strukturen als Rückgabewert von Funktionen haben. Der Grund ist, dass eine Struktur in C als "eine Variable" gilt. 88Wie kann man einen Zeiger als Konstante definieren? 1. double const ptr 2. Feldnamen können als konstante Zeiger (Zeiger-Feld-Dualität!) verwendet werden 89Was bedeutet "void"? Wann wird das verwendet? Nichts - wird verwendet wenn bei einer Funktion nichts zurückgegeben werden soll void-Pointer gibt es auch, das sind "generische" Pointer die keinen bestimmten Datentyp haben und umgehend richtig "gecasted" werden müssen 36 ©CVD Vil 90Wie darf der Name einer Variable ausschauen? • eine C Funktion oder Variable beginnt mit einem Buchstaben oder "_" dem UnderscoreZeichen • Namen von C Funktionen oder Variablen dürfen dann weiterhin Buchstaben, Zahlen und den "_" Underscore enthalten. Alles andere Sonderzeichen, Umlaute etc ist verboten. • Der Name der Variablen darf sich nicht mit einem C Schlüsselwort decken, z.B. main ist als Variablenname verboten • Namen sind "case-sensitiv" also Groß- und Kleinschreibung beachten. • Die maximale Länge des Namens ist abhängig vom Compiler, meistens jedoch 256 Zeichen. 91Welche Objekte muss man immer initialisieren? Konstante. 92Funktioniert eine switch Anweisung auch mit Gleitkommazahlen ? Nein 93Wie viele Bits besitzt long? Die Anzahl an bits in einem long hängt von der Rechnerarchitektur ab ( 32 bit, oder 64 bit), und ist NICHT immer 32 bit 94Warum existiert der Datentyp float in C eigentlich, warum verwendet man nicht immer ein double? Float wird heute hauptsächlich dort verwendet, wo es sich mehr "auszahlt" Speicher zu sparen oder schneller zu rechnen statt genau zu rechnen. 95Was steht in einer Header-Datei? Prinzipiell sollten (laut Konvention) darin nur Funktionsprototypen und Deklarationen, jedoch kein ausführbarer Code stehen! Drinnen stehen kann jedoch alles, da die Header-Datei einfach so wie sie ist vom Präprozessor in das Programm eingebunden wird, bevor dieses dem Compiler übergeben wird. 37 ©CVD Vil 96Welche zwei Arten von Header-Dateien gibt es? 1. Library/Bibliotheks-Headerdatein welche System-Headerdateien sind und mittels spitzer Klammern eingebunden werden, da sie sich in einem Verzeichnis, das dem Compiler bekannt ist befinden → #include <math.h> 2. Benutzer/User-Headerdateien welche der Programmierer zu Zwecken der Übersichtlichkeit selbst geschrieben hat und mittels Anführungszeichen eingebunden werden, da sie sich meistens im selben Verzeichnis wie die C-Quelldateien befinden → #include "main.h" 97Was muss erfüllt sein damit ein Algorithmus funktioniert? Es muss ausgetestet werden ob er funktioniert. • 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. 98Was ist ein Datentyp? Ein Datentyp ist eine Definitionsmenge von Daten inklusive aller Operationen und Funktionen, die auf dieser Menge definiert sind. Es gibt zwei Arten von Datentypen: 1. Reale Datentypen 2. Mathematische Datentypen 38 ©CVD Vil 99Wozu benötigt man die Continue-While Anweisung? Wenn man verschiedene if Abfragen hintereinander stehen hat kann man die Abfragen ausführen und die Schleife verlassen sobald eine if Abfrage gültig ist ohne die weiteren ausfühewn zu müssen Man kann damit if Anweisungen die dann noch kommen einfach überspringen 100 If Anweisung erklären wenn in der Bedingung a=b steht Das Ergebnis der Zuweisung ist das Ergebnis der Berechnung und somit der Wert von b. 39 ©CVD Vil