C Programmierung: Funktionsprototyp

Hallo zusammen! :smile:

Das ist mein erster Post hier, weshalb ich um Nachsicht bitte… Danke! :wink:

Ich studiere nun im 3. Semester Wirtschaftsingenieurwesen und muss in kürze (3 Wochen) eine Klausur in Informatik II, C Programmierung, schreiben. Obwohl ich - für meine Verhältnisse - recht fleißig war, stoße ich immer wieder auf scheinbar unlösbare Probleme in den alten Klausuren, Probeklausuren…

Hier meine 1. Frage:

Aufgabe aus einer Probeklausur:
_ _ _ _ _

Wie lauten die Prototypen folgender Funktionen?

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

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

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

Ich hänge - bedauerlicherweise - bereits bei a) und habe mir deshalb um b) noch keine großen Gedanken gemacht…

Es ist nicht so, dass ich euch einfach um eine Antwort bitten will. Mir liegt viel daran, dass auch zu verstehen, weshalb ihr unten stehend mal meinen Lösungsversuch erhaltet, bei welchem aber wirklich nichts Sinnvolles zu Tage kam. :frowning:
_ _ _ _ _

#include
#include
#include

char* string (char *x, char *y, char *z);

main() {

char d;
char *a, *b, *c;

printf(„Eingabe a:\n“);
scanf("%s", &a);
printf(„Eingabe b:\n“);
scanf("%s", &b);
printf(„Eingabe c:\n“);
scanf("%s", &c);

d = string(char *a, char *b, char *c);

printf(„d: %c“, d);

return 0;
}

char* string (char *x, char *y, char *z) {

char *zusammen;

char array[4];

array[0] = *x;
array[1] = *y;
array[2] = *z;
array[3] = ‚\0‘;

*zusammen = array[];

return *zusammen;
}
_ _ _ _ _

Der Gedankengang hinter obigem Chaos ist folgender:

In der main-Funktion übergeb ich 3 Buchstaben an die Adr. von a, b und c. In der Funktion string rufe ich diese wieder auf und hinterlege sie in dem array, welches ich dann an den char zusammen übergebe und im main wieder erhalte…

Naja, leider funktioniert das iwrgendwie nicht so richtig… :frowning:

Vielen Dank vorab für eure Bemühungen!!!

Liebe Grüße, Orchidee! :smile:

Hallo Orchidee,

char* string (char *x, char *y, char *z) {

char *zusammen;

char array[4];

array[0] = *x;
array[1] = *y;
array[2] = *z;
array[3] = ‚\0‘;

*zusammen = array[];

return *zusammen;
}
_ _ _ _ _

Der Gedankengang hinter obigem Chaos ist folgender:

In der main-Funktion übergeb ich 3 Buchstaben an die Adr. von
a, b und c. In der Funktion string rufe ich diese wieder auf
und hinterlege sie in dem array, welches ich dann an den char
zusammen übergebe und im main wieder erhalte…

Naja, leider funktioniert das iwrgendwie nicht so richtig…

(

Ist klar :wink:

array ist eine automatische lokale vVaiable und wird beim Aufruf von string() auf dem Stack erzeugt.
Mit return wird dann der Stack wieder abgeräumt.
Der zurückgegebene Zeiger zeigt dann also da hin wo array auf dem Stack erzeugt wurde.

Ändere
char array[4];
in
static char array[4];

Allerdings zerstört dann jeder Aufruf von string() den Inhalt wieder.

MfG Peter(TOO)

Hi,

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

na, diese Frage ist ja zumindestens noch einigermassen eindeutig. Es werden drei Zeichen als Parameter vereinbart und es soll der resultierende String zurueckgegeben werden.

Also sowas wie:

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

Der resultierende String wird dabei normalerweise auf dem Heap allokiert, wofuer in C malloc() und in C++ der operator new benutzt wird. Allokiert werden müssen 4 Zeichen (3 übergebene plus 1 fuer den \0 char) und dann die Zeichen einzelnd in den Zielstring kopiert werden

Das Ganze koennte also so aussehen:

char\* compose(char a, char b, char c)
{
 char\* s = new char[3+1];
 // entweder s[0]=a; s[1]=b; s[2]=c; s[3]='\0'; 
 // oder
 char\* p = s;
 \*p++ = a;
 \*p++ = b;
 \*p++ = c;
 \*p++ ='\0'; 
 return s;
}

wobei der String dann spaeter in C mit free() und in C++ mit dem operator delete wieder freigegeben werden muss.

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

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

Die ist eine sehr lustige Formulierung und sie ist keinesfalls eindeutig.

Man muesste den Klausurbetreuer erstmal fragen, was er denn meint.
„besitzt“ kann heissen, die zwei Felder sind Parameter, es kann aber auch heissen, die Felder sind irgendwo in der Funktion vereinbart. Wir gehen im Folgenden mal von einer Parameteruebergabe aus. „gibt 1 oder 2 zurueck“ kann sich ebenfalls auf die Felder (also Rueckgabe 1-2 Felder) oder auf 1-2 doubles beziehen, welche wiederum entweder in einem Feld oder als Parameter zurueckgegeben werden können. Gehen wir mal davon aus, dass tatsaechlich gemeint ist, den einen oder die beiden double als Feld zurueckzugeben.

Dann haette in C hat die Funktion zwei double Pointer (Felder) als Parameter plus 2 Parameter für die Anzahl der Elemente in den Feldern. Dann brauchen wir noch einen Parameter cnt mit der Anzahl der zurueckzugebenen doubles, also sowas wie

double\* maxFeld(double\* feld1, size\_t n1, 
 double\* feld2, size\_t n2,
 size\_t cnt)
{
}

In der Funktion koennte man dann analog zum ersten Fall doubles mit new oder malloc allokieren.

Da im Aufgabentext aber im zweiten Abschnitt von Funktionen die Rede ist, ist es auch möglich, dass der Student hier eine Funktion mit der Rueckgabe eines Feldes und eine weitere mit der Rueckgabe von zwei Feldern beschreiben soll. Dann entfiele natuerlich cnt und man muesste sich ueberlegen, wie man die (vielleicht allokierten) Felder dann per Parameteruebergabe an den Aufrufer zurueckbekommt.

Btw: In C++ gibt es std::vector, weshalb dort die Felder const-Referenzen auf vector wären und es kann auch ein vector zurueckgegeben werden. Aus Performanzgruenden wuerde man aber den Zielvector als non-const-Referenzparameter uebergeben.

Gruss
n.

Hi,

ich denke, Du hast die Aufgabe überinterpretiert. Es ist ja nur nach den Prototypen gefragt, also nach dem, was Du in eine .h Header-Datei schreiben würdest. Und das wäre bei a) tatsächlich

