Unterschied zwischen “Zeiger auf Int” und “Zeiger auf Array von Ints”

Lesezeit: 6 Minuten

Benutzer-Avatar
Sandip

int main()
{
    int (*x)[5];                 //pointer to an array of integers
    int y[6] = {1,2,3,4,5,6};    //array of integers
    int *z;                      //pointer to integer

    z = y;
    for(int i=0;i<6;i++)
        printf("%d ",z[i]);

    x = y;
    for(int i=0;i<6;i++)
        printf("%d ",(*x)[i]);

    return 0;
}

Beide oben genannten printfs geben die Nummern 1 bis 6 aus.
Wenn beides“Zeiger auf Array von ganzen Zahlen” und “Zeiger auf Ganzzahl” können dasselbe tun, haben sie dieselbe interne Repräsentation?
BEARBEITEN: Dieser Code gibt Warnungen aus, wenn er kompiliert wird, wie in den Antworten unten angegeben, er druckt die Werte jedoch korrekt sowohl die Zeit auf meinem x86_64-Computer mit gcc

  • Diese Frage geht mir irgendwie auf die Nerven. Ich denke, ich werde int (*x) vermeiden[] Stilerklärungen für immer.

    – jdizzle

    7. März 2010 um 21:22 Uhr

  • @Sandip: Der Code wird kompiliert, weil die GCC-Fehlererkennung im Standardmodus zu locker ist. Es meldet Beschränkungsverletzungen als Warnungen. Dein x = y Zuordnung ist wirklich ein Fehler.

    – AnT steht zu Russland

    8. März 2010 um 4:58 Uhr

Benutzer-Avatar
AnT steht zu Russland

Erstens wird Ihr Code nicht kompiliert. Das Array hat einen Typ int[6] (6 Elemente), während der Zeiger einen Typ hat int (*)[5]. Sie können diesen Zeiger nicht so machen, dass er auf dieses Array zeigt, da die Typen unterschiedlich sind.

Zweitens müssen Sie beim Initialisieren (Zuweisen) eines solchen Zeigers die verwenden & auf dem Array: x = &ynicht nur eine Ebene x = y wie in deinem Code.

Ich gehe davon aus, dass Sie den Code einfach eingegeben haben, anstatt den echten Code zu kopieren und einzufügen.

Drittens über die interne Vertretung. Im Allgemeinen sollten Sie in der Praxis davon ausgehen, dass alle Datenzeiger dieselbe interne Darstellung verwenden. Außerdem haben die Zeiger nach den obigen Zuweisungen (bei richtiger Schreibweise) denselben numerischen Wert. Der Unterschied zwischen int (*)[5] und int * existiert nur auf der konzeptuellen Ebene, dh auf der Ebene der Sprache: Die Typen sind verschieden. Es hat einige Konsequenzen. Wenn Sie beispielsweise Ihre erhöhen z Es springt zum nächsten Mitglied des Arrays, aber wenn Sie inkrementieren yes springt über das gesamte Array usw. Diese Zeiger machen also nicht wirklich “das Gleiche”.

  • Der Unterschied zwischen int (*)[5] und int * existiert wahrscheinlich in der Symboltabelle … Nicht, dass diese Unterscheidung Ihren Standpunkt ändert.

    – dmckee — Ex-Moderator-Kätzchen

    7. März 2010 um 21:01 Uhr

  • @dmckee: Ich weiß nicht, was du genau meinst. Dies ist eine C-Frage. In C werden Namen normalerweise nicht entstellt, was bedeutet, dass es keinen Unterschied in der Symboltabelle gibt (wenn ich Sie richtig verstanden habe).

    – AnT steht zu Russland

    8. März 2010 um 4:53 Uhr

  • In der Symboltabelle speichert der Compiler die jeder Variablen zugeordneten Typinformationen; das heißt, dort wird der Compiler nachsehen, wie weit er einen Zeiger inkrementieren kann.

    – dmckee — Ex-Moderator-Kätzchen

    8. März 2010 um 14:08 Uhr

Die kurze Antwort: Es gibt einen Unterschied, aber Ihr Beispiel ist fehlerhaft.

Die lange Antwort:

Der Unterschied ist das int* zeigt auf einen int-Typ, aber int (*x)[6] zeigt auf ein Array von 6 Ints. Eigentlich drin dein Beispiel,

x = y;

Da es sich um ein undefiniertes ** Verhalten handelt, wissen Sie, dass es sich um zwei verschiedene Arten handelt, aber in C tun Sie, was Sie wollen. Ich verwende einfach einen Zeiger auf ein Array von sechs Ints.

Nehmen Sie dieses modifizierte Beispiel:

int (*x)[6];                 //pointer to an array of integers
int y[6] = {1,2,3,4,5,6};    //array of integers
int *z;                      //pointer to integer
int i;

z = y;
for(i = 0;i<6;i++)
    printf("%d ",z[i]);

