C Programmierung - Klausurvorbereitung

Hallo zusammen! :smile:

Unten stehend habe ich alle Aufgaben der Probeklausur (Aufg. 5 - 15), die ich nun schon gelöst habe, aufgeführt. Ich wäre dankbar, wenn ihr meine Ergebnisse / Antworten kurz kontrollieren könntet.

Aufg. 9: Ist bekannt (mein erster Post hier im Forum).

Aufg. 11: Ich bin mir nicht sicher, ob ich den Unterschied von Deklaration und Definition von Funktionen richtig verstanden habe. :confused:

Die Deklaration ist quasi der Funktionsprototyp und die Definition die Funktion selbst?

Aufg. 13: Pre-Inkrement und Post-Inkrement…

Finde ich persönlich sehr verwirrend. Die Aufgabe habe ich schlicht durch ausprobieren gelöst!

Vielen Dank vorab und liebe Grüße! :smile:

Orchidee

_ _ _ _ _

Aufg. 5

Im Code steht die Definition:

int meine Variable;

a)Beim Programmstart wird in jedem Fall der Speicher für die Variable bereitgestellt.

wahr / falsch

wahr: Die Variable wurde deklariert/definiert, wodurch der Compiler Speicherplatz für eine integer-Variable reserviert.

b)Die Bereitstellung des Speichers ist an die Lebensdauer der Variablen geknüpft.

wahr / falsch

wahr: Lokale Variable sind automatische Datenobjekte, welche beim Start einer Funktion automatisch erstellt und bei ihrem Verlassen ebenso wieder zerstört werden. Der zuvor reservierte Speicherplatz wird hierauf für andere Zwecke freigegeben.

c)Wenn es sich um eine lokale Variable in einer Funktion handelt, dann wird bei jedem Aufruf der Funktion der selbe Speicherplatz verwendet.

wahr / falsch

falsch: Lokale Variable sind automatische Datenobjekte. Die Variable erhält bei jedem Funktionsstart einen anderen Speicherplatz.

Aufg. 6

Sie möchten sicherstellen, dass eine Variable bei Verwendung nicht undefiniert ist. Nennen Sie 2 Möglichkeiten, wie Sie dies erreichen können.

Variable definieren: int a;
Variable als statische Variable definieren: static int a;
Variable als globale Variable, außerhalb der versch. Funktionen, definieren: int a;

Aufg. 7

Beschreiben Sie, was bei der Code-Erzeugung passiert, wenn im Quelltext das folgende steht:

#define MAX 5
int feld[MAX];

Mit der Präprozessor-Anweisung #define wird dem symbolischen Namen (MAX) eine Konstante (5) zugewiesen. Der Präprozessor ersetzt überall im Quellcode den symbolischen Namen (MAX) durch die Konstante (5).

Durch int feld[MAX] wird ein Array mit 5 Elementen deklariert und initialisiert.

Aufg. 8

Nennen Sie 3 Arten von Fehlern, die Sie bei der Benennung und Initialisierung von Variablen machen können.

Falsche Namensvergabe: int !xy! = 5;
Datentyp und Wert passen nicht zusammen: int a = 3.5;
Semikolon vergessen: int a = 5

Aufg. 9

Wie lauten die Prototypen folgender Funktionen?

a)Die Funktion compose liefert eine null-terminierte Zeichenkette, die aus drei übergebenen Zeichen erzeugt wird.

char * compose(char a, char b, char c);

b)Die Funktion maxFeld besitzt zwei Felder von double-Zahlen und gibt entweder 1 oder 2 zurück.

int maxFeld(double, double);

(Achtung: Welche Argumente benötigen diese Funktionen?)

Aufg. 10

Ein C-Programm ruft die Standardfunktion sqrt auf. Dazu

a)wird die Header-Datei stdlib.h inkludiert

wahr / falsch

falsch: Die Funktion sqrt (Quadratwurzel aus positiven Zahlen) setzt das Einbinden von math.h voraus.

b)muss die richtige Header-Datei vor dem Aufruf von sqrt inkludiert werden.

wahr / falsch

wahr: Das Verwenden der Funktion sqrt setzt das Einbinden von math.h voraus.

c)muss unbedingt als erste Zeile die richtige Header-Datei inkludiert werden.

wahr/falsch

falsch: Es könnte wie folgt aussehen:

#include
#include
#include an 3. Stelle

Aufg. 11

Wenn eine Funktion aufgerufen wird,

a)dann muss sie zum Zeitpunkt des Bindens auch definiert sein.

wahr / falsch

wahr: Ohne die Definition der Funktion > kann der Compiler die Funktion nicht bearbeiten.

b)dann meldet der Compiler einen Fehler, wenn er die Definition der Funktion nicht findet.

wahr / falsch

wahr

c)dann kann die Deklaration mit #undef rückgängig gemacht werden.

wahr / falsch

