Bitte Erklärung zu "Funktionen" anhand von kleinem Beispiel



  • Hallo, ich bin ziemlicher Neuling im C-Programmieren.
    Ich habe das Problem, dass ich die sache mit Funktionen nicht so ganz verstehe. Habe mal ein kleines Beispiel programmiert, an dem ich zeigen möchte, wo mein Problem liegt. Das kleine Programm soll eine Zahl vom Benutzer einlesen und die mit 2multiplizieren, und am Ende das Ergebnis ausgeben. ICh weiß, dass dieses Problem auch ohne Funktion lösbar ist, aber ich möchte so erkennen, wie Funktionen "funktionieren"

    #include <stdio.h>
    #include <conio.h>
    
    int berechnung (int a);
    int main()
    
    {	int a;
     	printf("zahl a:");
     	scanf ("%d", &a);
     	printf (" Das Ergebnis aus 2*a = %d",berechnung (a) );
    	while(!kbhit());
     	return 0;
    } 	
    
    int berechnung (int a)
    {	
    	int b;
    	b=2*a;
     	return (b);
    }
    

    so gehts ! aber wenn ich hier

    printf (" Das Ergebnis aus 2*a = %d",berechnung (a) );
    

    statt "berechnung (a)" "berechnung (b)" schreibe gehts nicht. und ich würd gerne wissen warum nicht. meine funktion "berechnung" rechnet doch mit und liefert doch den wert b, und nicht a. ich hoffe mir kann jemand helfen. muss ich bei dem prototyp der funktion :

    int berechnung (int a);
    

    die variable nach der variable benennen, die von der funktion zurückgegeben wird, oder nach der, mit der die funktion arbeitet?



  • b ist eine lokale Variable in der Funktion berechnung(), d. h, sie kann NUR dort
    verwendet werden. Sobald die Funktion verlassen wird, ist der Speicherbereich,
    den b belegt hat nicht mehr zugänglich. Mit dem "return b" wird jedoch angegeben,
    dass der Inhalt von diesem Speicher an eine andere Stelle kopiert werden soll,
    und zwar dahin, wo es zugewiesen wird, z. B. :

    int x = berechne(...);

    x ist eine völlig andere Variable als b, aber der Inhalt von b wird nach x kopiert.

    In deinem Fall wird dieser Wert aber nicht in eine lokale Variable der Funktion
    "main()" kopiert, sondern er wird gleich einer anderen Funktion (printf()) als Parameter übergeben (also in den Parameter der reinkopiert).

    Das 'a' in "berechne()" hingegen hat mit dem 'a' in "main()" nix zu tun.
    Auch das sind zwei völlig verschiedene Variablen.
    Beim aufruf "berechne(a)" wird der Inhalt vom 'a' in "main()" in das 'a' vom "berechne()" kopiert.

    Wie der Parameter von "berechne()" heisst, kannst du dir aussuchen.
    Natürlich kann man den zurückgeben, aber müssten tut man nicht:

    // beide Versionen sind ok und kommen zum gleichen Ergebnis.
    int berechne(int Foo)
    {
        Foo += 42;
        return Foo;
    }
    
    int berechne(int Foo)
    {
        int bar = Foo + 42;
        return bar;
    }
    
    // Imho ist der Name des Parameters im Prototyp frei wählbar 
    // kann sich also auch vom Namen in der Implementierung 
    // unterscheiden. Es ist sogar möglich, im Prototyp 
    // ganz auf den Namen zu verzichten.
    // Allerdings sind die letzten beiden Versionen aus
    // gründen der Les- und Wartbarkeit nicht sonderlich zu empfehlen:
    int berechne(int Foo);
    int berechne(int Abc);
    int berechne(int);
    


  • gut, das habe ich soweit verstanden, dass die lokalen variablen nach ablauf der jeweiligen funktion verschwinden. wie ist das aber, wenn ich wie hier:

    #include <stdio.h>
    #include <conio.h>
    int eingabe (int x);
    int berechnung (int a);
    int main()
    {
        int b;
        int a=eingabe (x);
    	printf (" Das Ergebnis aus 2*a = %d",berechnung (b) );
    	while(!kbhit());
     	return 0;
    } 	
    int eingabe (int x)
    {
     	int x;
     	printf("zahl a:");
     	scanf ("%d", &x);
     	return (x);
    }
    int berechnung (int a)
    {	
    	int b;
    	b=2*a;
     	return (b);
    }
    

    die eingabe auch als extra funktion haben will. dann muss ich doch eine "hilfsvariable" einsetzen, die dann den wert "x", den die funktion "eingabe" zurück an "main" gibt nach "a" zuweien, mit dem dann die funktion "berechnung" weiter arbeiten kann. aber wenn ich das wie oben mache, dann kommt immer der fehler: "'x' undeclared (first use this funktion)". ich muss doch das "x" in der funktion "eingabe" deklarieren und nicht in "main" (oder sollte, um globale variable zu vermeiden). aber so funktioniert das anscheinen nicht. mein ziel ist es, diese kleine programm so zu strukturieren:

    in der main steht nur die funktion "eingabe" und dann folgt schon die anweisung "printf" und schon sollte das programm zu ende sein. unten sind dann noch die funktionen "eingabe" und "berechnung " implementiert. kannst du mit vllt sagen, wie das dann ohne globale variablen aussehen kann?



  • schulmathematik:

    f(x) = x + 3;

    musst du die funktion f jetzt immer mit einem 'x' aufrufen? nein, musst du nicht. x zeigt nur, dass hier irgendetwas variables hingehört. d.h. f(5) ist genauso gültig, wie ein f(T) (da käme halt T + 3 raus).

    funktionen in c (und allen anderen sprachen) sind genauso gedacht. eine funktion hat einen namen (f), eingabeparameter (x) und einen rückgabewert (x + 3).

    anders als in der mathematik gibt es in programmiersprachen aber auch methoden, die entweder keinen rückgabetyp besitzen (void) oder keine parameter (wie deine main z.b.)
    deine methode "eingabe" wäre z.b. eine typische funktion ohne parameter, sondern nur mit rückgabewert.



  • ich hoffe, ich fang nicht an zu nerven, aber irgendwi will das kleine programm nicht, aber ich weiß nicht, was daran jetzt noch falsch ist. meine funktion "eingabe" hat keine parameter, die sie übernimmt, jedoch gibt sie den wert "x" an die "main" über, die das "x" dann dem "a" zuweist. aber wenn ich das Programm ausführen will, kommt die fehlermeldung, dass "x" in main zum ersten mal benutzt wird:

    int a = eingabe (x), b;
    

    wahrscheinlich übersehe ihc nur eine kleinigkeit, aber ich komm einfach nicht drauf. hier nochmal der auktualisierte code:

    #include <stdio.h>
    #include <conio.h>
    int eingabe ();
    int berechnung (int a);
    int main()
    {
        int a = eingabe (x), b;
     	printf (" Das Ergebnis aus 2*a = %d",berechnung (b) );
    	while(!kbhit());
     	return 0;
    } 	
    
    int eingabe ()
    {	
    	int x;
     	printf ("\n Geben sie eine Zahl a ein : ");
     	scanf ("%d", x);
            return (x);
    
    }
    int berechnung (int a)
    {	
    	int b;
    	b=2*a;
     	return (b);
    }
    


  • Die Funktion eingabe() hat keine Parameter, also mußt du beim Aufruf auch nichts in die Parameterklammern schreiben (und die lokalen Variablen der Funktion sind dem Hauptprogramm sowieso egal:

    int a=eingabe(),b;
    

    Genauso haben die Variablen a und b des Hauptprogramms absolut nichts mit den gleichnamigen Variablen in der Funktion berechnung() zu tun - beim Aufruf printf(...,berechnung(b)); wird der Inhalt der Variablen main()::b kopiert in das Argument berechnung()::a, anschließend daraus berechnung()::b errechnet und zurückgegeben (und dieser Rückgabewert wird gleich weitergeschickt an printf()). (das Problem dabei ist, daß main()::b nicht initialisiert wurde und du mit irgendwelchem Datenmüll rechnest ;))

    PS: Und bei scanf() mußt du die Adresse des Ziels angeben, sonst schmiert dir das Programm ab ( scanf("%d",&x); ) 😉



  • juhu, ich habs hinbekommen, und die ergebnisse sind auch immer die erwarteten. ich möchte das prog mal so erklären, wie ich es verstanden habe. und wenn ihr der erklärung zustimmt, heißt das, dass ich es endlich kapiert habe.

    #include <stdio.h>
    #include <conio.h>
    double eingabe ();
    double berechnung (double a);
    int main()
    {
        double a = eingabe ();
        double b = berechnung (a);
     	printf (" Das Ergebnis aus 2*a = %.2lf",b);
    	while(!kbhit());
     	return 0;
    } 	
    
    double eingabe ()
    {	
    	double x;
     	printf ("\n Geben sie eine Zahl a ein : ");
     	scanf ("%lf", &x);
     	return (x);
    
    }
    double berechnung (double a)
    {	
    	double b;
    	b=2*a;
     	return (b);
    }
    

    also, dem "a" in "main" wird die zurückgegebene variable aus "eingabe" zugewiesen, und dei variable ais "eingabe" braucht in main nicht vereinbart werden. dann wird der variablen "b" aus "main" der rückgabewert aus der funktion "berechnen" zugewiesen. der rückgabewert aus "berechnen" nutz als parameter dei globale variable "a" aus main (deswegen muss ich doch beim aufruf, deklaration und prototyp das "double (a)" hinzufügne, oder?).
    ab jetzt kann ich also die globalen variablen "a" und "b" in der main benutzen,wie ich will.
    hoffe meine erklärung ist soweit richtig, dass ich auf ihr aufbauen kann, und größere programme mit den funktionen hinbekomme.
    vielen dank nochmal für eure antworten. die haben mir sehr geholfen. 👍



  • Es gibt in diesem Programm keine globalen Variablen. Nicht eine einzige.

    Vielleicht fällt es Dir leichter, den Zusammenhang (oder besser: nicht-Zusammenhang) zwischen den Variablen zu verstehen, wenn Du nicht immer dieselben Bezeichner nimmst. Folgendes Programm tut exakt dasselbe, wie Deins:

    #include <stdio.h>
    #include <conio.h>
    double eingabe ();
    double berechnung (double zuVerdoppeln);
    int main()
    {
        double eingabeWert = eingabe ();
        double ergebnis = berechnung (eingabeWert);
         printf (" Das Ergebnis aus 2*a = %.2lf", ergebnis);
        while(!kbhit());
         return 0;
    }    
    
    double eingabe ()
    {   
        double wert;
         printf ("\n Geben sie eine Zahl ein : ");
         scanf ("%lf", &wert);
         return (wert);
    
    }
    double berechnung (double zuVerdoppeln)
    {   
        double verdoppelt;
        verdoppelt=2*zuVerdoppeln;
         return (verdoppelt);
    }
    


  • bedeutet das, dass in:

    double berechnung (double zuVerdoppeln)
    {  
         double verdoppelt;
         verdoppelt=2*zuVerdoppeln;
         return (verdoppelt);
    }
    

    das "zuVerdoppeln" dem "eingabeWert" in

    double ergebnis = berechnung (eingabeWert);
    

    entspricht? also ist es egal, wie ich die parameter nenne. die funktion "berechnung" benötigt eine variable "zuVerdoppeln". die wird aus der main aus der zeile

    double ergebnis = berechnung (eingabeWert);
    

    entnommen.
    somit gilt dann, dass die funktion "berechnung" eine varibale aus der "main" mit dem namen "eingabeWert" holt, in der funktion für "zuVerdoppeln" einsetzt und damit den rückgabewert "verdoppelt" errechnet. stimmt das so?



  • Fast. Beim Aufruf der Funktion wird der Inhalt der Variablen 'eingabeWert' kopiert nach 'zuVerdoppeln' - und nachdem die Funktion fertig ist, schreibt das return den Inhalt von 'verdoppelt' in den Speicher (wo genau ist irrelevant) und das Hauptprogramm holt sich diesen Wert und schreibt ihn in 'ergebnis'.



  • so hab ich das auch verstanden, aber anscheinen nicht richtig beschrieben. aber egal, verstanden hab ich das. vielen dank nochmal. jetzt kann ihc mich schwierigeren programmen zuwenden. also dann wahrscheinlich bis zum nächsten "hilfe" thread^^


Anmelden zum Antworten