Welche Aufgaben erfüllt der Präprozessor?
Dieser Teil des C-Compilers bearbeitet die Anweisungen, die mit einem # beginnen und dient hauptsächlich der
♦ Texteinfügung (Einbindung der Headerdateien),
♦ Ersetzung (Ersatz symbolischer Konstanten) und
♦ Makros zu bearbeiten.
Welche Vorteile weisen Makros auf?
Durch die Verwendung von Makros werden C++-Programme transparenter und flexibler.
Es ergeben sich nämlich mehrere wesentliche Vorteile
♦ Gute Lesbarkeit:
Der Name eines Makros kann so gebildet werden, dass er einen Hinweis auf die Bedeutung enthält.
♦ Änderungsfreundlichkeit:
Soll z. B. der Wert einer Konstanten überall im Programm geändert werden, so muss bei einer symbolischen Konstanten nur der Wert in der #define-Direktive ersetzt werden.
Erklären Sie die folgenden Präprozessor- Direktiven Syntax:
a) #include <dateiname>
b) #include “dateiname“
a) Die #include <dateiname> Include-Direktive:
Sucht die angegebene Datei in einem voreingestellten Pfad. Dieser Pfad wird in der Regel durch die Entwicklungsumgebung (IDE = Integrated Development Environment) festgelegt. Header- Dateien die mit dem Compiler ausgeliefert werden (zB cmath & iostream), werden in der Regel durch diese Include-Form eingebunden.
b) Die #include “dateiname“ Include-Direktive:
Sucht die angegebene Datei zuerst in dem Verzeichnis, in dem sich die Datei befindet, die die Include-Direktive enthält. Wird die einzubindende Datei dort nicht gefunden, wird wieder im voreingestellten Include-Pfad nach der Datei gesucht. Diese Form wird hauptsächlich für eigene einzubindende Dateien verwendet. Der Name dateiname kann Pfadangaben enthalten. In diesem Fall wird nur in dem entsprechenden Directory gesucht.
Es soll der Wert einer Konstanten (zB 3.1415926536 =π) überall im Programm geändert werden.
Geben die Syntax der Präprozessor-Direktive an.
Syntax: #define name Ersatztext
Beispiel: #define PI 3.1415926536
Erklären Sie Anhand eines Beispiels (CUBE a*a*a) der Aufruf von parametrisierten Makros.
Es ist möglich, Makros mit Argumenten aufzurufen.
Dazu müssen bei der Definition entsprechende Parameter angegeben werden.
Das sind Platzhalter, die beim Aufruf des Makros durch die aktuellen Argumente ersetzt werden.
Beispiel #define CUBE(a) ((a) * (a) * (a))
Das Beispiel (CUBE a*a*a) soll nur in einem Teilprogramm gültig sein. Geben die Syntax der Entfernung der Definition an.
#define MIN(a,b) ((a)<(b)? (a) : (b) )
.... //Hier kann MIN aufgerufen werden
#undef MIN
Warum führen folgende folgenden Anweisungen zu Syntaxfehlern?
#define SQR (a) ( a * a)
#define AUSGABETEXT "Der Grenzwert ist bald erreicht, bitte "
"folgende Anweisungen duerchfuehren."
#define SQR_(a) ( a * a) /* fuehrt zu Syntaxfehler */
#define AUSGABETEXT "Der Grenzwert ist bald erreicht, bitte " \
"folgende Anweisung duerchfuehren."
Ergänzen Sie das folgende Beispiel mit Verzweigungsdirektiven, die je nach Wert dazu führen, dass verschiedenen Texte ausgegeben werden.
#define MAX 30
char array[MAX];
int main() {
cout << "kleines Feld";
cout << "30er-Feld";
cout << "mittleres Feld";
cout << "grosses Feld";
cout << endl;
}
#if MAX<10............
#elif MAX == 30............
#elif MAX < 50............
#else ............
#endif ............
Welche Bedeutung haben die:
a) #error-Direktiven,
b) #pragma-Direktiven?
a) #error-Direktive:
können Fehlermeldungen des Präprozessors angezeigt werden.
b) #pragma-Direktive:
sind compilerabhängig.
Sie erlaubt die Definition von beliebigen Präprozessor-Befehlen für einen bestimmten Compiler.
Geben Sie die Definition des Gültigkeitsbereichs von globalen und lokalen Variablen an.
Der Gültigkeitsbereich einer globale Variable ist von ihrer Deklaration ab und bis zum Ende des Programms gültig.
Der Gültigkeitsbereich einer lokalen Variable ist auf den Block beschränkt, in dem die Variable deklariert ist, außerhalb dieses Blocks kann auf die Variable weder lesend noch schreibend zugegriffen werden.
Was verstehen Sie unter dem Begriff „Verschattung oder hidden“ einer globalen Variablen?
Beim Überschatten überschattet/verdeckt eine Variable mit dem selben Namen eine andere weil sie in einem höheren Geltungsbereich liegt und den Zugriff auf die untere Variable dadurch verhindert.
Wenn in einem Block eine globale Variable neu deklariert wurde, gilt innerhalb des Blocks der wert der lokalen Variable.
Welche Nachteile ergeben sich, wenn eine Funktion als Parameter eine zweite Funktion übernimmt, die einen Wert zurückgibt?
Obwohl es zulässig ist, dass eine Funktion als Parameter eine zweite Funktion übernimmt, die einen Wert zurückgibt, kann man einen derartigen Code schwer lesen und kaum auf Fehler untersuchen.
Welche Vorteile weist die dynamische Speicherbelegung auf?
Mit Hilfe dynamischer Variablen, die nach Bedarf erzeugt und auch wieder gelöscht werden können, lassen sich Probleme variabler Größe sehr viel besser lösen.
Geben Sie die Syntax der Deklaration eines Zeigers sowie der Definition an.
Die Deklaration eines Zeigers erfolgt mit dem
„Indirektions-Operator“ –
ein Sternchen: int *zeiger;
Definition: int *zeiger = &anzahl;
Was verstehen Sie unter dem Begriff „Wilde Zeiger“?
Wenn die Definition nicht durchgeführt wird.
Welche Vor – und Nachteile ergeben sich beim Arbeiten mit dem Heap Speicher.
„Heap“, auch „Freispeicher“ : Damit bestimmen Sie selbst, wie lange eine Variable leben soll – was Vor- und Nachteile hat!
Geben Sie die Syntax für die Reservierung, die Nutzung und die Freigabe einer Heap-Speicherstelle an.
Heap-Reservierung: int *adr = new int; Das Schlüsselwort „new“ kennzeichnet einen Heap-Speicher;Rückgabewert der Aktion ist die Adresse der Heap-Speicherstelle. Heap-Speicher nutzen: *adr = 4711; // also vollkommen unveränderte Syntax Heap-Speicher freigeben:Noch bevor der Codeblock geschlossen wird, müssen Sie aktiv werden und den Speicherbereich wieder löschen: delete adr;
Ergänzen das folgende Programm so, dass die Funktion
Volumeberechnug(), laenge*breite*hoehe, einen Wert vom Typ int zurückgibt und drei int- Parameter übernimmt. Wenn kein Argument übergeben wird, sollen die Standardwerte (Breite =50 und Höhe= 75) verwendet werden. Alle möglichen Fälle sollen auf der Konsole ausgegeben werden.
/*Volumeberechnung*/
#include <iostream>
using namespace std;
int VolumeCube(int length, int width = 50, int height = 75);
// Standartwerte für width 25 und height 1
int length = 100;
int width = 50;
int height = 2;
int volume;
volume = VolumeCube(length, width, height);
cout << "Erstes Volumen gleich: " << volume << "\n";
volume = VolumeCube(length, width);
cout << "Zweites Volumen gleich: " << volume << "\n";
volume = VolumeCube(length);
cout << "Drittes Volumen gleich: " << volume << "\n";
system ("pause");
return 0;
int VolumeCube(int length, int width, int height) {
return (length * width * height);
Definieren Sie für die Class Konto einen Konstruktor, der ein Konto eröffnet und einen Destruktor, der das Konto löscht.
#include <cstdlib>
class Konto {
public: double kontostand;
Konto(); //Konstruktor als Methode
~Konto();//Destruktor void standAuslesen();
};
Konto::Konto() //Konstruktor implementieren
{ kontostand = 0; cout << "Konto wird eroeffnet!" << endl; }
Konto::~Konto() // Implementierung Für den Destruktor { cout << "Konto wird geloescht!" << endl; }
void Konto::standAuslesen() { cout << "Kontostand: " << kontostand << endl; }
Konto kto; kto.standAuslesen();
Was sind Pointer/Zeiger?
Speicheradressen in CPP
Pointer können auf Variablen zeigen. Wenn man sich diese Ausgeben lässt erhält man die Speicheradresse der Variable.
Über den Zeiger kann auch der Wert der <Variable geändert werden?
Statt Werte zu kopieren wird auf diese Verwiesen.
Bei größen Werten ist dies deutlich schneller.
Nennen Sie die Vorteile von Makros
Gute Lesbarkeit: Der Name eines Makros kann so gebildet werden, dass er einen Hinweis auf die Bedeutung enthält.
Änderungsfreundlichkeit bei Makros: Soll z. B. der Wert einer Konstanten überall im Programm geändert werden, so muss bei einer symbolischen Konstanten nur der Wert in der #define-Direktive ersetzt werden.
Der Source-Code bleibt relativ kurz und damit übersichtlich.
Alles, was zusammengehört, bildet eine Einheit.
Die Wiederverwendbarkeit wird verbessert.
Nur veränderte Programmteile müssen neu übersetzt werden.
Was ist der unterschied zwischen einer a) Funktion und einem b) Makro?
a) Funktion
int area(int l, int h) {
return l * h;
Bei jedem Funktionsaufruf springt Programm nach oben zur Funktion
b) Makro
#define AREA(l,h) l * h
Makro dagegen wird immer neu in den Quelltext kopiert.
Macht das Programm schneller aber auch größer.
Geben sie a) Definition eines Makros mit Parametern an.
b) erklären wie der Präprozessor den Ersatztext mit den aktuellen Argumenten einsetzt
a) #define QUADRAT(a) ((a) * (a))
b) z = QUADRAT (x+1);
Führt zu -> z = ((x+1) * (x+1)) ;
Was verstehen Sie unter dem Begriff „Neudefinition von Makros“?
Zur Neudefinition wird die #undef-Direktive benötigt.
Danach kann das Makro neu definiert werden.
Erklären sie die Bedeutung der Präprozessor‐Direktive # ifdef
Mit # ifdef können Sie abfragen, ob ein bestimmter name definiert ist oder nicht.
Ist der Name definiert, so übernimmt der Präprozessor alle Anweisungen die zwischen der # ifdef Direktive und der zu ihr dazugehörigen #endif Direktive stehen
#ifdef name
// Block, der kompiliert wird
#endif
Geben Sie ein Beispielprogramm mit den Verzweigungen: if, elif, else und endif Direktive an.
#if Feld <10
#elif Feld == 10
cout << "10er-Feld";
#elif Feld < 50
#else cout << "grosses Feld";
WIe unterscheidet sich der Code der a) Definition und b) Deklaration einer Funktion?
a) Definition einer Funktion:
<Typ R> <Name>( <Typ P1> <Name P1>, . . . )
{
<Programmcode>
b) Deklaration einer Funktion:
<Typ R> <Name>( <Typ P1> <Name P1>, . . . );
Nennen die zwei Attribute einer Variablen und erklären Sie deren Bedeutung.
Alle Variablen haben zwei Attribute, den
♦ Gültigkeitsbereich (scope) und
♦ die Speicherklasse (storage class).
Nennen Sie die Eigenschaften von Funktionen.
Eigenschaften von Funktionen:
♦ Jedes Programm muss eine Funktion main() enthalten, die beim Programmstart
ausgeführt wird.
♦ Jede Funktion kann als Teil des Programmablaufs andere Funktionen aufrufen.
♦ Beim Aufruf einer Funktion können dieser Daten (Parameter) übergeben werden.
♦ Anschließend gibt die aufrufende Funktion die Ablaufkontrolle an die aufgerufene
Funktion ab.
♦ Ist die aufgerufene Funktion beendet, so übergibt sie der aufrufenden Funktion
einen Rückgabewert, den die aufrufende Funktion verwenden kann.
♦ Anschließend macht die rufende Funktion an der Stelle nach dem Aufruf der Funktion weiter.
Was ist an der Anweisung:
Result = (double(triple(square(cube(meinWert)))));
problematisch.
Man kann nur schwer erkennen, was dieser Code bewirkt.
Undurchsichtig.
Erklären Sie den Unterschied zwischen direkter und indirekter Rekursion.
Eine Funktion kann sich auch selbst aufrufen. Dies wird als Rekursion bezeichnet, die sowohl direkt als auch indirekt erfolgen kann.
Eine direkte Rekursion liegt vor, wenn eine Funktion sich selbst aufruft.
Eine indirekte Rekursion liegt vor, wenn eine Funktion eine andere Funktion aufruft, die dann wieder die erste Funktion aufruft.
Geben Sie die Syntax (mit Methoden und Variablen) einer Class an.
class <klassenname>
<datentyp><datenbezeichner>;
<funktionstyp><funktionsname(parameter...)>
<Anweisungen der Funktion>
Wie lässt sich ein Objekt einer Class anlegen?
Bsp. Student
class student Student_1;
Was verstehen Sie unter „Vererbung“?
Unter „Vererbung“ versteht man die Ableitung neuer Klassen von einer vorhandenen „Basisklasse“. Dabei „vererbt“ die Basisklasse ihre Eigenschaften an die neue abgeleitete Klasse zusätzlich zu den in der abgeleiteten Klasse neu definierten Elementen.
Was versteht man unter “Überladen”?
Man kann mehrere Funktionen desselben Namens im gleichen Bereich angeben.
Diese Funktionen werden als überladene Funktionen oder Überladungen bezeichnet
Durch welche objektorientierten Konzepte unterstützt die OO‐Software das Erstellen von komplexen Klassen
Vererbung und
Aggregation
Definieren Sie Vererbung und Aggregation
Vererbung
o Kann eine Objektklasse duplizieren und dann verfeinern.
o Beschreibt die Beziehung zwischen der allgemeinen Klasse (Basisklasse) und einer abgeleiteten Klasse.
o mehrere einzelne Klassen können zu einer komplexen Klasse zusammengefasst werden.
Worin liegt der Vortei von Klassen?
Mit einmal getestete Klassen lassen sich nach dem Baukastenprinzip zu hochkomplexen Programmstrukturen zusammenfügen.
Mit Klassen ist es möglich, neue Ausprägungen von Maschinenteilen mit minimalem Programmieraufwand umzusetzen.
Welche Vorteiel bieten objektorientierter Methoden in der Automatisierungssoftware?
Vorteile:
‐ Abbildung von realen Maschinenkomponenten durch Softwareobjekte.
‐ Getestete Funktionsbausteine dank Kapselung „use and forget“. Die Bausteine einfach in Libraries aufbewahrt werden.
‐ Wiederverwendbarkeit der erstellten Funktionsbausteine und des Quellcodes.
‐ Klare, grafische sichtbare Schnittstellen nach außen.
‐ Vereinfachtes Arbeiten in Teams.
Nennen Sie beispielhalt Eigenschaften für die Class Auto.
‐ vier Räder,
‐ einen Motor,
‐ einen Benzintank,
‐ Farbe und Anzahl der Sitze.
Erkläre Datenkapselung
Ein Konzept, das den Zugriff auf bestimmte Daten in einem Programm beschränkt.
Die Umsetzung erfolgt durch die Verwendung von "privaten" Eigenschaften und "öffentlichen" Funktionen, die als "Getter" und "Setter" bezeichnet werden.
Wie unterscjeiden sich Private, Protected und Public Daten?
Den Grad der Datenkapselung.
‐ Public: Eigenschaften und Methoden auf die von extern zugegriffen werden sollen, werden als public bezeichnet.
‐ Protected: Nur innerhalb der Klasse selbst und aus Subklassen dieser Klasse kann auf die in diesem Teil zugegriffen werden.
‐ Private: Eigenschaften und Methoden/Funktionen die nur intern genutzt werden, werden private genannt.
Lebe eine Klasse vom Typ Student an.
class Student {
public:
char name[20];
long int mat_nr;
int fachbereich;
void set_anzahl(int anzahl) {
anzahl_lv = anzahl; }
void set_notenschnitt(float schnitt) { noten_mittel = schnitt; }
void neuer_schein(float note) {
float sum = noten_mittel*anzahl_lv; noten_mittel = (sum + note)/(anzahl_lv+1); anzahl_lv++; }
int zeige_anzahl() {
return anzahl_lv; }
float zeige_notenschnitt() {
return noten_mittel;}
private:
int anzahl_lv;
float noten_mittel;
Last changed2 years ago