Différence entre “pointeur sur int” et “pointeur sur un tableau d’ints”

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; } 

Les printfs ci-dessus affichent les numéros 1 à 6.
Si les deux ” pointeur vers un tableau d’entiers ” et ” pointeur vers un entier ” peuvent faire la même chose, ont-ils la même représentation interne?
EDIT: Ce code donne des avertissements lorsqu’il est compilé comme indiqué par les réponses ci-dessous, mais il affiche les valeurs correctement à la fois sur l’heure sur ma machine x86_64 à l’aide de gcc

Premièrement, votre code ne sera pas compilé. Le tableau a le type int[6] (6 éléments), tandis que le pointeur a le type int (*)[5] . Vous ne pouvez pas faire en sorte que ce pointeur pointe vers ce tableau car les types sont différents.

Deuxièmement, lorsque vous initialisez (affectez à) un tel pointeur, vous devez utiliser le & sur le tableau: x = &y , pas simplement un x = y comme dans votre code.

Je suppose que vous avez simplement saisi le code au lieu de copier-coller le code réel.

Troisièmement, à propos de la représentation interne. En règle générale, dans la pratique, vous devez vous attendre à ce que tous les pointeurs de données utilisent la même représentation interne. De plus, après les assignations ci-dessus (si elles sont écrites correctement), les pointeurs auront la même valeur numérique. La différence entre int (*)[5] et int * n’existe que sur le plan conceptuel, c’est-à-dire au niveau du langage: les types sont différents. Cela a des conséquences. Par exemple, si vous incrémentez votre z il passera au membre suivant du tableau, mais si vous incrémentez y , il sautera sur tout le tableau, etc. Ainsi, ces pointeurs ne font pas vraiment la même chose.

La réponse courte: il y a une différence, mais votre exemple est imparfait.

La réponse longue:

La différence est que int* pointe sur un type int, mais que int (*x)[6] pointe sur un tableau de 6 ints. En fait, dans votre exemple,

 x = y; 

est un comportement non défini **, vous savez que ce sont deux types différents, mais en C vous faites ce que vous voulez. Je vais juste utiliser un pointeur sur un tableau de six ints.

Prenons cet exemple modifié:

 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] 

Premier,

 1 2 3 4 5 6 

Serait imprimé. Ensuite, nous arrivons à x[0] . x [0] n'est rien d'autre qu'un tableau de 6 ints. Un tableau en C est l'adresse du premier élément. Ainsi, l'adresse de y serait imprimée, puis l'adresse du tableau next lors de la prochaine itération. Par exemple, sur ma machine:

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

Comme vous pouvez le constater, la différence entre des adresses consécutives n’est autre que:

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

En résumé, ce sont deux types de pointeurs différents.

** Je pense que c'est un comportement indéfini, s'il vous plaît, n'hésitez pas à corriger mon message si c'est faux.

J’espère que ce code aide:

 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); } 

imprime ce qui suit:

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

UPDATE: Vous pouvez remarquer que le pointeur sur l'entier est incrémenté de 4 octets (taille de l'entier 32 bits) alors que le pointeur sur le tableau d'entiers incrémenté de 20 octets (la taille de int arr [5], c'est-à-dire la taille de 5 int de 32 bits chacune). Cela démontre la différence.

Pour répondre à votre question à partir du titre, à partir de la FAQ comp.lang.c: Puisque les références à un tableau se décomposent en pointeurs, si arr est un tableau, quelle est la différence entre arr et & arr?

Cependant, le code que vous avez posté a d’autres problèmes (vous assignez y , pas &y à x , et y est un tableau à 6 éléments, mais *x est un tableau à 5 éléments; tous deux devraient générer des avertissements de compilation). .

Qui sait – ce code présente un comportement indéfini:

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

J’espère que ce code aide.


 #include  #include  #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 
 #include 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; } 

//SORTIE::

11 22 33 44 55 66

11 22 33 44 55 66

Les pointeurs vers un tableau conviennent mieux à un tableau multidimensionnel. mais dans l'exemple ci-dessus, nous avons utilisé un tableau à une seule dimension. donc, dans la seconde boucle for, nous devrions utiliser (x [0] + j) avec * pour afficher la valeur. Ici, x [0] signifie 0ème tableau. Et lorsque nous essayons d’imprimer une valeur en utilisant printf ("% d", x [i]); vous obtiendrez la première valeur est 11, puis une valeur résiduelle en raison de la tentative d'access à la première ligne du tableau, etc.

Il faut comprendre la représentation interne de (*x)[i] . En interne, il est représenté par *((*x)+i) , qui n’est rien d’autre que le ième élément du tableau pointé par x. C’est aussi un moyen d’avoir un pointeur pointant sur un tableau 2D. Le nombre de lignes n’est pas pertinent dans un tableau 2D.

Par exemple:

 int arr[][2]={{1,2},{3,4}}; int (*x)(2); x=arr; /* Now x is a pointer to the 2d array arr.*/ 

Ici, x pointe vers un tableau 2D comportant 2 valeurs entières dans toutes les colonnes, et les éléments du tableau sont stockés de manière contiguë. Donc (*x)[0] imprimera arr[0][0] (qui est 1), (*x)[1] imprimera la valeur de arr[0][1] (qui est 2) et ainsi de suite . (*x+1)[0] affichera la valeur de arr[1][0] (3 dans ce cas) (*x+1)[1] imprimera la valeur de arr[1][1] (4 dans ce cas) et ainsi de suite.

Désormais, un tableau 1d ne peut être traité comme rien, mais un tableau 2d ne comportant qu’une seule ligne avec autant de colonnes.

 int y[6] = {1,2,3,4,5,6}; int (*x)[6]; x =y; 

Cela signifie que x est un pointeur sur un tableau ayant 6 entiers. Donc (*x)[i] qui est équivalent à *((*x)+i) affichera la valeur d’index de y .