falsch: Mit #undef werden entweder symbolische Konstanten oder Makros aufgehoben, nicht aber Funktionen.

Aufg. 12

Ein C-Programm liest mit scanf das Alter des Anwenders in eine int-Variable ein. Sie möchten fehlerhafte Eingaben (z.B. die Eingabe von „[]“ im Programm erkennen und abfangen).

a)Das geht nicht. Das Programm stürzt ab.

wahr / falsch

falsch: Wenn [] anstatt des Alters eingegeben wird, stürzt das Programm nicht ab. Gem. unten stehendem Bsp. (b) würde 0 ausgegeben werden. Wurde die Variable, in welcher das Alter gespeichert wird, zuvor nicht initialisiert, erscheint ein zufälliger Wert.

b)Sie verwenden den Rückgabewert von scanf.

wahr / falsch

wahr: Unter der Voraussetzung, dass es sich nicht um einen „zufälligen“ Rückgabewert handelt. Die Variable gem. unten stehendem Bsp. wurde zuvor initialisiert.
_ _ _

int alt = 0;

printf(„Bitte geben Sie das Alter ein:\n“);
scanf("%i", &alt);

if (alt>0&&alt 0 || i-- c

b)Genau ein Wert von a und b ist kleiner als c, aber nicht beide

a

Schon ein: GUT
Hi

Habe jetzt nicht viel Zeit investiert, aber bei 11b und 14 hätte ich anders geantwortet.

Ciao, Allesquatsch

Howdy,

also vorab schon mal. Genauso unprofessionell, wie die schon genannten Fragen geht es hier weiter. Man darf wohl davon ausgehen, dass der Klausursteller kein Informatiker ist. Das Problem dabei ist, dass der Aufgabensteller Antworten nach seinem Wissensstand moechte und die koennen schon ab und zu von der Wahrheit abweichen.

Im Code steht die Definition:
int meine Variable;

Sprich, ihr sollt Aussagen zu einem inkorrektem Code abgeben?
Wenn ja, dann wird dafuer natuerlich kein Speicher bereitgestellt.

Gehen wir jetzt davon aus, dass „int meineVariable;“ gemeint war.
Dann stellt sich immer noch die Frage, ist das nun eine globale Variable oder eine innerhalb einer Funktion?

a)Beim Programmstart wird in jedem Fall der Speicher für die
Variable bereitgestellt.

wahr: Die Variable wurde deklariert/definiert, wodurch der
Compiler Speicherplatz für eine integer-Variable reserviert.

Ja fuer globale und statische Variablen, nein fuer auto Variablen innerhalb von Funktionen (also finale Antwort somit „falsch“).

Lokale auto Variablen vom Typ int koennen durchaus auch komplett in CPU Registern gehalten werden (dann muss ueberhaupt kein Speicher reserviert werden)

b)Die Bereitstellung des Speichers ist an die Lebensdauer der
Variablen geknüpft.

wahr: Lokale Variable sind …

In C ja, in C++ nein. Erklaerung hier nur fuer lokale Variablen nicht notwendig (wobei auch nicht korrekt ist, dass lokale Variable immer auto sind) und unter der Voraussetzung, dass ueberhaupt Speicher bereitgestellt wurde.

c)Wenn es sich um eine lokale Variable in einer Funktion
handelt, dann wird bei jedem Aufruf der Funktion der selbe
Speicherplatz verwendet.

falsch: Lokale Variable sind automatische Datenobjekte. Die
Variable erhält bei jedem Funktionsstart einen anderen
Speicherplatz.

Fuer statische Variablen innerhalb der Funktion wird immer derselbe Speicherplatz verwendet, fuer auto nicht notwendigerweise. Die Aussage „erhaelt bei jedem Funktionsstart einen anderen Speicherplatz“ ist aber auch falsch.

Aufg. 6

Sie möchten sicherstellen, dass eine Variable bei Verwendung
nicht undefiniert ist. Nennen Sie 2 Möglichkeiten, wie Sie
dies erreichen können.

Variable definieren: int a;
Variable als statische Variable definieren: static int a;
Variable als globale Variable, außerhalb der versch.
Funktionen, definieren: int a;

Die Frage ist deshalb kniffelig, weil es zwei Moeglichkeiten gibt, welche der Klausursteller hier meinen koennte: undefined identifier und undefined value.

Da er aber schreibt „bei Verwendung“ ist anzunehmen, dass er undefined value meint, denn einen „undefined identifier“ kann man per se nicht verwenden.

Ziel m.M. nach also, dass die Variable einen Wert hat, also ihr etwas zugewiesen wurde. Das kann auch implizit, z.B. bei statischen Variablen passieren. Und es haengt vom Platz der Definition ab. int a; global ist initialisiert, waehrend int a; innerhalb einer Funktion nicht initialisiert ist.

Sollte er wider Erwarten „undefined identifier“ meinen, dann sind deine Angaben korrekt.

