2010-03-27 4 views
0

associé à (gcc) Multi-Dim Array or Double Pointer for Warning-free Compile, existe-t-il un moyen de renvoyer ce que l'on appelle un "pointeur de tableau décroissant" d'une fonction? en résumé (supposons 2 matrice dim) renvoyer format int (*a)[5] plutôt que int** format?Retour multidiffusé multidimensionnel de la fonction

autant que je vois, quand retourné int** pointeur est envoyé à une autre fonction en attente (int*)[] paramètre, il ne fonctionne pas correctement.

+0

Une chance de voir du code? – Goz

+0

Notez que la fonction prenant 'int * []' prend actuellement 'int **'. Le problème est que le tableau 2D n'est pas 'int **', c'est-à-dire que renvoyer le tableau 2D d'une fonction sera correct (car cela représente les données internes) mais pas utilisable comme paramètre pour une fonction 'void (f * a []) ' –

Répondre

4

Oui, mais la syntaxe ne sera pas l'air bien

int(*f())[5] { 
    static int a[1][5] = { { 1, 2, 3, 4, 5 } }; 
    return a; 
} 

Fondamentalement, il est juste votre a remplacé par f() (fonction). L'utilisation d'un typedef il devient plus lisible

typedef int inner_array[5]; 

inner_array *f() { 
    // like before ... 
} 

Notez que pour indiquer le type abstact, sans nom, vous devez écrire int(*)[5]. Autrement dit, vous venez d'effacer le nom. (int*)[5] n'est pas une syntaxe valide.

Vous avez raison - vous ne pouvez pas retourner int** car cela signifie que vous avez un pointeur vers un pointeur. L'accès avec f()[A][B] lirait à partir de l'adresse fournie par le pointeur renvoyé, puis relu à partir de l'adresse donnée par ce pointeur à son tour. Mais en fait, le pointeur de tableau que vous renvoyez ne pointe que vers un bloc de mémoire, donc si vous deviez faire deux indirections, vous essayeriez de réinterpréter les données comme étant des pointeurs. Par contre, si vous renvoyez un int(*)[5] et que vous faites f()[A][B], vous ne lirez aucune valeur à partir de l'adresse renvoyée par le pointeur. Au lieu de cela, vous ajoutez simplement le décalage A à l'adresse et réglez le type de int(*)[5] à int[5] pour avoir un tableau qui fait référence à la mémoire à l'adresse ajustée. L'index suivant sera alors de nouveau ajusté par B et comme il fonctionne sur un int* puis (après que le tableau est tombé en panne), plus sur un pointeur de tableau, il lira alors le contenu stocké à l'adresse ajustée, pour finalement donner le int. C'est une différence importante entre les pointeurs sans tableau et les pointeurs de tableau.

Vous pouvez expérimenter avec ceci, si vous voulez. Considérez ces deux extraits. On s'écraser sans doute, mais l'autre ne sera probablement pas (mais à la fois le rendement comportement non défini, donc cela ne devrait pas être fait dans les programmes réels)

int *pi = 0; 
int(*pa)[5] = 0; 

int i = *pi; // read int stored at null-pointer address! 
int *a = *pa; // does not read any data from address, just adjusts the type! 
0
struct thing { 
    int A[10][10]; 
}; 

typedef struct thing thing_t; 

thing_t f1(void) { 
    thing_t t; 
    ... 
    return t; 
} 
thing_t * f1(void) { 
    thing_t * tp; 
    ... 
    return tp; 
} 

Bien, vous allez vraiment cela le Fausse Route.

Questions connexes