2 Fragen zu Arrays + Funktionen



  • Hallo,
    ich habe eine Funktion, wo als Parameter ein 2-Dimensionales Array benötigt wird. Nun wie soll ich es am besten übergeben, da es innerhalb der Funktion bearbeitet wird. Sollte ich lieber direkt einen Pointer übergeben oder einen Pointer innerhalb der Funktion auf das Array setzen?

    Nun noch meine 2. Frage:
    Ich habe wieder eine Funktion und innerhalb soll ein neues Array erstellt werden. Wie kann ich das anstellen, da ich ja bei der Dimension eine Konstante brauche?
    Oder kann ich das Problem nur mit einem Vector lösen?

    void Funktion(const int DIM)
    {
        int arr[DIM]; //Geht nicht... aber dachte DIM ist eine konstante?!
    }
    

    Gruß Speedy_92



  • Was macht eine Funktion mit einer Konstanen als Parameter für einen Sinn?
    Da kannst du den gleich rausnehmen. 🙄

    Die Übergabe wird normalerweise mittels eines Zeigers auf den Anfang des Arrays + 1 oder 2 Dimensionen angegeben.



  • du kannst es über einen std::vector lösen, was die eleganter variante ist oder dein array mittels new[] erzeugen also:

    void Funktion(const int DIM)
    {
        int *arr=new int[DIM];
    }
    

    DIM ist hier konstant, aber keine konstante, da es zum zeitpunkt des kompilierens nicht bekannt ist.



  • Array als Parameter:

    void Funktion(int (*ptr_arr)[])
    {
    
    }
    

    So richtig?!
    Aber eine Frage noch:
    Wie kann ich nun auf die einzelnen Ints zugreifen?
    So in entwa?:

    //Innerhalb der Funktion
    ptr_arr[2] //???
    

    Mein Problem ist dabei halt nur das es 2-Dimensional ist... Bei einer Dimension würde ich es hinbekommen.



  • nein. foo[] ist ein zeiger, da c/c++ keinen unterschied zwischen zeigern und arrays macht. daher übergibt man ein array ohne bestimmte größe so:

    void Funktion(int arr[]);
    

    oder

    void Funktion(int *arr);
    

    die beiden ausdrücke sind identisch. welchen man lieber benutzt, ist geschmackssache.

    zugriff auf ein so übergebenes array, funktioniert wie sonst auch:

    void Funktion(int *arr)
    {
     ptr[0]; //für das erste element
    }
    

    bzw.

    void Funktion(int arr[])
    {
     ptr[0]; //für das erste element
    }
    


  • ghorst schrieb:

    nein. foo[] ist ein zeiger, da c/c++ keinen unterschied zwischen zeigern und arrays macht. daher übergibt man ein array ohne bestimmte größe so:

    void Funktion(int arr[]);
    

    oder

    void Funktion(int *arr);
    

    die beiden ausdrücke sind identisch. welchen man lieber benutzt, ist geschmackssache.

    zugriff auf ein so übergebenes array, funktioniert wie sonst auch:

    void Funktion(int *arr)
    {
     ptr[0]; //für das erste element
    }
    

    bzw.

    void Funktion(int arr[])
    {
     ptr[0]; //für das erste element
    }
    

    Aber wenn ich ein 2-Dimensionales nehme bekomme ich folgenden Fehler:

    Feldindex fehlt
    
    void Funktion(int arr[][])
    


  • das mit dem zweidimensional hatte ich jetzt gerade überlesen. da hast du die freie wahl, wie du * und [] zusammensetzt. also möglich sind "int **arr", "int * arr[]" oder "int arr[][]". sind syntaktisch alle gleich. semantisch sollte zumindest von der mittleren variante die finger lassen, da die eher impliziert, dass man keine matrix hat.
    beim erzeugen mit new musst du darauf achten, dass du zuerst nur ein array von pointer erzeugst und diese dann auch noch gefüllt werden müssen.
    also:

    int **arr;
    arr=new (int*)[DIM];
    for (unsigned int i=0;i<DIM;++i)
    	arr[i]=new int[DIM];
    


  • du kannst bei arrays nur die erste dimmension offen lassen. die zweite
    musst du angeben damit der kompiler das richtige feld findet

    int arr1[10][10];
    
    arr1[1][0] // 10tes element
    
    inr arr2[10][100000000000];
    
    arr2[1][0] // 100000000000tes element
    


  • ghorst schrieb:

    nein. foo[] ist ein zeiger, da c/c++ keinen unterschied zwischen zeigern und arrays macht.

    Nein! C++ macht sehr wohl einen Unterschied zwischen Arrays und Zeiger, nur bei der Parameterübergabe spielt die Syntax keine Rolle. Hier gab es eine Diskussion zu diesem Thema.

    Ausserdem dürfte Folgendes wegen der Klammern um int* zu einem Fehler führen:

    ghorst schrieb:

    int **arr;
    arr=new (int*)[DIM];
    

    Und jeden Speicher, den man mit new anfordert, muss man mit delete wieder löschen. Gleiches gilt für new[] beziehungsweise delete[] .

    Nicht zuletzt deswegen (und auch, weil man auf die explizite Übergabe der Dimension verzichten kann) lohnt sich auch der Einsatz von STL-Containern, z.B. std::vector .



  • @nexus in der diskussion geht es um statische arrays, die zwar auch zeiger sind, aber eben nicht auf den heap und dafür von dem compiler reserviert werden müssen. aber eigentlich ist das alles egal, da ich nicht von statischen arrays sprach.
    ansonsten macht c++ null unterschied. ob du nun int[] oder *int zu dem ding sagst, ist gleich. dein hinweis, dass die klammerung zu einem fehler führt halte ich für falsch.



  • Okay. Ich wollte eigentlich nur Missverständnisse vermeiden, weil pauschalisierende Aussagen wie "C/C++ macht keinen Unterschied zwischen Zeigern und Arrays" schon sehr verwirren können.

    Und was die Klammerung angeht: Kompiliert

    int **arr;
    arr=new (int*)[DIM];
    

    bei dir? Wenn ja, was für eine IDE/welchen Compiler benutzt du?

    Die Klammer nach dem new ist eigentlich dazu da, zusätzliche Argumente an den new -Operator zu übergeben, z.B. nothrow .



  • c++ null unterschied. ob du nun int[] oder *int zu dem ding sagst

    Inkrementier mal einen Zeiger und inkrementier mal ein Array. 🙄



  • Was ich noch nicht so ganz verstehe ist, warum man bei einem Array als Parameter keine Referenz machen muss um es zu ändern...:

    void Funk(int arr[10])
    {
        arr[0] = 0; //Wird geändert
    }
    

    wenn ich das gleiche mit einer normalen int-Variable machen würde, dann würde sie ja nicht geändert werden:

    void Funk(int var)
    {
        var = 5; //Wird nicht geändert
    }
    

    Ich hoffe das stimmt was ich hier sage 🤡



  • Ein Array wird immer per Referenz übergeben.

    Das heisst, wenn du eine Kopie haben willst, musst du die selber anlegen, oder std::vector o.ä. benutzen.



  • ghorst schrieb:

    ansonsten macht c++ null unterschied. ob du nun int[] oder *int zu dem ding sagst, ist gleich.

    Arrays sind keine Lvalues. Zeiger schon. Siehe drakon 😉



  • Speedy_92 schrieb:

    Was ich noch nicht so ganz verstehe ist, warum man bei einem Array als Parameter keine Referenz machen muss um es zu ändern.

    Verständlich gesagt: Bei der Übergabe eines Arrays ist es so als würdest du einen Zeiger übergeben, deswegen weiß die Funktion, wo sich das Array im Speicher befindet und kann es somit modifizieren.



  • Vielen Dank. Alles klar geworden 🙂



  • Du musst dir bei der Übergabe eines Arrays immer die Dimension als zusätzlichen Parameter übergeben (oder du arbeitest mit konstanten Werten), da sizeof innerhalb der Funktion nicht das gewünschte Ergebnis erzielt, weil die Grösse des Zeigers ermittelt wird.

    ➡ Wieder ein Grund für std::vector 😉



  • Nexus schrieb:

    Du musst dir bei der Übergabe eines Arrays immer die Dimension als zusätzlichen Parameter übergeben (oder du arbeitest mit konstanten Werten), da sizeof innerhalb der Funktion nicht das gewünschte Ergebnis erzielt, weil die Grösse des Zeigers ermittelt wird.

    ➡ Wieder ein Grund für std::vector 😉

    Naja... ich möchte ein Feld erstellen. Damit möchte ich hinterher arbeiten, also z.B. mit WINAPI zeichnen... Deshalb finde ich es in diesem Moment schöner mit einer Konstanten Dimension zu arbeiten.



  • Ja, das ist schon okay.

    Behalte einfach den vector im Hinterkopf, falls du einmal dynamische Arrays benötigst 😉


Anmelden zum Antworten