Aufg. 7

Beschreiben Sie, was bei der Code-Erzeugung passiert, wenn im
Quelltext das folgende steht:

#define MAX 5
int feld[MAX];

Mit der Präprozessor-Anweisung #define wird dem symbolischen
Namen (MAX) eine Konstante (5) zugewiesen. Der Präprozessor
ersetzt überall im Quellcode den symbolischen Namen (MAX)
durch die Konstante (5).

Durch int feld[MAX] wird ein Array mit 5 Elementen deklariert
und initialisiert.

Wiederum: falls int x[5]; innerhalb einer Funktion definiert wird, so ist es nicht initialisiert.

Aufg. 8

Nennen Sie 3 Arten von Fehlern, die Sie bei der Benennung und
Initialisierung von Variablen machen können.

Falsche Namensvergabe: int !xy! = 5;
Datentyp und Wert passen nicht zusammen: int a = 3.5;
Semikolon vergessen: int a = 5

Redefinition: Es gibt ein globales x und ein weiteres lokales x (und man hat nach der Definition des lokalen x ggf. keinen Zugriff auf das globale x mehr)
Keyword mismatch: Man versucht eine Variable wie ein Keyword zu benennen: int for = 5;
Naming: int zähler = 10;

Aufg. 10

Ein C-Programm ruft die Standardfunktion sqrt auf. Dazu

a)wird die Header-Datei stdlib.h inkludiert

wahr / falsch

falsch: Die Funktion sqrt (Quadratwurzel aus positiven Zahlen)
setzt das Einbinden von math.h voraus.

Nein, mit stdlib.h wird sqrt() nicht bekannt gemacht.
Mit math.h kann man sqrt() bekannt machen, muss man aber nicht.

b)muss die richtige Header-Datei vor dem Aufruf von sqrt
inkludiert werden.

wahr / falsch

wahr: Das Verwenden der Funktion sqrt setzt das Einbinden von
math.h voraus.

Nein, denn man koennte in seinem Code den Prototyp auch selber
schreiben, also vor Benutzung von sqrt() z.B.

extern double sqrt(double);

c)muss unbedingt als erste Zeile die richtige Header-Datei
inkludiert werden.

wahr/falsch

falsch: Es könnte wie folgt aussehen:

#include
#include
#include an 3. Stelle

yep.

Aufg. 11

Wenn eine Funktion aufgerufen wird,

a)dann muss sie zum Zeitpunkt des Bindens auch definiert sein.

wahr / falsch

wahr: Ohne die Definition der Funktion > kann der Compiler die Funktion nicht bearbeiten.

Ja fuer richtige Funktionen, nein fuer Funktionen, die ueber Funktionspointer aufgerufen werden (diese koennen z.B. spaeter dynamisch geladen werden).

b)dann meldet der Compiler einen Fehler, wenn er die
Definition der Funktion nicht findet.

wahr / falsch

wahr

Unter der Annahme, dass der Aufgabensteller bei 11a ja erwartet, dann wahr.

c)dann kann die Deklaration mit #undef rückgängig gemacht
werden.

wahr / falsch

falsch: Mit #undef werden entweder symbolische Konstanten oder
Makros aufgehoben, nicht aber Funktionen.

yep.

Aufg. 12

Ein C-Programm liest mit scanf das Alter des Anwenders in eine
int-Variable ein. Sie möchten fehlerhafte Eingaben (z.B. die
Eingabe von „[]“ im Programm erkennen und abfangen).

a)Das geht nicht. Das Programm stürzt ab.

wahr / falsch

falsch: Wenn [] anstatt des Alters eingegeben wird, stürzt
das Programm nicht ab. Gem. unten stehendem Bsp. (b) würde 0
ausgegeben werden. Wurde die Variable, in welcher das Alter
gespeichert wird, zuvor nicht initialisiert, erscheint ein
zufälliger Wert.

yep.

b)Sie verwenden den Rückgabewert von scanf.

wo ist hier die Frage? Ja, in einem richtigen Programm verwendet man den Rueckgabewert (in dem Beispiel allerdings nicht)

wahr / falsch

wahr: Unter der Voraussetzung, dass es sich nicht um einen
„zufälligen“ Rückgabewert handelt. Die Variable gem. unten
stehendem Bsp. wurde zuvor initialisiert.
_ _ _

int alt = 0;

printf(„Bitte geben Sie das Alter ein:\n“);
scanf("%i", &alt);

if (alt>0&&alt 0 || i-- c

Nein. Da nicht spezifiziert ist, dass a immer kleiner als c ist, und b durch das Wort „zwischen“ durchaus den Wert a und c annehmen darf,
waere der gesuchte Ausdruck wohl eher
b = max(a,c)

wobei man min und max im Gegensatz zu C++ selbst programmieren muss.

b)Genau ein Wert von a und b ist kleiner als c, aber nicht
beide

