2010-03-26 6 views
0

J'ai une fonction, qui est parfois appelée avec des tableaux réguliers, parfois dynamiques.(gcc) Multi-Dim Array ou Double Pointer pour Compiler sans avertissement

Si je définit la fonction comme

function_name(int[10][10] a) 

et envoyer int ** comme paramètre, je reçois un avertissement. En face, si je déclare

function_name(int** a) 

et envoie int [] [] en tant que paramètre (après la coulée) je ne peux pas accéder à des éléments de réseau à l'intérieur de la fonction.

Quelle est la manière correcte?

Répondre

1

Quand un tableau est transmis à une fonction, elle « désintégrations » pour un pointeur vers le premier élément. Donc, étant donné:

T a[10]; 
f(a); 

Dans l'appel f(a), a est en fait &a[0], à savoir, un pointeur, et le type est T * (le type de &a[0]).

Lorsque vous avez un tableau de tableaux, la règle applicable:

T a[10][5]; 
f(a); 

a désintègre à un pointeur à nouveau, égal à &a[0]. a[0] est de type "tableau [5] de T". Ainsi, &a[0] est de type « pointeur sur un tableau [5] de T », à savoir, si vous deviez déclarer un pointeur p à égal à &a[0], vous feriez:

T (*p)[5]; /* parentheses because [] binds tighter than * */ 
p = &a[0]; 

Compte tenu de ce qui précède, et en supposant votre tableau est déclaré dans le code d'appel comme int a[10][10];, vous devez déclarer votre fonction:

function_name(int (*a)[10]); 

Pour plus, voir this.

Il y a une erreur de syntaxe dans function_name(int[10][10] a) — vous devez spécifier la taille du tableau après le nom "variable": function_name(int a[10][10]). En fait, ce qui précède est équivalent à function_name(int (*a)[10]), à cause de la "désintégration" mentionnée ci-dessus.

Modifier: ah, je pense que je comprends maintenant. Vous ne pouvez pas déclarer une fonction qui prend à la fois un tableau "bidimensionnel" et un pointeur-sur-pointeur, pour les raisons mentionnées ci-dessus (le "déclin" en pointeur n'arrive qu'une fois). Un pointeur vers pointeur ne peut pointer vers des données contiguës, et peut avoir un nombre différent d'éléments dans chaque "ligne". Un tableau de tableaux ne peut pas avoir ces propriétés. Ils sont fondamentalement différents.

1

int ** et int [][] ne sont pas les mêmes. Le premier est pointer to pointer to int tandis que le second est un tableau 2d de int.

int[][] decays to int (*)[] when you pass it as argument to function.

void func(int arr[][10]) { //decays to `int (*arr)[10]` 
    printf("%d correct", arr[1][9]); //10th element of 2nd row 
    //printf("%d correct", (*(arr + 1))[9]); //same as above 
} 

int main() { 
    int (*arr)[10]; //pointer to array of ints 
    arr = malloc(sizeof(int (*)[]) * 2); //2 rows & malloc will do implicit cast. 

    arr[1][9] = 19; 
    func(arr); 

    return 0; 
} 
Questions connexes