Passer des pointeurs de tableaux en C

Donc, j’ai un code qui ressemble à ceci:

int a[10]; a = arrayGen(a,9); 

et la fonction arrayGen ressemble à ceci:

 int* arrayGen(int arrAddr[], int maxNum) { int counter=0; while(arrAddr[counter] != '\0') { arrAddr[counter] = gen(maxNum); counter++; } return arrAddr; } 

À l’heure actuelle, le compilateur me dit “avertissement: passer l’argument 1 de ‘arrayGen’ rend un entier à partir d’un pointeur sans conversion”

Ma pensée est que je passe “a”, un pointeur sur un [0], puis puisque le tableau est déjà créé, je peux simplement renseigner les valeurs pour un [n] jusqu’à ce que I a [n] == ‘\ 0’. Je pense que mon erreur est que arrayGen est écrit pour prendre un tableau, pas un pointeur sur un tableau. Si cela est vrai, je ne sais pas comment procéder, puis-je écrire des valeurs dans des adresses jusqu’à ce que le contenu d’une adresse soit “\ 0”?

La magie de base ici est cette identité en C:

 *(a+i) == a[i] 

Ok, maintenant je vais faire en sorte que ce soit en anglais lisible.

Voici le problème: un nom de tableau n’est pas une lvalue; il ne peut pas être atsortingbué à. Donc, la ligne que vous avez avec

 a = arrayGen(...) 

c’est le problème. Voir cet exemple:

 int main() { int a[10]; a = arrayGen(a,9); return 0; } 

ce qui donne l’erreur de compilation:

 gcc -o foo foo.c foo.c: In function 'main': foo.c:21: error: incompatible types in assignment Compilation exited abnormally with code 1 at Sun Feb 1 20:05:37 

Vous devez avoir un pointeur, qui est une valeur, auquel atsortingbuer les résultats.

Ce code, par exemple:

 int main() { int a[10]; int * ip; /* a = arrayGen(a,9); */ ip = a ; /* or &a[0] */ ip = arrayGen(ip,9); return 0; } 

comstack bien:

 gcc -o foo foo.c Compilation finished at Sun Feb 1 20:09:28 

Notez qu’en raison de l’identité en haut, vous pouvez traiter ip comme un tableau si vous le souhaitez, comme dans ce code:

 int main() { int a[10]; int * ip; int ix ; /* a = arrayGen(a,9); */ ip = a ; /* or &a[0] */ ip = arrayGen(ip,9); for(ix=0; ix < 9; ix++) ip[ix] = 42 ; return 0; } 

Exemple de code complet

Juste pour compléter, voici mon exemple complet:

 int gen(int max){ return 42; } int* arrayGen(int arrAddr[], int maxNum) { int counter=0; while(arrAddr[counter] != '\0') { arrAddr[counter] = gen(maxNum); counter++; } return arrAddr; } int main() { int a[10]; int * ip; int ix ; /* a = arrayGen(a,9); */ ip = a ; /* or &a[0] */ ip = arrayGen(ip,9); for(ix=0; ix < 9; ix++) ip[ix] = 42 ; return 0; } 

Pourquoi même retourner arrAddr? En passant un [10] par référence, le contenu du tableau sera modifié. À moins que vous n’ayez besoin d’ une autre référence au tableau, la suggestion de charlies est correcte.

Hmm, je sais que votre question a été résolue, mais quelque chose d’autre à propos du code me dérange. Pourquoi utilisez-vous le test contre ‘\ 0’ pour déterminer la fin du tableau? Je suis à peu près sûr que cela ne fonctionne qu’avec les chaînes en C. Le code est effectivement compilé après le correctif suggéré, mais si vous parcourez votre tableau, je suis curieux de voir si vous obtenez les bonnes valeurs.

Je ne suis pas sûr de ce que vous essayez de faire, mais l’atsortingbution d’une valeur de pointeur à un tableau est ce qui dérange le compilateur, comme l’a mentionné Charlie . Je suis curieux de vérifier contre la constante de caractère NUL '\0' . Votre exemple de tableau est une mémoire non initialisée, de sorte que la comparaison dans arrayGen ne produira pas ce que vous souhaitez.

La liste de parameters que vous utilisez finit par être identique à:

 int* arrayGen(int *arrAddr, int maxNum) 

pour la plupart des buts. La déclaration réelle dans la norme est:

La déclaration d’un paramètre en tant que “tableau de type ” doit être réglée sur “pointeur qualifié vers type “, les qualificateurs de type (le cas échéant) étant ceux spécifiés dans les [et] de la dérivation de type de tableau. Si le mot clé static apparaît également dans le [et] de la dérivation du type de tableau, alors, pour chaque appel à la fonction, la valeur de l’argument réel correspondant doit permettre d’accéder au premier élément d’un tableau avec au moins autant d’éléments que spécifiés. par l’expression de taille.

Si vous voulez vraiment forcer l’appelant à utiliser un tableau, utilisez la syntaxe suivante:

 void accepts_pointer_to_array (int (*ary)[10]) { int i; for (i=0; i<10; ++i) { (*ary)[i] = 0; /* note the funky syntax is necessary */ } } void some_caller (void) { int ary1[10]; int ary2[20]; int *ptr = &ary1[0]; accepts_pointer_to_array(&ary1); /* passing address is necessary */ accepts_pointer_to_array(&ary2); /* fails */ accepts_pointer_to_array(ptr); /* also fails */ } 

Votre compilateur devrait se plaindre si vous l'appelez avec tout ce qui n'est pas un pointeur sur un tableau de 10 entiers. Je peux honnêtement dire que je n'ai jamais vu celui-ci ailleurs que dans divers livres ( The C Book , Expert C Programming ) ... du moins, pas dans la programmation C. En C ++, cependant, j'ai eu raison d'utiliser cette syntaxe dans exactement un cas:

 template  std::size_t array_size (T (&ary)[N]) { return N; } 

Votre kilométrage peut varier cependant. Si vous voulez vraiment creuser des trucs comme celui-ci, je ne saurais trop vous recommander la programmation Expert C Vous pouvez également trouver The C Book en ligne sur gbdirect .

Essayez d’appeler votre paramètre int* arrAddr , pas int arrAddr[] . Bien que, quand j’y réfléchisse, les parameters de la méthode main sont similaires mais fonctionnent. Donc pas sûr de la partie explication.

Edit: Hm, toutes les ressources que je peux trouver sur Internet disent que cela devrait fonctionner. Je ne suis pas sûr, j’ai toujours passé les tableaux comme pointeurs moi-même, je n’avais jamais eu ce problème auparavant, alors la solution m’intéresse beaucoup.

La façon dont vous l’utilisez, arrayGen () n’a pas besoin de renvoyer une valeur. Vous devez également placer ‘\ 0’ dans le dernier élément, cela ne se fait pas automatiquement ou transmettre l’index du dernier élément à remplir.

@jeffD Passer l’index serait la méthode préférée, car rien ne garantit que vous ne bashez pas d’autres ‘0 avant votre dernier (je l’étais certainement lorsque je l’ai testé).