a

sicher?

b)dann meldet der Compiler einen Fehler, wenn er die
Definition der Funktion nicht findet.

wahr / falsch

wahr

Unter der Annahme, dass der Aufgabensteller bei 11a ja
erwartet, dann wahr.

Meines Erachtens „falsch“, da nur die Deklaration der Funktion vorhanden sein muss, nicht aber die Definition. Beim statischen Binden im Linker ist das anders.

Ciao, Allesquatsch

Hi,

b)dann meldet der Compiler einen Fehler, wenn er die
Definition der Funktion nicht findet.

Meines Erachtens „falsch“, da nur die Deklaration der Funktion
vorhanden sein muss, nicht aber die Definition. Beim
statischen Binden im Linker ist das anders.

yep, da wurde von 11a vom Linker wieder zum Compiler gesprungen. Das hab ich ueberlesen.

Allerdings verbleibt hier die Frage, inwieweit die Studenten erklärt bekommen haben, dass der Compiler unter gewissen Umstaenden den Linker aufruft und das die Fehlermeldungen dann nicht vom Compiler erzeugt werden, z.B. in einem Programm x.c wie folgt:

int f();

int main()
{
 return f();
}

und cc x.c erhält man unter Linux

/tmp/cc8rMPE8.o: In function `main':
x.c:frowning:.text+0xa): undefined reference to `f'
collect2: ld returned 1 exit status

wobei der Student dabei wissen muss, dass ld der Linker/Binder ist.

Gruss
n.

Hallo n.,

/tmp/cc8rMPE8.o: In function main': x.c:frowning:.text+0xa): undefined reference to f’
collect2: ld returned 1 exit status

wobei der Student dabei wissen muss, dass ld der Linker/Binder
ist.

Ist heute alles etwas unübersichtlich geworden.
Die meisten Neulinge halten heute die IDE für den Compiler :frowning:

Den Linker kennen die meisten erst gar nicht.
Besonders bei der Entwicklung von Software für MicroController wird das tragisch, da musst man auch die Funktion von Cstartup kennen, welches dummerweise in Assembler geschrieben werden muss.

MfG Peter(TOO)

Guten Morgen! :smile:

vielen Dank für die vorherige Korrektur! :smile:

Ich habe noch einige weitere Fragen der Probeklausur bearbeitet und bitte erneut um eine kurze Kontrolle. :smile:
_ _ _ _ _

Vorab:

Aufg. 19 und Aufg. 22 habe ich noch nicht bearbeitet.

Bei Aufg. 21 d) gehe ich davon aus, dass der Wert 128 ist und somit €. Oder ist es -128, was ebenso zur Ausgabe von € führt? Bin mir hierbei wirklich nicht sicher… :confused:

Bei Aufg. 24 nehme ich an, dass ptr = 0 ist. ptr wurde ja nicht initialisiert aber andererseits würde ptr dann ja einen zufälligen Wert enthalten… Ich schätze, ich habe hier dezentes Chaos verursacht… :wink:

Aufg. 25 verstehe ich schlicht und ergreifen nicht. Dazu bin ich wohl zu blond… Welcher Code soll denn hier ergänzt werden? Der Einzeiler? Wisst ihr, was ich dort basteln soll?

_ _ _ _ _

Aufg. 16

n ist eine positive int-Variable. Schreiben Sie C-Code, der die Summe der ersten n Vielfachen (3) bildet.

Schreiben Sie zunächst die Summe für n = 4 aus!

Summe für n = 4: 1 * 4 + 2 * 4 + 3* 4 = 24
_ _ _ _ _

#include
#include

int main(int argc, char** argv) {

int i, anzahl = 3, zahl1 = 3, zahl2 = 0, summe = 0;

for (i = 1; i ==0) ? (x+x) : (x))
int z = 1;
int erg = AV(z++);

a) Schreiben Sie AV(1) aus:
b) Schreiben Sie AV(z) aus:
c) Schreiben Sie AV(z++) aus:
d) Geben Sie die Werte von erg und z an:

Aufg. 20

Bestimmen Sie die Werte der Variablen x nach den folgenden Zuweisungen:

int i = 3.0, j = 4.0;
double x;

a) x = i / j;

= 0.00

b) x = (double) i / j;

= 0.75

c) x = (double) (i / j);

= 0.00

d) x = i / (double j);

= Fehler

Nur > liefert das gewünschte Ergebnis aufgrund der richtigen Verwendung des casts.

Aufg. 21

Was macht der Code?

signed char x = 127; x++;

Der Code…

a) führt zu einer Fehlermeldung auf der Konsole, da der Wertebereich von signed char nur bis 127 reicht.

wahr/falsch

falsch: Es erscheint keine Fehlermeldung.

b) weist der Variablen c den Wert NaN zu, da die Funktionen in math.h dies unterstützen

