Passer un tableau en argument d'une fonction

Le problème exposé dans ce sujet a été résolu.

Bonjour,

En C, j'essaye, dans une fonction, d'initialiser toutes les valeurs d'un tableau passé en argument :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// koch_fonctions.c
void init_picture(uint32_t **picture, uint32_t size, uint32_t bg_color)
{
  for (uint64_t i = 0; i < size * size; i++) {
    (*picture)[i] = bg_color;
  }
}

// test_fonctions.c
int main() {
  uint32_t size = 200;
  const uint64_t PIC_AREA = size * size;

  uint32_t picture[PIC_AREA];
  init_picture(&picture, size, 0);

  return EXIT_SUCCESS;
}

Seulement, j'obtiens l'avertissement suivant à la compilation, et une erreur de segmentation à l'exécution :

1
2
3
4
5
6
7
8
9
$ clang -Wall -Wextra -lm test_fonctions.c koch_fonctions.c
test_fonctions.c:18:16: warning: incompatible pointer types passing 'uint32_t (*)[PIC_SIZE]' to parameter of type 'uint32_t **' (aka 'unsigned int **')
      [-Wincompatible-pointer-types]
  init_picture(&picture, size, 0);
               ^~~~~~~~
./koch_fonctions.h:50:37: note: passing argument to parameter 'picture' here
extern void init_picture(uint32_t **picture, uint32_t size, uint32_t bg_color);
                                    ^
1 warning generated.

Merci.

+0 -0

En C, les tableaux statiques sont systématiquement passés par référence et ne sont pas strictement équivalents à des pointeurs. Ça veut dire que, d’une part, tu dois passer le tableau directement et non son adresse lors de l’appel de fonction…

1
  init_picture(picture, size, 0);

… d’autre part, ta fonction doit bien prendre en argument une variable de type tableau statique, et non un pointeur de pointeur comme c’est le cas actuellement.

1
void init_picture(uint32_t picture[], uint32_t size, uint32_t bg_color)
+0 -0

Au passage, un fun fact un peu connu, tu peux spécifier une taille minimum pour de tels arguments avec le mot clef statique. En gros,

1
void foo(int bar[static 3]);

permet de spécifier que bar est un tableau d’au moins trois cases. C’est un peu hs, mais la fonctionnalité est rigolote.

+0 -0

tu dois passer le tableau directement et non son adresse lors de l’appel de fonction…

Dominus Carnufex

En fait, dans le contexte d'un appel de fonction, tableau et &tableau sont strictement équivalents. Dans le premier cas, la conversion tableau vers pointeur est implicite et dans le second cas, on prend l'adresse, ce qui revient à une conversion explicite. Le problème est surtout, comme tu le dis, que la signature de init_picture est incompatible.

@Vayel : Au passage, je ne sais pas si tu es au courant, mais ce que tu déclare ici est un VLA.

1
2
3
uint32_t size = 200;
const uint64_t PIC_AREA = size * size;
uint32_t picture[PIC_AREA];

Il n'y a pas de problème, c'est autorisé en C, mais attention, les règles sont un peu différentes des tableaux statiques. Si tu veux un tableau statique, tu dois soit noter la taille en dur, soit utiliser un define. Annoter size de const fonctionnera uniquement en C++ car une variable constante ne forme pas une expression constante en C.

+0 -0

Salut,

Je profite de ce sujet pour faire un peu de pub, cet aspect des tableaux étant abordés dans le chapitre sur les tableaux du cours sur le C (plus précisément la section traitant des tableaux multidimensionnels).

En fait, dans le contexte d'un appel de fonction, tableau et &tableau sont strictement équivalents. Dans le premier cas, la conversion tableau vers pointeur est implicite et dans le second cas, on prend l'adresse, ce qui revient à une conversion explicite. Le problème est surtout, comme tu le dis, que la signature de init_picture est incompatible.

Praetonus

Les deux expressions diffèrent au niveau du type et de leur utilisation : l'une donne un pointeur sur le premier élément du tableau et la seconde un pointeur sur un tableau.

+0 -0

Merci à tous pour vos explications. :)

J'avais en fait mal compris l'énoncé. On me donnait ce prototype

1
void init_picture(uint32_t **picture, uint32_t size, uint32_t bg_color);

et je devais implémenter la fonction. En cherchant à la tester, j'étais parti sur un tableau pour picture, puisque je ne voyais pas comment m'en sortir avec un pointeur, jusqu'à ce que je lise "allocation dynamique".

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte