Was bedeutet int (T*)[3]



  • Hallo zusammen

    Ich habe mal eine Frage zu 2D Arrays. (C Arrays)

    In meinem Buch steht, das man C Arrays an eine Funktion übergeben kann.
    Man soll die Größe der Array mitgeben, damit die Funktion weis, wie groß die Array ist.

    Jedoch verstehe ich eine Sache überhaupt nicht.

    Wenn man eine 2D c-Array an eine Funktion übergibt. Muss man ja Dann auch 2 Werte übergeben. (x und y)
    Jedoch gäbe es laut Autor die Möglichkeit, das diese Informationen (teilweise) in den Typ mit einfließen. Jedoch verstehe ich ab hier überhaupt nichts mehr

    Hier ein Beispiel.

    Ich möchte eine 2D int Array übergeben.

    Int array2d [2][3] = {{...}{...}};
    
    int funktion(int (*T)[3], size_t n)
    {
    ...
    }
    

    Was soll
    int (*T)[3]
    bewirken?



  • Das bedeutet, dass T ein Zeiger auf ein int-Array mit 3 Elementen ist. Verabschiede dich von dem Gedanken, dass es 2d-Arrays gibt. Es gibt nur Arrays. ein "mehrdimensionales" Array ist ein Array, dessen Elemente Arrays sind.



  • Ok. Mit 2D Arrays meine ich ja natürlich mehrdimensionale Arrays.

    Also zeigt T auf array2d[0]?

    Und T[2] ist also array2D[0][2]. Oder?

    Kann mir einer grade nebenbei noch erklären was Arrays mit Zeigern zu tuen haben? Das begreife ich auch nicht so richtig.

    Was Zeiger sind weis ich.



  • Sebastian Müller schrieb:

    Also zeigt T auf array2d[0]?

    Ja.

    Und T[2] ist also array2D[0][2]. Oder?

    Ja.
    Nein, siehe campers Antwort weiter unten.

    Kann mir einer grade nebenbei noch erklären was Arrays mit Zeigern zu tuen haben? Das begreife ich auch nicht so richtig.

    Wäre gut, wenn du sagen würdest, was genau du nicht verstehst.



  • Ich meinem Buch wird immer beschrieben, das Arrays Zeiger wären. Stimmt das?

    Wenn ja...

    Ist die Array selbst der Zeiger, oder nur seine Elemente?



  • Ein Array ist kein Zeiger.
    Ein Array ist ... naja, eben ein Array. Ein Ding das aus mehreren "Objekten" des selben Typs besteht, die hintereinander im Speicher liegen.

    In C und C++ werden allerdings oft Zeiger auf das erste Element eines Arrays übergeben, und dann über die ptr[index] Syntax auf Elemente des Arrays zugegriffen.
    Deswegen ist ptr aber noch lange kein Array und das Array auch kein Zeiger.

    Was die Sache noch verwirrender macht, ist, dass Arrays, so man sie an einer Stelle hinschreibt wo ein Zeiger erwartet wird, automatisch in einen Zeiger auf ihr erstes Element konvertiert werden.
    Nennt sich "array to pointer decay" - google den Begriff.



  • Ahhhhh jetzt habe Ich es verstanden.

    Ich habe mich gewundert warum man Anstelle eines richtigen Zeiger ,eine Array einsetzten kann. Bei Funktionsparametern bsw.

    Danke für eure Hilfe.



  • Sebastian Müller schrieb:

    Ich meinem Buch wird immer beschrieben, das Arrays Zeiger wären. Stimmt das?

    Nein, das ist völlig falsch. Wenn das da wirklich so drin steht, solltest du das Buch wahrscheinlich wegwerfen, der Autor hat etwas wesentliches nicht verstanden.

    Ein Array ist eine Anordnung von Elementen gleichen Typs hintereinander im Speicher. Wenn ein Array in einem Ausdruck auftaucht (mit wenigen Ausnahmen, z.B. sizeof), wird es in einen Zeiger auf sein erstes Element umgewandelt. Mit diesem Zeiger kann man dann auf die folgenden Elemente des Arrays zugreifen, d.h. ein Ausdruck wie array[5] ist eigentlich eine Abkürzung für *((&array[0]) + 5).



  • Ich habe diese Textstelle nochmal im Buch nachgelesen, und hatte mich damals wohl verlesen.

    Der Autor meint das selbe wie ihr.

    Ich kann das Buch wohl behalten. 😋



  • Nochmals Danke für die Aufklärung.



  • Sebastian Müller schrieb:

    Ich habe mich gewundert warum man Anstelle eines richtigen Zeiger ,eine Array einsetzten kann. Bei Funktionsparametern bsw.

    Funktionsparameter sind ein (hässlicher) Sonderfall. Ein Funktionsparameter, der als Array deklariert ist, ist sogar immer gleichbedeutend mit einem Zeiger.

    Beispiel:

    void f(int array[2][3]);
    // ist gleichbedeutend mit
    void f(int (*array)[3]);
    

    Das geht über den Array->Zeiger-Zerfall hinaus, beispielsweise kann man sowas machen, was mit Arrays nicht funktioniert (da der Zeiger, der sich durch den Zerfall ergibt, ein rvalue ist):

    void f(int array[2][3]) {
      ++array; // zeigt nun auf das ehemalige Element array[1]
    }
    

  • Mod

    Bashar schrieb:

    Und T[2] ist also array2D[0][2]. Oder?

    Ja.

    T[2] innerhalb der Funktion ist äquivalent zu array2D[2] ausserhalb der Funktion, beides verweist auf den Bereich unmittelbar hinter dem (äußeren) Array (weil das ja nur 2 Elemente hat).



  • Ups, richtig.


Log in to reply