wahr/falsch

falsch: NaN wird nicht ausgegeben.

c) weist der Variablen c den Wert 0 zu

wahr/falsch

falsch: 0 wird nicht ausgegeben.

d) weist der Variablen c den Wert -128 zu

wahr/falsch

falsch: Die Variable erhält den Wert 128, welcher gem. ANSI-Zeichensatz ein €-Zeichen darstellt, welches auch ausgegeben wird.

Aufg. 22

Gegeben sei der Prototyp

double doCalc (double *dPtr);

und ein Feld iArr von int Werten. Der Aufruf

double result = doCalc ( (double*) iArr ) );

a) führt zu einer Warnmeldung des Compilers, da ein iArr kein Zeiger auf eine double-Größe ist

wahr/falsch

b) übergibt der Funktion einen Zeiger. Die Bytes werden in der Funktion als double-Größe interpretiert

wahr/falsch

c) führt sicher zu einem Absturz zur Laufzeit

wahr/falsch

d) übergibt die Adresse des ersten Feldelements von iArr

wahr/falsch

Aufg. 23

Definieren und initialisieren Sie ein zweidimensionales Feld wie rechts angegeben:

11 12
21 22
0 0
0 0

int Feld [4] [2] = { 11, 12, 21, 22, 0, 0, 0, 0 } ;

Aufg. 24

Gegeben sei ein float-Zeiger ptr. Verwenden Sie sizeof, damit der folgende Ausdruck immer zu wahr ausgewertet wird

( (ptr + 42) == ptr + _____ * _____

( (ptr + 42) == ptr + sizeof(ptr) * 10,5 )

Aufg. 25

Eine Statusanzeige kann grün, gelb oder rot sein. Ergänzen Sie den Code, so dass er korrekt wird:



Status status = gruen;

Aufg. 26

In einer Funktion wird Speicher dynamisch beschafft und nur dem lokalen Zeiger ptr zugewiesen. Dann gilt:

a) Der Aufruf free(ptr) gibt den Speicher wieder frei

wahr/falsch

wahr

b) Mit der Anweisung ptr = 0; wird der Speicher freigegeben

wahr/falsch

falsch: Der Zeiger ptr wird durch die Zuweisung von 0 initialisiert.

c) Nach der Anweisung ptr = 0; kann der Speicherplatz nicht mehr freigegeben werden

wahr/falsch

wahr

d) Beim nächsten Aufruf der Funktion kann der Speicher freigegeben werden

wahr/falsch

wahr: Unter der Voraussetzung, dass die Initialisierung gem. b) nicht erfolgt.

Aufg. 27

Definieren Sie einen Typen Auto, der als Struktur ein Fahrzeug beschreibt. Ein Fahrzeug habe einen Hersteller, einen Typ, eine Fahrgestellnummer, einen Kilometerstand und ein Herstellungsdatum. Ergänzen Sie den Code und initialisieren Sie die Variable vom Typ Auto wie im Text angegeben.

Auto meinGolf // VW
// Golf
// 123456
// 93294,7
// 3. Juli 2004

struct tag
{
char hersteller [30] ;
char typ [30] ;
int fnummer ;
float kmstand ;
char datum [30] ;
}
auto;

_ _ _ _ _

Vielen Dank und liebe Grüße, Orchidee! :smile:

Schleifen bitte C-like
Bei

