Quelle est la différence entre les déclarations suivantes :
Quelle est la règle générale permettant de comprendre les déclarations plus complexes ?
Quelle est la différence entre les déclarations suivantes :
Quelle est la règle générale permettant de comprendre les déclarations plus complexes ?
Je ne sais pas si elle a un nom officiel, mais je l'appelle le Droit-Gauche "Truc" (TM).
Commencer à la variable, puis aller à droite et à gauche, et à droite...et ainsi de suite.
int* arr1[8];
arr1 est un tableau de 8 pointeurs vers des entiers.
int (*arr2)[8];
arr2 est un pointeur (la parenthèse bloc de droite à gauche) à un tableau de 8 entiers.
int *(arr3[8]);
arr3 est un tableau de 8 pointeurs vers des entiers.
Cela devrait vous aider, avec le complexe des déclarations.
La réponse pour les deux derniers peuvent également être déduit de la règle d'or dans C:
Déclaration d'utilisation.
int (*arr2)[8];
Qu'advient-il si vous déréférencement de arr2? Vous obtenez un tableau de 8 entiers.
int *(arr3[8]);
Ce qui se passe si vous prenez un élément de arr3? Vous obtenez un pointeur vers un entier.
Cela aide également lorsque vous traitez avec des pointeurs de fonctions. Pour prendre sigjuice de l'exemple:
float *(*x)(void )
Ce qui se passe quand vous déréférencement de x? Vous obtenez une fonction que vous pouvez appeler sans arguments. Ce qui se passe quand vous l'appelez? Il retournera un pointeur sur un char.
La priorité de l'opérateur est toujours délicat, si. Cependant, l'utilisation de parenthèses peuvent aussi être source de confusion en raison de la déclaration suivante de l'utilisation. Au moins, pour moi, intuitivement arr2 ressemble à un tableau de 8 pointeurs vers des entiers, mais il est en fait l'inverse. Faut juste un peu s'y habituer. Une raison suffisante pour toujours ajouter un commentaire à ces déclarations, si vous me demandez :)
edit: exemple
En passant, j'ai juste trébuché à travers la situation suivante: une fonction statique de la matrice et qui utilise l'arithmétique des pointeurs pour voir si le pointeur de la ligne est hors limites. Exemple:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_ELEM(ar) (sizeof(ar) / sizeof((ar)[0]))
int *
put_off(const int newrow[2])
{
static int mymatrix[3][2];
static int (*rowp)[2] = mymatrix;
int (* const border)[] = mymatrix + NUM_ELEM(mymatrix);
memcpy(rowp, newrow, sizeof(*rowp));
rowp += 1;
if (rowp == border) {
rowp = mymatrix;
}
return *rowp;
}
int
main(int argc, char *argv[])
{
int i = 0;
int row[2] = {0, 1};
int *rout;
for (i = 0; i < 6; i++) {
row[0] = i;
row[1] += i;
rout = put_off(row);
printf("%d (%p): [%d, %d]\n", i, (void *) rout, rout[0], rout[1]);
}
return 0;
}
Sortie:
0 (0x804a02c): [0, 0] 1 (0x804a034): [0, 0] 2 (0x804a024): [0, 1] 3 (0x804a02c): [1, 2] 4 (0x804a034): [2, 4] 5 (0x804a024): [3, 7]
Notez que la valeur de frontière ne change jamais, de sorte que le compilateur peut optimiser tout ça. C'est différent de ce que vous voulez d'abord utiliser: const int (*border)[3]
: qui déclare la frontière comme un pointeur vers un tableau de 3 entiers qui ne changera pas de valeur tant que la variable existe. Cependant, ce pointeur peut être rappelé à tout autre tableau à tout moment. Nous voulons que ce genre de comportement pour l'argument, au lieu (parce que cette fonction ne modifie en aucune façon les entiers). Déclaration d'utilisation.
(p.s.: n'hésitez pas à améliorer cet exemple!)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.