Fragen zur Klausurvorbeitung, 85% beantwortet, 15% fehlen mir noch...
-
C-Developer schrieb:
Stimmt und genau so verhält sich:
if(Ausdruck == Ausdruck_1)
Anweisung_1;
if(Ausdruck == Ausdruck_2)
Anweisung_2;
etc ..nee, hier wird Anweisung_2 ja nur ausgeführt, wenn Ausdruck==Ausdruck_2. Anweisung_2 muss aber auch ausgeführt werden, wenn Ausdruck==Ausdruck_1
-
if(Ausdruck == Ausdruck_1) { Anweisung_1; if(Ausdruck == Ausdruck_2) { Anweisung_2; */... weitere Verschachtelung*/ } }
-
nein, auch falsch
-
Hi!
Zu 4:
int *x ist ein Zeiger auf einen beliebigen Integer Wert, nich den der Variable x, x ist ja der Zeiger.int y = 10; int *x = &y; // *x zeigt auf y
Zu 8:
C-Developer liegt genau richtig. Die einzelnen Zeige von Switch-Case werden der Reihe nach unten durchlaufen. Falls eine Abfrage zutrifft werden die darunterliegenden aber nicht übrsprungen.switch( xyz ) { case 1: anweisungen; break; // break ignoriert alle darunterliegenden abfragen } Zu 10: unsigned int und signed int belegen (oft) 32 bit. Auf jedenfall sind beide aber immer gleich groß. Der Witz an unsigned int ist, das er im + bereich mehr Werte aufnehmen kann als signed int. [cpp] unsigned int umax = 0xffffffff; signed int smax = 0x7fffffff;
Zu 12:
Zeiger können auf den ersten Eintrag eines arrays zeigen. Durch inkrementieren des Zeigers zeigt der auf den zweiten Eintrag usw...Klasse1 obj1[ 10 ]; Klasse1 *obj2 = obj1; *( obj2++ ) = 10; // obj1[ 0 ] = 10 *( obj2++ ) = 20; // obj1[ 1 ] = 20
!Speicher der vom Heap genommen wurde muss vom Programmierer zurückgegeben werden.!
void foo( Klasse1 *p ) // hier kann ein Zeiger auf ein array übergeben werden { }
void foo( Klasse1 arr[] ) // ist auch möglich, aber nicht wirklich schön { }
Klasse1 *bar() { Klasse1 arr[ 10 ]; return arr; // Vorsicht, sowas NIE machen. Das funktioniert zwar ruft aber ein undefiniertes Verhalten vor, da arr gelöscht wird sobald der Scope verlassen wird }
Klasse1 *bar() { Klasse1 *p = malloc( 3*sizeof( Klasse1 ) ); return p; // Das klappt so, der Speicher muss aber zurückgegeben werden }
Zu 14:
struct Person_t { char *Vorname; char *Nachname; }; void foo( Person_t *p ) { p->Nachname = "Nachname"; } int main() { Person_t person; person.Vorname = "Vorname"; person.Nachname = "Hallo"; foo( &person ); printf( "%s %s\n", person.Vorname, person.Nachname ); }
Zu 15:
Es besteht ein ganz gewaltiger Unterschied. Alles was in Union definiert wird greift auf den selben Speicherbereich zu!union foo { float xyz[ 3 ]; struct { float x, y, z; } };
wenn xyz[ 1 ] geändert wird ändert sich auch "y". Wenn "z" geändert wird ändert sich xyz[ 2 ] usw...
Zu 17:
size_t fwrite(const void *pur, size_t size, size_t nmemb, FILE *fp)pur = puffer der geschrieben werden soll
size = größe des Datenblocks welcher geschrieben werden soll
nmemb = anzahl der Datenblöcke (sizenmemb = tatsächliche Größe)
*fp = DateizeigerZu 22:
struct
{
byte b1 : 1;
byte b2 : 1;
// ...
};b1 erhält den wert von Bit1, b2 den Wert von Bit2 usw...
zu 26:
Daten strukturieren in Strukturen, Prozedurale Programmierung...
-
David_pb schrieb:
Zu 8:
C-Developer liegt genau richtig. Die einzelnen Zeige von Switch-Case werden der Reihe nach unten durchlaufen. Falls eine Abfrage zutrifft werden die darunterliegenden aber nicht übrsprungen.nein. lies nochmal was ich geschrieben habe
-
Stimmt, du hast natürlich recht. Übersehens!
-
was heißt hier "nein auch falsch"
begründung ?
-
linchpin schrieb:
was heißt hier "nein auch falsch"
begründung ?Wenn Ausdruck == Ausdruck1, dann ist ja wohl Ausdruck != Ausdruck2 für Ausdruck1 != Ausdruck2, von daher ist es sinnlos, das zweite if in die erste if-Bedingung reinzunehmen.
-
Anabolika schrieb:
- Es gibt drei Grundprinzipien, die man zur Beschreibung imperativer Programme benötigt. Erklären Sie diese anhand ihrer Darstellung in Flussdiagrammen.
Randfrage: Was genau hat dein Bild mit der Aufgabe zu tun?
- Welche Gründe kann es geben, in einem C-Programm Programmteile in Funktionen auszugliedern?
- bessere Aufgabenverteilung, mehrere Entwickler arbeiten an Funktion x die andere Entwickler arbeiten an Funktion y
- das Programm wird übersichtlicher und strukturierter
- Teile des Programms lassen sich in anderen Programmen später wieder verwenden
Da fehlt noch mehrfache Verwendung einer bestimmten Anweisungsfolge in mehreren Programmteilen (statt an zehn Stellen ein Schleifenkonstrukt einzubauen, das ein Array sortiert, nimmt man lieber EINE Sortierfunktion und ruft sie bei Bedarf auf)
7) Wie kann man zeigen, dass man ein Programm, das nur while-Schleifen als Schleifen enthält, durch ein Programm mit gleichem Ein-Ausgabe-Verhalten ersetzen kann, das als Schleifen nur do-Schleifen nutzt?#include <stdio.h> void do_schleife(){ int zahl=1, tmp=0; do{ tmp=tmp+zahl; printf("%d+",zahl++); } while(zahl <= 10); printf("\b = %d",tmp); } void while_schleife(){ int zahl=1, tmp=0; while(zahl <= 10) { tmp=tmp+zahl; printf("%d+",zahl++); } printf("\b = %d\n",tmp); } int main(void) { do_schleife(); printf("\n"); while_schleife(); return 0; }
[/quote]Das ist zwar für ein Beispiel ausreichend, aber noch lange kein genereller Beweis.
- Wie werden im Standard-C Buchstaben und Boolesche Werte behandelt? Gehen Sie z.B. für eine Variable int x auf die Bedingung if(x) ein.
Buchstaben werden durch ihren jeweiligen ASCII-Wert dargestellt (im Datentyp char), boolesche Werte durch Ganzzahlen (0 = false, andere Werte = true)
- Beim Rechnen mit ganzen Zahlen und Fließkommazahlen muss man das Verhalten in Extremsituationen kennen, die man in der allgemeinen Mathematik nicht in dieser Form berücksichtigt. Welche Extremsituationen sind zu beachten, wie verhält sich C in diesen Situationen, welche „besonderen“ Werte können beobachtet werden?
Teil man beispielsweise 2(int) / 3(int) so ergibt dies 0,6… will man diesem einem Double zuweisen, so funktioniert das nicht einwandfrei, da die Zahl hinter dem Komma einfach abgeschnitten wird, der Wert einer Doublevariable hätte dann den Wert 0,000000. Des Weiteren muss man anstelle eines Kommas einen Punkt bei der Eingabe von Kommzahlen eingeben.
Ich glaube, bei der Frage ging es eher um Über- und Unterlauf (ersterer wird als 1.#INF, letzterer als 0 markiert) und ungültige Eingaben für Gleitkomma-Operationen (z.B. Wurzel(-1))
- Wozu dient das Schlüsselwort enum in C? Erklären Sie seine Einsatzmöglichkeiten.
Enum (enumeration) in Deutsch Aufzählung, ist ein Datentyp mit einem endlichen Wertebereich. Alle Werte des Aufzählungstyps werden bei der Deklaration des Typs als Name definiert. Dabei wird auch eine Reihenfolge festgelegt, die eine Ordnung der einzelnen Werte bestimmt, die Werte können also sortiert werden.
enum FARBE {BLAU, GRUEN, ROT, GELB}
enum OBST {APFEL, KIRSCHE, PFLAUME}Dies bringt den Vorteil, dass der Compiler automatisch fehlerhafte Zuweisungen verhindern kann.
In C++ ja - in C kann jeder int als enum-Wert genutzt werden.
- Wie kann in C ein Datentyp aussehen, der den Vornamen und Nachnamen einer Person enthalten kann? Wie muss dann eine Funktion aussehen mit der der Nachname geändert wird?
char vorname[..];
char nachmame[..];Ich würde die beiden Werte noch in einem struct zusammenfassen, ändern kannst du den Nachnamen dann über "memcpy(p.nachname,"Maier");" oder ähnliches
- Beim Lesen- und Schreiben von Dateien wird der Textmodus und der Binärmodus unterschieden. Erklären Sie den Unterschied, gehen Sie dabei auf die Betriebssysteme Windows und Unix ein.
Binärmodus - jedes Byte wird unverändert übernommen
Textmodus - Zeilenende-Zeichen (\n) werden je nach Betriebssystem anders interpretiert- Erläutern Sie, wie rekursive Funktionen grundsätzlich aufgebaut sind.
Kurz gesagt ist eine Rekursion eine Funktion, die sich selbst aufruft und sich selbst immer wieder neu definiert.
aufruft: ja, definiert: nein
-
Danke für die Antworten, ich werds soweit korrigieren.