for (i = 0; i tut's mir in den Augen weh.

In C ist es üblich Schleifen so zu schreiben:


    for (i = 0; i 
    
    Willst Du Wert von 1 bis zeilen haben, kannst Du auch
    
    
        for (i = 0; i++ oder
        
        
            for (i = 1; i schreiben.
            
            Aber Achtung: Prüfe Deine Schleifen, ob die Anzahl der Durchläufe stimmt.
            
            Ciao, Allesquatsch

Deutich schlechter: noch mal überarbeiten
Eigentlich bin ich nur aufgestanden, um was gegen meine Erkältung einzunehmen. Aber diesmal wäre die notwendige Antwort viel länger, da sehr viel mehr Fehler drin sind.
Vielleicht setzt Du Dich noch mal dran und überprüfst erst mal selbst. Einfach noch mal die Aufgabenstellung lesen und im K&R Dinge nachschlagen.

Wenn’s mir besser geht, schaue ich noch mal drüber. Wäre aber schön, wenn auch Du erst mal Korrekturen machst.

Ciao, Allesquatsch

Howdy,

fangen wir mal mit den einfachen Sachen an.

Bei Aufg. 21 d) gehe ich davon aus, dass der Wert 128 ist und
somit €. Oder ist es -128, was ebenso zur Ausgabe von € führt?
Bin mir hierbei wirklich nicht sicher… :confused:

Ein signed char hat den Wertebereich -128…127 (siehe http://de.wikipedia.org/wiki/Zweierkomplement).

128 liegt nicht in dem Wertebereich…
Das Result ist -128.

Bei Aufg. 24 nehme ich an, dass ptr = 0 ist. ptr wurde ja
nicht initialisiert aber andererseits würde ptr dann ja einen
zufälligen Wert enthalten…

Der Wert von ptr ist nicht relevant. Er koennte auch 0 sein, dann kann man das Ergebnis besser sehen (sieh mal unter %p bei printf nach. Gibt es kein %p, kannst du auch bei %x nachschauen).

Eine Loesung waere
(ptr + 42) == (float*)((char*)ptr + sizeof(*ptr)*42);

Aufg. 25 verstehe ich schlicht und ergreifen nicht. Dazu bin
ich wohl zu blond… Welcher Code soll denn hier ergänzt
werden?

Was stand denn bei den … ?

Gruss
n.

Ergänzung
Hi,

In C ist es üblich Schleifen so zu schreiben:

for (i = 0; i

und noch schöner, weil der eine oder andere Compiler das unterschiedlich optimiert:

for (i = 0; i 

D.h. oft ist die zweite Variante schneller (insbesondere in C++, wo man dort z.B. auch Iteratoren benutzen kann).


Gruss
n.

Hallo! :smile:

vielen Dank für die raschen Rückmeldungen! :smile:

Ich habe mir die einzelnen Aufgaben erneut angesehen u teilweise verbessert (was ich eben entdeckt habe).

Nachfolgend meine Änderungen / Verbesserungen:
__________

Aufg. 16

Die Summe wird korrekt ermittelt. Der Schleifenkopf kann natürlich in for(i=1;i

Hallo! :smile:

Sry, habe deine Antwort eben erst bemerkt, weshalb sich das nun mit meinem Korrekturversuch überschneidet. :wink:

Ich denke, Aufg. 21 „signed char x = 127; x++;“ habe ich mittlerweile richtig (gem. meinem Post „Korrekturversuch“ von soeben).

Aufg. 25

Die … stammen von mir. Alles, was zur Aufgabe gegeben ist, ist der Einzeiler:

Status status = gruen;

Mehr steht dort tatsächlich nicht. :frowning:

Liebe Grüße!

Orchidee

Hallo Orchidee,

überprüft mit:
_ _ _ _ _

short int a = 32767;
a++;

printf(„a: %i“,a);
_ _ _ _ _

Ausgabe:

a: -32768

d.h.:

a) falsch (keine Fehlermeldung)
b) falsch (keine Ausgabe von NaN)
btw. char sind Buchstaben, weshalb NaN sowieso nicht zutreffen
sollte, oder?
c) falsch (0 wird nicht ausgegeben)
d) wahr (entgegen meiner ersten Lösung wird -128 zugewiesen)

Ich habe nun vermutet, dass sowohl 128 (auch wenn es das hier
nicht gibt) als auch -128 zur Ausgabe von € (gem. dem
ANSI-Zeichensatz) führen müsste aber dem ist nicht so… :confused:

Test:

char a = 134;
printf…
Ausgabe: (Symbol) christliches Kreuz

char a = -134;
printf…
Ausgabe: z

*kopfschüttel

Du hast da etwas Grundsätzliches noch nicht verstanden:

Der Computer kennt gar keine Buchstaben!

Der Computer kann nur Zahlen verarbeiten. Es gibt nur Vereinbahrungen, wie z.B. die ASCII-Tabelle, welche vereinbart, welcher Zahlenwert welchem Buchstabe zugeordnet wird.

C hat grundsätzlich keine Ahnung vom verwendeten Zeichensatz, sondern übernimmt die Vorgaben des Betriebssystems.

char x = 0x61; // a
funktioniert nur auf einem System welche die ASCII-Codierung verwendet, auf einem Rechner mit EBCDIC wird ein ‚-‘ erzeugt.

char x = ‚a‘; // a
funktioniert auf allen Systemen.

printf("%d %c", x, x);
erzeugt dann
97 a

char a = -134;
printf…
Ausgabe: z

*kopfschüttel

Am einfachsten wandelst du die -137 in Hex um, das ergibt 0xFFFFFF7A
Davon nimmst du dann die letzten 8 Bits (0x7A).
In der ASCII-Tabelle findest du dann für 0x7A = ‚z‘

MfG Peter(TOO)

Hi,

  1. Gegeben ist eine quadratische Matrix mat mit n :Zeilen und Spalten. Schreiben Sie C-Code, der das :stuck_out_tongue:rodukt der grau unterlegten Elemente der Matrix :berechnet.

x x x x x
x x x x
x x x
x x
x

in 18 verwendest Du die gegebene Matrix double **mat (oder vielleicht auch int mat[5][5]) überhaupt nicht. Kann also nicht richtig sein.

Falls es noch nicht gesagt wurde,

26 d) Beim nächsten Aufruf der Funktion
kann der Speicher freigegeben werden.

geht nicht, da erstens zwischen den Aufrufen der lokale Pointer undefiniert ist, und selbst wenn er an der selben Stelle neu angelegt wird, wird ja als erstes Speicher beschafft und die zufällig noch vorhanden sein könnende alte Adresse überschrieben. Wie man es dreht und wendet, es ist ein Speicherleck.

Gruß, Lutz

Gruß, Lutz

der Ueberflug …

_ _ _ _ _

Aufg. 16

n ist eine positive int-Variable. Schreiben Sie C-Code, der
die Summe der ersten n Vielfachen (3) bildet.

Schreiben Sie zunächst die Summe für n = 4 aus!

Summe für n = 4: 1 * 4 + 2 * 4 + 3* 4 = 24
_ _ _ _ _

#include
#include

int main(int argc, char** argv) {

int i, anzahl = 3, zahl1 = 3, zahl2 = 0, summe = 0;

Beispiel ist nicht korrekt, weil hier zahl1=3 und nicht 4 verwendet wird.

Aufg. 17

In einer switch-Anweisung

a) muss jeder case mit einem break abschließen

wahr / falsch

falsch: Mehrere case-Fälle ohne break-Anweisung haben die
gleiche Auswirkung wie eine ODER-Verknüpfung.

„falsch“ ist richtig, aber deine Erklaerung ist falsch,
sofern dazwischen auch noch was aufgerufen wird.
Beispiel:

 case 1: f();
 case 2: g();
 case 3: h();
 break;

b) können mehrere Werte nach case stehen
falsch: Jeder case bezieht sich auf einen ganzzahligen Wert
(case 4: case 5: case 2*2:smile:.

yep;

c) ist ein default-Zweig möglich

wahr: Ein default-Zweig ist möglich aber nicht zwingend
erforderlich.

yep;

Aufg. 18

Gegeben ist eine quadratische Matrix mat mit n Zeilen und
Spalten. Schreiben Sie C-Code, der das Produkt der grau
unterlegten Elemente der Matrix berechnet.

x x x x x
x x x x
x x x
x x
x

_ _ _ _ _

Wie schon von Lutz bemerkt.

Aufg. 19

Das Makro AV wird wie folgt definiert und verwendet

#define AV(x) { ((x)>==0) ? (x+x) : (x))

Hier gehen wir mal davon aus, dass die { ein (
und dass >== ein >= sein sollte.

#define AV(x) { ((x)>=0) ? (x+x) : (x))
int z = 1;
int erg = AV(z++);

a) Schreiben Sie AV(1) aus:
b) Schreiben Sie AV(z) aus:
c) Schreiben Sie AV(z++) aus:
d) Geben Sie die Werte von erg und z an:

a. : ( ((1)>=0) ? (1+1) : (1))
b. : ( ((z)>=0) ? (z+z) : (z))
c. : ( ((z++)>=0) ? (z+++z++) : (z++))

d. Da z+++z++ ein ungeordneter Ausdruck ist, ist per C Standard
das Resultat „implementation defined“. Oft kommt sowas raus:
z >= 0 => true
z = 2
2 + 2 = 4
z += 1
z += 1
=> erg = 4 z = 4

Aufg. 20

Bestimmen Sie die Werte der Variablen x nach den folgenden
Zuweisungen:

Nur > liefert das gewünschte Ergebnis
aufgrund der richtigen Verwendung des casts.

yep.

Aufg. 21

d) weist der Variablen c den Wert -128 zu

siehe separater Artikel.

Aufg. 22

Gegeben sei der Prototyp

double doCalc (double *dPtr);

und ein Feld iArr von int Werten. Der Aufruf

double result = doCalc ( (double*) iArr ) );

Keine Warnmeldung.

b) übergibt der Funktion einen Zeiger. Die Bytes werden in der
Funktion als double-Größe interpretiert

yep.

c) führt sicher zu einem Absturz zur Laufzeit

wahr/falsch

nein. Der Zugriff __kann__ aber eine Floatingpoint Exception ausloesen, sofern dort das Muster einer sNaN abgelegt ist (signalling not a number).

d) übergibt die Adresse des ersten Feldelements von iArr

yep.

Aufg. 23

Definieren und initialisieren Sie ein zweidimensionales Feld
wie rechts angegeben:

11 12
21 22
0 0
0 0

int Feld [4] [2] = { 11, 12, 21, 22, 0, 0, 0, 0 } ;

int feld[4][2] = { {11,12},{21,22},{0,0},{0,0} };
ist hier gefragt (unabhaengig davon, dass andere Methoden auch gehen).

Aufg. 24

Gegeben sei ein float-Zeiger ptr. Verwenden Sie sizeof, damit
der folgende Ausdruck immer zu wahr ausgewertet wird

( (ptr + 42) == ptr + sizeof(ptr) * 10,5 )

nein, siehe separater Artikel.

