Übergabe von Array an Funktion



  • Weil zur Laufzeit keine Informationen über die Größe des Array mitgegeben werden

    warum ist das dann in der main methode möglich, die länge herauszufinden?
    findet das nicht zu laufzeit statt?!

    danke schon mal!



  • warum ist das dann in der main methode möglich, die länge herauszufinden?
    findet das nicht zu laufzeit statt?!

    Nein. In C gibt es nach der Kompilierung keine Typinformationen mehr (außer du übergibst sie selbst irgendwie).

    So wird

    int myArray[] = {1,40,6,8,9};
    int cnt = sizeof(myArray)/sizeof(int);
    

    zu

    int myArray[] = {1,40,6,8,9};
    int cnt = 5;
    

    kompiliert. D.h. zur Laufzeit sind nur noch Konstanten vorhanden, "sizeof" hat nur den Zweck dass du die Konstante nicht direkt in den Code schreiben musst sondern der Compiler dir die Berechnung abnimmt. Hat den Vorteil dass du die Konstante bei änderungen nicht manuell umschreiben musst sondern nur neukopilierst.



  • Norben schrieb:

    warum ist das dann in der main methode möglich, die länge herauszufinden?

    Weil in der main-Funktion die Länge separat mit übergeben wird?!
    Weil es dort Vereinbarungen gibt, die besagen, dass mit NULL belegte Elemente als Ende des Arrays anzusehen sind?! (genauso wie bei char-Arrays mit '\0', dann spricht man von Strings)
    Dein Lehrer hat keine Ahnung, wenn er solche Aufgabenstellungen vorgibt.



  • Norben schrieb:

    warum ist das dann in der main methode möglich, die länge herauszufinden?

    Weil das Array (hier) in main definiert wurde. Dadurch ist es eindeutig.

    Noch ein Tipp:
    Statt sizeof(myArray)/sizeof(int); nehmt besser

    sizeof(myArray)/sizeof(myArray[0]);
    //oder 
     sizeof(myArray)/sizeof(*myArray);
    

    Dann braucht ihr euch da keine Gedanken um den Typ zu machen.
    Falls der mal geändert wird, braucht ihr dort keine Anpassung zu machen.

    Wie sieht eure Min/Max-Funktion denn jetzt aus?



  • Wie sieht eure Min/Max-Funktion denn jetzt aus?

    Wir haben die Arraylänge mit übergeben. So funktioniert es. Uns hat nur interessiert, ob es eben auch anders geht, da die Aufgabenstellung lautete:

    Implementieren und testen Sie folgende C-Funktionen:
    int maxValue(int a[]); //liefert das größte Element der Array zurück

    int main(int argc, const char * argv[])
    {	
        int a[] = {200,5,4,3,2,1};
        int cnt = sizeof(a)/sizeof(int);
    
        printf("maxValue: %i \n", maxValue(a,cnt));
    
        return(0);
    }
    
    int maxValue(int a[], int cnt)
    {
        doSort(a,cnt);
        return a[cnt-1];
    }
    

  • Mod

    Fällt euch denn keine wesentlich einfachere Möglichkeit ein, das Maximum einer Reihe Zahlen zu finden, als diese zu sortieren? Wenn ich dir in echt ein paar Karten mit Zahlen* und die gleiche Aufgabe geben würde, wie würdest du vorgehen?

    *: Es sind zu viele Karten, als dass du auf einem Blick das Maximum sehen könntest.



  • SeppJ schrieb:

    Wenn ich dir in echt ein paar Karten mit Zahlen* und die gleiche Aufgabe geben würde, wie würdest du vorgehen?

    Durchblättern und immer die gerade Größte rauslegen, bis eine neue Größere kommt. Also in C die einzelnen Werte in eine Variable legen und immer mit dem nächsten Element vergleichen, falls dieses Größer, die Variable überschreiben?


  • Mod

    Klingt nach einer guten Idee. Versuch das doch mal. Als leicht fortgeschrittenere Aufgabe kannst du auch noch mal darüber nachdenken, welche der beiden Techniken (Sortieren oder die neue Idee) wohl schneller ist und warum.



  • Ist wahrscheinlich effizienter, weil beim Sortieren das Array mehrfach durchlaufen werden muss, bis die Reihenfolge passt und hier das Array nur ein mal durchlaufen wird?

    int maxValue(int a[], int cnt)
    {
        int max;
        for(int i=0 ; i<cnt ; i++)
        {
            if(a[i] > a[i-1])
            {
                max = a[i];
            }
        }
        return max;
    }
    

  • Mod

    Norben schrieb:

    Ist wahrscheinlich effizienter, weil beim Sortieren das Array mehrfach durchlaufen werden muss, bis die Reihenfolge passt und hier das Array nur ein mal durchlaufen wird?

    Ja. Wobei beim Sortieren nicht wirklich von vorne nach hinten durchgelaufen wird, aber insgesamt sind beim Sortieren viel mehr Zugriffe nötig als es Elemente im Array gibt. Beim Maximumsucher, so wie hier, braucht es hingegen nur einen Zugriff pro Arrayelement.

    int maxValue(int a[], int cnt)
    {
        int max;
        for(int i=0 ; i<cnt ; i++)
        {
            if(a[i] > a[i-1])
            {
                max = a[i];
            }
        }
        return max;
    }
    

    Das ist so noch nicht richtig. Sieht zwar auf den ersten Blick so aus, ist es aber nicht.



  • SeppJ schrieb:

    Das ist so noch nicht richtig.

    Achso, okay, da war ein Fehler drin.

    int maxValue(int a[], int cnt)
    {
        int max = 0;
        for(int i=0 ; i<cnt ; i++)
        {
            if(a[i] > max)
            {
                max = a[i];
            }
        }
        return max;
    }
    


  • Was ist, wenn nur negative Zahlen im Array stehen?
    Dann ist max die größte Zahl, obwohl sie gar nicht vorkommt.
    max muss als Initialisierungswert den kleinst möglichen Wert eines ints haben.
    Den bekommst du via INT_MIN aus limits.h.


  • Mod

    Nathan schrieb:

    Was ist, wenn nur negative Zahlen im Array stehen?
    Dann ist max die größte Zahl, obwohl sie gar nicht vorkommt.
    max muss als Initialisierungswert den kleinst möglichen Wert eines ints haben.
    Den bekommst du via INT_MIN aus limits.h.

    Und wenn es sich nicht um ints handelt (Mal angenommen wir schreiben eine typunabhängige Funktion)? Oder wenn das Array leer ist(das betrifft auch den aktuellen Code)? Es gibt da eine bessere Idee für den Anfangswert...



  • SeppJ schrieb:

    Nathan schrieb:

    Was ist, wenn nur negative Zahlen im Array stehen?
    Dann ist max die größte Zahl, obwohl sie gar nicht vorkommt.
    max muss als Initialisierungswert den kleinst möglichen Wert eines ints haben.
    Den bekommst du via INT_MIN aus limits.h.

    Und wenn es sich nicht um ints handelt (Mal angenommen wir schreiben eine typunabhängige Funktion)? Oder wenn das Array leer ist(das betrifft auch den aktuellen Code)? Es gibt da eine bessere Idee für den Anfangswert...

    Stimmt. 👍



  • Okay stimmt, negative Zahlen gibt es auch noch. 🙂

    Mit der limits.h Variante würde ich min einfach INT_MIN zuweisen? (min = INT_MIN;)? Und dahinter verbirgt sich quasi -32768?

    Und wenn es sich nicht um ints handelt (Mal angenommen wir schreiben eine typunabhängige Funktion)? Oder wenn das Array leer ist(das betrifft auch den aktuellen Code)? Es gibt da eine bessere Idee für den Anfangswert...

    Bekomme ich leider nicht heraus. Der restliche Code stimmt aber soweit, es geht nur noch um den Anfangswert?


  • Mod

    Norben schrieb:

    Okay stimmt, negative Zahlen gibt es auch noch. 🙂

    Mit der limits.h Variante würde ich min einfach INT_MIN zuweisen? (min = INT_MIN;)? Und dahinter verbirgt sich quasi -32768?

    Ja. Wobei INT_MIN aber in der Regel wesentlich kleiner sein wird, eher so etwas wie -2 hoch 31.

    Und wenn es sich nicht um ints handelt (Mal angenommen wir schreiben eine typunabhängige Funktion)? Oder wenn das Array leer ist(das betrifft auch den aktuellen Code)? Es gibt da eine bessere Idee für den Anfangswert...

    Bekomme ich leider nicht heraus. Der restliche Code stimmt aber soweit, es geht nur noch um den Anfangswert?

    Letzter Tipp bevor ich es verrate (ja, es ist schwer da drauf zu kommen): Der Anfangswert muss ja nicht der kleinstmögliche Wert überhaupt sein, es muss bloß irgendein Wert sein, von dem du weißt, dass er höchstens so groß ist wie das Maximum in der Menge. Aus welcher Wertemenge könnte solch ein Wert kommen? 😉

    Ansonsten ist der Code soweit richtig. Wenn du drauf kommst, was ein besserer Startwert wäre, ergeben sich ein paar Änderungen von ganz alleine.



  • int max = minValue(a, cnt);
    

    Wobei das ja weniger effizent wäre. Ich komm echt nicht drauf. :p


  • Mod

    Einfach irgendein Wert aus dem Feld, zum Beispiel der erste.

    Wenn man es weiß, ist es ganz einfach, aber man kommt einfach nicht drauf. :p



  • SeppJ schrieb:

    Einfach irgendein Wert aus dem Feld, zum Beispiel der erste.

    Und wie löst du damit das Problem eines leeren Arrays? Das war immerhin einer deiner Einwände gegen INT_MIN (und eigentlich auch der einzige, weil es typunabhängige Funktionen in C nicht gibt). Ich warte schon die ganze Zeit auf deinen Vorschlag...



  • Achso, danke. Da wäre ich nicht drauf gekommen.^^

    [...]typunabhängige Funktionen in C nicht gib

    Mit generischen Pointern ist das aber möglich oder?


Anmelden zum Antworten