char * compose(char, char, char);

und bei b)

int maxFeld(double, double);

Nach einer möglichen Implementierung ist in der angegebenen Aufgabenstellung gar nicht gefragt.

Gruß, Lutz

PS: ich würde b) als den Einzeiler

return (x>=y)?1:2;

verstehen, also double-Feld als übergebenen Parameter. Solltet ihr aber Feld im Sinne von Tupel, Vektor oder Array verwendet haben, dann siehe eine Anwort früher.

Nur den Funktionsprototyp ist richtig
Hi

Sehe es auch so, dass die Aufgabe überhaupt keine Implementierung fordert, sondern nur einen Einzeiler.

b) finde ich völlig unprofessionell beschrieben

Das beginnt damit, dass sich jeder jetzt ausdenken darf, was wohl mit „der Besitz“ von Feldern gemeint sein könnte.

Feld wird im Deutschen aber mit Array gleichgesetzt, so dass ich die Übergabe von 2 doubles erst mal ausgeschlossenen habe.

Sind die Felder nur innerhalb der Funktion definiert aber kein Übergabeparameter, spielen sie für den Prototypen keine Rolle.
Wird also nicht übergeben, wäre die Parameterliste (void).

Irritierend ist auch, dass konkrete Rückgabewert genannt werden, die ganz unterschiedliche Typen darstellen können.

Das macht im Grunde genommen nur Sinn, wenn es gar keinen Funktionsprototypen gibt, sondern die Funktion das von Lutz beschriebene Makro ist. Makros sind aber in C nicht typisiert.
(In C++ gäbe es die Möglichkeit Makros zu typisieren.)

In der header-Datei stünde dann

#define maxFeld(X, Y) ((X) \> (Y) ? (1) : (2))

was aber weder formal noch inhaltlich in C ein Funktionsprototyp ist.

Mit großer Wahrscheinlichkeit will IMHO der Lehrer diese beiden Lösungen hören, muss sich aber sagen lassen, dass die sprachliche Form von b) ungeeignet ist.

Ciao, Allesquatsch

Hallo zusammen! :smile:

Vielen Dank für die zahlreichen Rückmeldungen und Erklärungsversuche!

Es ist mir bewusst, dass ich die Aufgabe überinterpretiert habe und mein Programmierungsversuch nicht Klausurrelevant ist. Ich habe eben versucht, zu überprüfen, ob meine Annahme des Funktionsprototypen so stimmt. :wink:

Für Aufgabenteil a) habe ich mich für die Lösung > entschieden, welche ja auch meiner Überlegung entspricht. Unabhängig davon, dass mein Programm nicht funktioniert - leider auch, nachdem ich static hinzugefügt habe. Nicht so schlimm! :smile:

Aufgabe b) ist für mich schlicht und ergreifend auf die schnelle nicht lösbar, weshalb ich auf die Punkte eben verzichten müsste. Auch das ist aber nicht tragisch, das es sich hier um eine von insgesamt 30ig Aufgaben handelt und ich bis dato ganz gut zurechtgekommen bin.

Ich werde in den nächsten Tagen mal eine kompl. Klausur mit meinen Lösungsversuchen online stellen. Eventuell habt ihr ja Lust, drüber zu schauen.

Jetzt lese ich noch mal, was es mit „malloc“ genau auf sich hat. ^^

Bis dahin nochmal vielen Dank für die Hilfe und schönes Wochenende! :smile:

Liebe Grüße, Orchidee

Hi,

Unabhängig davon, dass mein
Programm nicht funktioniert - leider auch, nachdem ich static
hinzugefügt habe. Nicht so schlimm! :smile:

char\* compose(char a, char b, char c)
{
 static char s[3+1];
 // entweder s[0]=a; s[1]=b; s[2]=c; s[3]='\0';
 // oder
 char\* p = s;
 \*p++ = a;
 \*p++ = b;
 \*p++ = c;
 \*p++ ='\0'; 
 return s;
}

Die Verwendung von static in diesem Fall bringt aber (wie schon von den anderen auch erwähnt) in richtigen Programmen Probleme mit sich.

Gruss
n.