Aufg. 25

Eine Statusanzeige kann grün, gelb oder rot sein. Ergänzen Sie
den Code, so dass er korrekt wird:



Status status = gruen;

hier weiss die Antwort nur der Aufgabensteller.

Aufg. 26

In einer Funktion wird Speicher dynamisch beschafft und nur
dem lokalen Zeiger ptr zugewiesen. Dann gilt:

a) Der Aufruf free(ptr) gibt den Speicher wieder frei
wahr

yep.

b) Mit der Anweisung ptr = 0; wird der Speicher freigegeben

wahr/falsch

falsch: Der Zeiger ptr wird durch die Zuweisung von 0
initialisiert.

Er wird nicht freigeben. Dem ptr wird etwas zugewiesen.
Ob das die Initialisierung ist, haengt von anderen Faktoren ab.

c) Nach der Anweisung ptr = 0; kann der Speicherplatz nicht
mehr freigegeben werden

wahr

sofern der Wert von ptr nicht vorher irgendwo anders gespeichert
wurde, so kann der Speicher nicht mehr freigegeben werden.

d) Beim nächsten Aufruf der Funktion kann der Speicher
freigegeben werden

wahr/falsch

wahr: Unter der Voraussetzung, dass die Initialisierung gem.
b) nicht erfolgt.

Das kann man nicht serioeserweise beantworten, da die Rahmenbedingungen
nicht klar definiert sind. Man kann den Speicher einmal freigeben, solange
man den Originalwert, den malloc zurueckgegeben hat, irgendwo gespeichert
hat. Zwei oder mehrmaliges Freigeben, ala free§;free§ ist ein Fehler
und fuehrt gelegentlich zum Crash.

Aufg. 27

Definieren Sie einen Typen Auto, der als Struktur ein Fahrzeug
beschreibt. Ein Fahrzeug habe einen Hersteller, einen Typ,
eine Fahrgestellnummer, einen Kilometerstand und ein
Herstellungsdatum. Ergänzen Sie den Code und initialisieren
Sie die Variable vom Typ Auto wie im Text angegeben.

Auto meinGolf // VW
// Golf
// 123456
// 93294,7
// 3. Juli 2004

struct auto
{
char hersteller [30] ;
char typ [30] ;
int fnummer ;
float kmstand ;
char datum [30] ;
};

typedef struct auto Auto;

Gruss
n.

OT: oh tempora, o mores
Hi Peter,

Ist heute alles etwas unübersichtlich geworden.
Die meisten Neulinge halten heute die IDE für den Compiler :frowning:

ja, das kann schon mal passieren. Und die „Der Strom kommt aus der Steckdose“-Mentalitaet nimmt auch im Programmierbereich zu, gut zu erkennen, wenn man in einem Vorstellungsgespraech den ‚bösen‘ Kommentar „Wir arbeiten hier mit Makefile Systemen, edieren mit dem gvim und benutzen STL oder boost nur dort, wo sie schneller als unsere eigenen Bibliotheken sind. Haben Sie ein Problem damit?“ platziert …

Und bei denen, die dann partout auf STL und boost bestehen, lohnt es sich dann auch immer mal, das Basiswissen generell abzufragen …

F: Sie kennen also STL und boost?
A: Ja
F: Kennen sie maps?
A: Ja
F: Was sind denn multimaps ?
A: maps, bei denen 
 doppelte Keys auftreten koennen ?!
F: Wie wuerden Sie denn eine multimap implementieren .... 
 hier haben sie ein Blatt Papier .... 
A: .... 3m Geraschele, keine richtige Antwort
F: Nun gut, wie wuerden sie denn eine std::map implementieren?
A: Weiss ich auch nicht
F: Koennen Sie mir skizzieren, wie man eine einfach 
 verkettete Liste implementiert ...
A: Mit Mueh und Not kommt was auf das Papier. Vollkommen richtig 
 ist es natuerlich nicht.
F: Und jetzt vergleichen Sie bitte map und verkettete Liste
 bzgl. der Zugriffszeiten, also der Zeit, die man fuer das Finden
 eines Elements benoetigt.
.....

Das Ganze ist aber nicht nur ein C++ Phänomen. Frag mal einen Java Programmierer, ob er weiss, wie ein long in einen String umgewandelt wird und ob er meint, dass das Ganze in seiner Sprache performant implementiert ist …

Gruss in die CH
n.

Hallo! :smile:

vielen lieben Dank für die Kontrolle und die vielen Erklärungen!

Ich habe noch einiges zu recherchieren aber ich denke, meine Chancen für die Klausur stehen nicht soooo schlecht. :wink:

Vlt. habe ich ja Glück, und die Klausur ähnelt der, die wir hier zusammen bearbeitet haben. :smile:

Nochmal: vielen Dank!

Wünsche euch allen vorab ein schönes Wochenende!

Liebe Grüße,

Orchidee