Was konkret wird jeweils deklariert?



  • a) int vA;
    b) int** vC;
    c) int* vD [15];

    Wie es oben schon in der Frage steht, frage ich mich was hier deklariert wird.



  • Was glaubst du denn? Bzw. wo ist das Problem?

    Zur Not: https://cdecl.org/ und eingeben.


  • Gesperrt

    vA ist eine int-Variable
    vC ist ein int-Array
    vD ist wie vC ein int-Array, es werden aber 15 int-Pointer-Speicherplätze reserviert (Auto-Variable)

    So hätte ich es interpretiert

    Alle innerhalb eines Codeblocks deklarierten Variablen sind standardmäßig automatisch, dies kann jedoch mit dem Schlüsselwort auto explizit gemacht werden.

    Eine nicht initialisierte automatische Variable hat einen undefinierten Wert, bis ihr ein gültiger Wert ihres Typs zugewiesen wird. Die Verwendung der Speicherklasse register anstelle von auto ist ein Hinweis an den Compiler, die Variable in einem Prozessorregister zwischenzuspeichern.

    Abgesehen davon, dass der Referenzierungsoperator (&) nicht für die Variable oder eine ihrer Unterkomponenten verwendet werden darf, steht es dem Compiler frei, den Hinweis zu ignorieren. In C++ wird der Konstruktor von automatischen Variablen aufgerufen, wenn die Ausführung den Ort der Deklaration erreicht.

    Der Destruktor wird aufgerufen, wenn er das Ende des gegebenen Programmblocks erreicht (Programmblöcke sind von geschweiften Klammern umgeben).

    Übersetzt mit www.DeepL.com/Translator (kostenlose Version)


  • Mod

    Ist aber falsch.



  • @EinNutzer0 sagte in Was konkret wird jeweils deklariert?:

    vC ist ein int-Array

    Wie kommst du darauf? Das ist kein Array.

    vD ist wie vC ein int-Array, es werden aber 15 int-Pointer-Speicherplätze reserviert (Auto-Variable)

    vD ist in der Tat ein Array (Länge 15, Inhalt: Pointer auf int)


  • Gesperrt

    Dann ist es ein Zeiger auf das erste Element eines Arrays von int-Pointern (vermutlich)

    @wob sagte in Was konkret wird jeweils deklariert?:

    Das ist kein Array.

    Pointer auf Pointer sind doch ein Array, nur eben nicht initialisiert.



  • @EinNutzer0 sagte in Was konkret wird jeweils deklariert?:

    Dann ist es ein Zeiger auf das erste Element eines Arrays von int-Pointern (vermutlich)

    Soll das ein Ratespiel sein?

    https://en.cppreference.com/w/c/language/array
    https://en.cppreference.com/w/c/language/pointer

    Arrays sind die Dinger mit den eckigen Klammern.

    Ob ein Zeiger irgendwo in ein Array zeigt oder nicht, ist für die Fragestellung erstmal irrelevant.

    Pointer auf Pointer sind doch ein Array, nur eben nicht initialisiert.

    Nein.



  • @EinNutzer0 https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay, siehe auch das klassiche Problem mit sizeof, wenn man ein Array versucht in ne Funktion zu geben.


  • Gesperrt

    @Leon0402 sagte in Was konkret wird jeweils deklariert?:

    @EinNutzer0 https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay, siehe auch das klassiche Problem mit sizeof, wenn man ein Array versucht in ne Funktion zu geben.

    Danke!


  • Gesperrt

    Aber ich denke, ich habe jetzt mehr Fragezeichen als vorher 😆



  • @EinNutzer0 sagte in Was konkret wird jeweils deklariert?:

    Aber ich denke, ich habe jetzt mehr Fragezeichen als vorher 😆

    Auch irgendwas konkrektes? Ich bin mir nicht sicher, wie ich helfen kann. Lies dir am besten mal die beiden Seiten zu Array und Pointer auf cppreference (mein Post oben) durch.

    Ein Pointer auf Pointer kannst du auch verwenden, um z.B. eine Pointervariable aus einer Funktion für den Aufrufer zu ändern (praktisch wie call-by-reference für einen einfachen Pointer). Es muss da kein Array involviert sein.


  • Mod

    Denk dir halt nichts aus, was da nicht steht. Wie kommst du überhaupt auf Arrays, wenn da Sternchen stehen? Arrays sind was mit eckigen Klammern, Sternchen sind was mit Pointern. Daher kann b) nichts mit Arrays zu tun haben, sondern muss mindestens 2x das Wort Pointer beinhalten. c) muss irgendwas mit einer Instanz von Array und einer Instanz von Pointer sein, und es ist nur eine Frage, wie man das lesen muss, um auf die richtige Reihenfolge zu kommen.

    Bei der Reihenfolge gilt innen nach außen und von rechts nach links. Hier gibt es kein "innen", aber von rechts nach links ist vD demnach ein Array[15]. Array[15] von was? Dem links daneben, also Array[15] von Pointer. Array[15] von Pointer auf was? Dem links daneben, also Array[15] von Pointer auf int. Fertig.

    Das macht dir, wie schon gesagt, auch cdecl.org, was du offenbar nicht beachtet hast: https://cdecl.org/?q=int*+vD+[15]%3B

    PS: Ich weiß natürlich, wie du auf Arrays kommst, wenn da Sternchen stehen. Weil dir irgendjemand Array-zu-Pointer-Zerfall schlecht erklärt hat. Ich versuche es mal besser zu erklären: Die ganze Problematik betrifft ausdrücklich nur die alleräußerste Ebene der Typen (also ganz rechts, wenn du es in C aufschreibst, bzw. ganz links wenn du es auf Deutsch sagst). Dann und nur dann wenn diese Ebene ein Array ist, dann verhält sich dieses Array (bis auf einige wenige Ausnahmen wie sizeof) wie ein Pointer (auf sein erstes Element). In dem Beispiel oben ist vD ein Array[15] von Pointer auf int, die alleräußerste Ebene ist also tatsächlich ein Arraytyp. vD wird sich also so verhalten wie ein Pointer auf Pointer auf int.
    Hätten wir stattdessen int (*vE)[15] (also ein Pointer auf ein Array[15] von int), so wäre die äußerste Ebene ein Pointer, kein Array. Dieses vE wird also niemals in so etwas wie Pointer auf Pointer auf int zerfallen, sondern sich absolut überall wie ein Pointer auf ein Array[15] von int verhalten.

    Das hat natürlich gewisse Implikationen für Funktionaufrufe. Wenn ein äußerer Arraytyp sich wie ein Pointer verhält, dann ist er damit ja auch ein gültiges Argument für Funktionen, die eigentlich einen Pointer erwarten. Und umgekehrt kann ein Funktionsparameter niemals einen Arraytyp in der äußersten Ebene haben, denn es zerfällt ja sofort zu einem Pointer. Daher ist void foo(int a[5]) das gleiche wie void foo(int *b), weil das a sofort zu einem Pointer zerfällt. Und hier (bei Funktionsparametern) ist dann die eine Ausnahme: Dieses a ist dann wirklich ein Pointer, kein zerfallenes Array, und selbst mit etwas wie sizeof(a) würde man die Größe eines Pointers bekommen, nicht 5*sizeof(int).


  • Gesperrt

    Aber, ein Pointer auf einen (int-)Pointer ergibt doch keinen Sinn.

    Wäre dann bei: int ********* what; "Declaration of Pointer of Pointers" die richtige Antwort?

    Und an das "Viech" vC könnte ich doch auch ein Array zuweisen, oder ginge das nicht... : vC = int*[15];

    ... sagen wir so, es sieht zumindest abenteuerlich aus.


  • Mod

    @EinNutzer0 sagte in Was konkret wird jeweils deklariert?:

    Aber, ein Pointer auf einen (int-)Pointer ergibt doch keinen Sinn.

    Wieso nicht? Wie würdest du sonst einen Pointer an eine Funktion übergeben, wenn dieser dort verändert werden soll?

    Ein bisschen albern sinnloses Beispiel, aber ich habe gerade keine Lust, dir komplexe Datenstrukturen zu erklären:

    #include <stdio.h>
    
    void next(int **ptr)
    {
      (*ptr) += 1;
    }
    
    int main(void) {
    	int array[] = {1,2,3,0};
    	int *iterator = array;
    	while(*iterator)
    	{
    		printf("%d ", *iterator);
    		next(&iterator);
    	}
    }
    

    Zu deinen anderen Fragen:
    Offensichtlich hast du immer noch nicht einmal die mehrmals verlinkte Webseite auch nur angesehen, noch hast du mal versucht deinen tollen Codevorschlag auszuprobieren. Ich stecke in diesen Satz alleine (er hat sogar ein Komma!) schon mehr Mühe als du dir mit deinen Fragen gibst, warum sollte ich Antworten geben, die du in Sekunden selber hättest herausfinden können?


  • Gesperrt

    @SeppJ Schau es dir an:

    https://ibb.co/H7K8CGL

    ist nicht erlaubt, aber die Frage bleibt warum?


  • Mod

    Weil das keine Deklaration ist…



  • @EinNutzer0 Schau dir mal die Standardfunktion strtol an.
    Da ist endptr es zwar ein **char, aber das Prinzip ist das Gleiche.

    https://cplusplus.com/reference/cstdlib/strtol/