x = y; // should be x = &y but leave it for now!

for(i = 0;i<6;i++)
    printf("%d ",x[i]); // note: x[i] not (*x)[i]

Zuerst,

1 2 3 4 5 6

Würde gedruckt werden. Dann kommen wir dazu x[0]. x[0] ist nichts als ein Array von 6 Ints. Ein Array in C ist die Adresse des ersten Elements. Also die Adresse von y gedruckt werden würde, dann die Adresse der next Array in der nächsten Iteration. Zum Beispiel auf meiner Maschine:

1 2 3 4 5 6 109247792 109247816 109247840 109247864 109247888 109247912

Wie Sie sehen können, ist der Unterschied zwischen aufeinanderfolgenden Adressen nichts anderes als:

sizeof(int[6]) // 24 on my machine!

Zusammenfassend handelt es sich um zwei unterschiedliche Zeigertypen.

** Ich denke, es ist ein undefiniertes Verhalten, bitte zögern Sie nicht, meinen Beitrag zu korrigieren, wenn er falsch ist.

Benutzer-Avatar
nur ein anderer Typ

Hoffe dieser Code hilft:

int main() {

    int arr[5] = {4,5,6,7,8};        
    int (*pa)[5] = &arr;
    int *pi = arr;

    for(int i = 0; i< 5; i++) {
        printf("\n%d %d", arr[i], (*pa)[i]);    
    }

    printf("\n0x%x -- 0x%x", pi, pa);
    pi++;
    pa++;
    printf("\n0x%x -- 0x%x", pi, pa);
}

druckt folgendes:

4 4
5 5
6 6
7 7
8 8
0x5fb0be70 -- 0x5fb0be70
0x5fb0be74 -- 0x5fb0be84 

AKTUALISIEREN:

Sie können feststellen, dass der Zeiger auf die Ganzzahl um 4 Bytes erhöht wird (Größe einer 32-Bit-Ganzzahl), während der Zeiger auf das Array der Ganzzahl um 20 Bytes erhöht wird (Größe von int arr[5] dh Größe von 5 int von jeweils 32 Bit). Dies zeigt den Unterschied.

Benutzer-Avatar
jamesdlin

Um Ihre Frage aus dem Titel zu beantworten, aus den häufig gestellten Fragen zu comp.lang.c: Da Array-Referenzen in Zeiger zerfallen, was ist der Unterschied zwischen arr und &arr, wenn arr ein Array ist?

Der von Ihnen gepostete Code weist jedoch andere Probleme auf (Sie weisen zu ynicht &y zu xund y ist ein Array mit 6 Elementen, aber *x ist ein Array mit 5 Elementen; beide sollten Kompilierungswarnungen generieren).

Wer weiß – dieser Code zeigt undefiniertes Verhalten:

printf("%d ",(*x)[i]);

Benutzer-Avatar
Nate

Hoffe, dieser Code hilft.


#include <stdio.h>
#include <stdlib.h>
#define MAXCOL 4
#define MAXROW 3

int main()
{      
      int i,j,k=1;
      int (*q)[MAXCOL];      //pointer to an array of integers

      /* As malloc is type casted to "int(*)[MAXCOL]" and every 
         element (as in *q) is 16 bytes long (I assume 4 bytes int), 
         in all 3*16=48 bytes will be allocated */

      q=(int(*)[MAXCOL])malloc(MAXROW*sizeof(*q)); 

      for(i=0; i<MAXROW; i++)
        for(j=0;j<MAXCOL;j++)
          q[i][j]=k++;


      for(i=0;i<MAXROW;i++){
        for(j=0;j<MAXCOL;j++)
          printf(" %2d ", q[i][j]);
        printf("\n");         
      } 
}

#include<stdio.h>

int main(void)
{
    int (*x)[6];                 //pointer to an array of integers
    int y[6] = {11,22,33,44,55,66};    //array of integers
    int *z;                      //pointer to integer
    int i;

    z = y;
    for(i = 0;i<6;i++)
        printf("%d ",z[i]);
    printf("\n");

    x = &y;

    for(int j = 0;j<6;j++)
        printf("%d ",*(x[0]+j));

    return 0;
}

//AUSGANG::

11 22 33 44 55 66

11 22 33 44 55 66

Zeiger auf ein Array eignen sich am besten für mehrdimensionale Arrays. aber im obigen Beispiel haben wir ein eindimensionales Array verwendet. also sollten wir in der zweiten for-Schleife (x[0]+j) mit *, um den Wert auszudrucken. Hier x[0] bedeutet 0. Array. Und wenn wir versuchen, den Wert mit printf(“%d “,x[i]); Sie erhalten den ersten Wert 11 und dann einen Müllwert, weil Sie versuchen, auf die erste Zeile des Arrays zuzugreifen, und so weiter.

1364200cookie-checkUnterschied zwischen “Zeiger auf Int” und “Zeiger auf Array von Ints”

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy