Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Umsetzung Structur-Chart - Funktionsaufruf und Parameter

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
10.11.2017, 01:29 Uhr
breezy



Hallo zusammen,

ich bin momentan dabei ein C-Programm zu implementieren welches folgendes Structur-Chart umsetzen soll: https://www.imgur.com/a/dvut7

Das ist mein erstes Programm mit mehreren Funktionen, habt Nachsicht!

Bisher ist folgender Code zusammen gekommen:


Code:
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>

void f11(void);
int f12(int iA);
void f13(void);
void f21(void);
int f22(int iB);
int f32(int iC);

int iA, iB, iC;

int main()
{
    f11();
    f12(iA);
    f13();
}

void f11()
{
    f21();
}

void f21()
{
;
}

int f12(iA)
{
    f22(iB);
    iA = 1;
    int iF = iA + 1;
    

    return iF;
}

int f22(iB)
{
    iB = 2;
    int iE = iB + 1;
    f32(iC);

    return iE;
}

int f32(iC)
{
    iC = 3;
    int iD = iC + 1;

    return iD;
}

void f13()
{
;
}



Könnt ihr mir feedback geben? Würde man die Funktionen in der Reihenfolge definieren oder eher von links nach rechts?

Danke euch!

Dieser Post wurde am 10.11.2017 um 01:31 Uhr von breezy editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
10.11.2017, 13:11 Uhr
ao

(Operator)


Die Reihenfolge der Definition ist egal und Geschmackssache.

Die globalen Variablen int iA, iB, iC; solltest du löschen. Code, der nur kompiliert, wenn es Variablen mit bestimmten Namen gibt, ist bäh.


C++:
int f12(iA)
{
    f22(iB);
    iA = 1;
    int iF = iA + 1;
    

    return iF;
}



1. Hier ist ein Syntaxfehler, der Funktionskopf muss heißen:
int f12 (int iA)
Bei f22 und f32 entsprechend.

2. Verständnisfehler: iB ist der FORMALE Parameter von f22 (Funktionskopf also int f22 (int iB)). Das heißt nicht, dass f22 nur mit Variablen aufgerufen werden darf, die iB heißen. f22 kann mit jedem int-Ausdruck als Argument aufgerufen werden. Du könntest also schreiben:

f22 (42);

oder auch:

C++:
int iF = f22 (iA);


Dabei verwendest du das iA (formaler Parameter von f12) als Aufrufparameter von f22 und speicherst gleichzeitig die Rückgabe von f22 in iF (was du aus f12 retournieren sollst).
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
10.11.2017, 13:54 Uhr
breezy



Hey ao,

danke für deine ausführliche Antwort!

Ich hab nun versucht, den code nach deinen Tipps abzuändern, beim compilieren gibt er dann Fehler aus (Siehe code als Kommentar!):


Code:

#include <stdlib.h>
#include <conio.h>
#include <stdio.h>

int f11(void);
int f12(int iA);
int f13(void);
int f21(void);
int f22(int iB);
int f32(int iC);

int main()
{
    f11();
    f12(); //'f12' too few arguments to call
    f13();
}

int f11()
{
    f21();
}

int f21()
{
}

int f12(int iA)
{
    static int iF;
    f22(); //'f22' too few arguments to call

    return iF;
}

int f22(int iB)
{
    static int iE;
    f32(); //'f22' too few arguments to call
    return iE;
}

int f32(int iC)
{
    static int iD;
    return iD;
}

int f13()
{
}



Kannst du mir da nochmal helfen? Ich habe es so verstanden, dass die Funktion durch beliebige (int)Parameter aufgerufen werden darf, warum möchte er dann aber etwas spezifisches haben?

Danke!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
10.11.2017, 14:02 Uhr
ao

(Operator)


"Beliebig" heißt nicht, dass du den Parameter ganz weglassen darfst. Richtig ist zum Beispiel

C++:
f12(1); // Aufruf mit einem konstanten int (einem sog. Int-Literal)

int a = 3 + 6;
f12(a); // Aufruf mit einer Int-Variablen

int b = 4 + 7;
f12(a+b); // Aufruf mit einem arithmetischen Ausdruck
// hier wird zuerst a+b (also 9+11) berechnet und das dann an f12 übergeben.

f12(f22(0)); // Aufruf mit dem Ergebnis eines Funktionsaufrufs (f22)
// hier wird zuerst f22(0) ausgeführt, und dann wird der Rückgabewert davon (ebenfalls ein int) an f12 übergeben.


Du kannst jeden Ausdruck eintragen, der für den Compiler einen int-Wert darstellt. Nur wenn du gar nichts einträgst, ist das ein Fehler.

Dieser Post wurde am 10.11.2017 um 14:05 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
10.11.2017, 14:26 Uhr
breezy



Okay, also würde der Aufruf mit z.B. f22(); mit void arbeiten und somit ein Fehler anzeigen?

Wenn ich nun f12(100), f22(101) und f32(102) aufrufe wäre es richtig? (Offensichtlich, der compiler findets gut)

Warum kann ich dann aber f12 nicht mit f12(iA) aufrufen? Er beschwert sich über eine nicht deklarierte Variable. Muss ich die Variable zwingend definieren für den Aufruf mit iA?

Und eine letzte Frage, muss z.B. die Funktion f11 einen Wert zurück geben oder kann ich return (); weg lassen?

Danke nochmal, sehr gute Erklärungen!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
10.11.2017, 17:47 Uhr
ao

(Operator)



Zitat von breezy:
Okay, also würde der Aufruf mit z.B. f22(); mit void arbeiten und somit ein Fehler anzeigen?

"Mit void arbeiten" ist ein bisschen merkwürdig ausgedrückt, aber ich denke, du meinst das richtige.

f22 ist ganz oben (unter den ganzen #includes) deklariert als "int f22 (int iB);" Das ist der sogenannte Prototyp, der dem Compiler anzeigt, wie die Funktion f22 zu gebrauchen ist (einen int übergeben, ein int in der Rückgabe).

Anmerkung: Das iB könnte an dieser Stelle auch fehlen, zum Deklarieren braucht man nur die Datentypen der Parameter. "int f22 (int);" ist also bereits ein gültiger Prototyp, mit dem ein Compiler was anfangen kann. Häufig wird der Prototyp aber gleichzeitig zum Dokumentieren für andere Programmierer verwendet, und die wollen natürlich nicht nur Anzahl und Typen der Parameter kennen, sondern auch die Bedeutung, damit sie wissen, wie sie sie benutzen müssen. Hierfür ist der Bezeichnername hilfreich.

Jedenfalls, nachdem f22 so deklariert wurde, kann es nur so benutzt werden (mit Übergabe eines int). Alles andere ist ein Fehler.

Wenn f22 so deklariert wäre: int f22 (int x, int y);
dann müsstest du beim Aufrufen immer zwei Argumente übergeben: f22 (123, 456);


Zitat:
Wenn ich nun f12(100), f22(101) und f32(102) aufrufe wäre es richtig? (Offensichtlich, der compiler findets gut)

Ja.


Zitat:
Warum kann ich dann aber f12 nicht mit f12(iA) aufrufen? Er beschwert sich über eine nicht deklarierte Variable. Muss ich die Variable zwingend definieren für den Aufruf mit iA?

Wenn du eine Variable mit dem Namen iA an der Stelle verwenden willst, dann muss sie vorher deklariert sein. Ein C- oder C++-Compiler kann Variablen nicht einfach so aus dem Nichts erzeugen. Du müsstest dann schreiben


C++:
int main ()
{
int iA = 42;
f12 (iA);
}




Zitat:
Und eine letzte Frage, muss z.B. die Funktion f11 einen Wert zurück geben oder kann ich return (); weg lassen?

Das Weglassen ist kein Fehler, der vom Compiler bestraft wird, aber du solltest es auf keinen Fall tun. Das ist ein Fall von sogenanntem "undefined behaviour". Das heißt, es kann heute glatt funktionieren und morgen aus heiterem Himmel abstürzen. Das gilt für Funktionen, die einen echten Rückgabetyp (also nicht void) haben.

Das ist eine der wirklich bösen Stellen in C, weil man leicht mal ein return vergessen kann, wenn Funktion ein paar If-Verzweigungen hat, und ich persönlich verstehe auch nicht, warum das nicht verboten ist (oder ist es das inzwischen?). Tatsache ist, dass alle modernen Compiler das erkennen und eine Warnung ausgeben können. Tatsache ist auch, dass ich schon mal stundenlang nach einem mysteriösen Absturz gesucht habe, der an sowas lag, und dass ich seitdem in jedem Projekt, das ich anfange, diese Warnung auf "Fehler" setze. Das heißt, ich will in dem Fall eine Fehlermeldung haben, der Compiler soll das nicht akzeptieren, weil die Folgen echt übel sein können.

Mit welchem Compiler arbeitest du?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: