11
votes

Type de pointeur incompatible

J'ai la fonction avec la signature suivante: xxx pré>

et variable de type suivant: p> xxx pré>

quand j'appelle la fonction

103.c:79: warning: passing argument 1 of ‘box_sort’ from incompatible pointer type (string where i am calling the function)
103.c:42: note: expected ‘int **’ but argument is of type ‘int (*)[11] (string where the function is defined)

c gcc

1 commentaires

Quels sont les max_boxes et max_dimensionnalité ? Sont-ils des macros, des constantes, ...?


4 Réponses :


2
votes

Vous n'avez jamais construit un éventail de pointeurs car la signature nécessite.

Il y a deux façons de faire des matrices 2D dans C. Dans un cas, vous avez juste beaucoup de quelque chose et le compilateur est raconté quelles sont les dimensions. Il calcule le début de la ligne en multipliant l'indice de ligne par le nombre de colonnes, puis il ajoute l'index de la colonne pour trouver l'élément dans cette ligne.

L'autre sens est avec un vecteur de pointeurs, où le compilateur ne conçoit pas le vecteur de trouver le début de la rangée, mais le compilateur ne les fera pas pour vous automatiquement, vous devez le faire vous-même.

Votre objet réel est l'un des premiers types, mais votre prototype de fonction demande le deuxième type.

Vous devez donc changer le prototype pour correspondre à l'objet ou construire un vecteur de pointeurs de ligne à passer à la fonction.


1 commentaires

Bien expliqué, DigitalRoss. Pour plus d'informations, voir aussi C-FAQ.com/aryptr/index.html



15
votes

Je sais qu'il y avait une question presque exactement comme celle-ci il y a quelques jours ... ne peut pas le trouver maintenant.

La réponse est, int [taille] [] code> (voir Remarque en bas) et int ** code> ne sont définitivement pas le même type. Vous pouvez utiliser int [] code> et int * code> interchangeable dans de nombreux cas, en particulier dans des cas comme celui-ci, car la matrice se désintègre à un pointeur sur le premier élément lorsque vous le transmettez une fonction. Mais pour un tableau bidimensionnel, ce sont des méthodes très différentes de stockage. P>

Voici ce qu'ils ressemblent en mémoire pour un tableau 2x2: P>

int **a = malloc(2 * sizeof(int*));
a[0] = malloc(2 * sizeof(int));
a[1] = malloc(2 * sizeof(int));


5 commentaires

Cool ASCII-Art, mais je pense que vous avez le premier indice incorrect pour les cases pointées par la flèche.


J'aime l'explication visuelle. Je me demande cependant, s'ils l'ont rendu possible pour * et [] de travailler entrechantillonner, pourquoi pas pour * {n} et [] {n}? Était-ce simplement trop difficile?


NOMEN: C'est parce que cela n'a pas de sens - vous pouvez convertir judicieusement un tableau en un pointeur à son premier élément, car un tableau est juste une séquence d'éléments contigus; mais vous ne pouvez pas convertir judicieusement un tableau-de-tableaux en pointeur à un pointeur, car un pointeur à un pointeur doit être pointé à Pointeur (s), et il n'y a pas de pointeurs réels là-bas pour qu'il pointez. Ahem.


@CAF: Merci d'avoir couvert cela. J'ai vu le commentaire et la pensée de Nomen, attendez que l'explication visuelle ne démontre pas pourquoi elles ne peuvent pas travailler de manière interchangeable? Les mots sont bons aussi, cependant!


@CAF Si vous vraiment voulait avoir cette fonctionnalité dans une langue ne pouvait-il pas faire une conversion profonde ? C'est-à-dire de convertir un tableau 2D en un pointeur à un tableau de pointeurs aux sous-bras. Cela nécessite un tableau supplémentaire ou au moins quelque chose qui peut être itéré, mais cela devrait fonctionner correctement? Ou je manque quelque chose de fondamental?



1
votes

Il n'y a pas de tel type en C comme int [] [] [] code>, seule la première partie d'une matrice multidimensionnelle peut être indéterminée. Donc, int [] [5] code> est correct.

En plus des autres réponses postées ici, si vous pouvez utiliser C99, vous pouvez utiliser des tableaux de variables pour accomplir ce que vous voulez: p>

void box_sort(int N, int M, int x[M][N]);


0 commentaires

0
votes

Lorsqu'une expression de tableau apparaît dans la plupart des contextes, son type est implicitement converti de "réseau N-Element de T" en "pointeur à t", et sa valeur est définie sur l'adresse du premier élément du tableau. Les exceptions à cette règle sont lorsque l'expression de la matrice est un opérande de la taille code> ou de l'adresse des opérateurs ( & code>) ou si l'expression de tableau est un littéral de chaîne utilisé. Pour initialiser un autre tableau dans une déclaration.

Qu'est-ce que cela signifie dans le contexte de votre code est que dans votre appel à box_sort code>, le type d'expression cases code> est implicitement converti de M-Element Array de N-Element Array of int code> à Pointeur sur N-Element Array d'int code> ou int (*) [max_dimensionnalité + 1] code>, votre fonction devrait donc s'attendre à des types de paramètres tels que: p> xxx pré>

depuis int * a code> et int a [] est synonyme dans une déclaration de paramètre de fonction, il suit que int (* a) [n] code> est synonyme de int a [] [n] code>, afin que vous puissiez Ecrivez ci-dessus comme p> xxx pré>

Bien que je préfère personnellement la notation du pointeur, car il reflète plus précisément ce qui se passe. Notez que dans votre fonction, vous seriez indifférez ar code> comme normal: p> xxx pré>

puisque l'expression arr [x] code> est équivalent à * (arr + x) code>, le pointeur est implicitement déréférencé. p>

Si vous voulez que Box_sort fonctionne sur des tableaux de taille arbitraire (c.-à-d. Les tableaux où la deuxième dimension ne représente pas nécessairement max_dimensionnalité + 1), une approche est de procéder aux éléments suivants: P>

int boxes[X][Y];
...
box_sort (&boxes[0], X, Y, x, y);
...
void box_sort(int *arr, size_t rows, size_t cols, int x, int y)
{
  ...
  arr[x*cols + y] = ...;
}


0 commentaires