test.c:23:16: warning: returning 'int (*)[4]' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types]
23 | return tableau_entier;
| ^~~~~~~~~~~~~~
test.c: In function 'main':
test.c:39:46: error: subscripted value is neither array nor pointer nor vector
39 | printf("[%d] ",tab[i][j]);
| ^
J'avoue être confus et ne pas bien comprendre le sens des erreurs qu'il m'indique d'autant plus que le même code avec un tableau à une seul dimension fonctionne correctement.
Merci d'avance pour vos réponses.
- Edité par GuillaumePerez2 1 septembre 2021 à 16:43:52
test.c:23:16: warning: returning 'int (*)[4]' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types]
23 | return tableau_entier;
| ^~~~~~~~~~~~~~
Le type de la fonction, telle qu'elle est déclarée, n'est pas celui de la valeur retournée.
Effectivement, voici la déclaration de la fonction :
int *cree_tableau(void);
Elle est de type int*, donc doit retourner une valeur de type int*. Ce type est équivalent à int[], qui est adapté à un tableau à 1 dimension.
Or tu retournes :
static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
return tableau_entier;
qui est de type int[][], fait pour un tableau à 2 dimensions.
Si tu veux retourner un tableau à 2 dimensions, peut-être qu'il faut déclarer la fonction comme étant de type int**. Mais je crois que ce n'est pas si simple.
GuillaumePerez2 a écrit:
test.c:39:46: error: subscripted value is neither array nor pointer nor vector
39 | printf("[%d] ",tab[i][j]);
| ^
Toujours le même genre d'erreur : tu utilises deux indices pour 'tab', comme si c'était un tableau à 2 dimensions. Est-ce le cas ?
int *tab = cree_tableau();
Non : il est de type int*, qui est équivalent à int[] : ça déclare un tableau à 1 dimensions. Peut-être qu'il faut déclarer 'tab' comme était de type int**. Là aussi je crains que ce ne soit pas si simple.
Il faut le faire dans la définition de la fonction et du pointeur dans le main ('**' dans les deux cas) Il y a un problème plus grave. Qui dira au compilateur le nombre de colonnes du tableau dans le main? Ce truc marche avec les tableaux dynamiques utilisant malloc, ce qui n'est pas le cas ici. Je suggère plutôt de déclarer le tableau dans le main et de seulement l'initialiser dans la fonction. On dit à la fonction le nombre de colonnes (déclaration)
Le Tout est souvent plus grand que la somme de ses parties.
test.c:23:16: warning: returning 'int (*)[4]' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types]
23 | return tableau_entier;
| ^~~~~~~~~~~~~~
Le type de la fonction, telle qu'elle est déclarée, n'est pas celui de la valeur retournée.
Effectivement, voici la déclaration de la fonction :
int *cree_tableau(void);
Elle est de type int*, donc doit retourner une valeur de type int*. Ce type est équivalent à int[], qui est adapté à un tableau à 1 dimension.
Or tu retournes :
static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
return tableau_entier;
qui est de type int[][], fait pour un tableau à 2 dimensions.
Si tu veux retourner un tableau à 2 dimensions, peut-être qu'il faut déclarer la fonction comme étant de type int**. Mais je crois que ce n'est pas si simple.
GuillaumePerez2 a écrit:
test.c:39:46: error: subscripted value is neither array nor pointer nor vector
39 | printf("[%d] ",tab[i][j]);
| ^
Toujours le même genre d'erreur : tu utilises deux indices pour 'tab', comme si c'était un tableau à 2 dimensions. Est-ce le cas ?
int *tab = cree_tableau();
Non : il est de type int*, qui est équivalent à int[] : ça déclare un tableau à 1 dimensions. Peut-être qu'il faut déclarer 'tab' comme était de type int**. Là aussi je crains que ce ne soit pas si simple.
- Edité par robun il y a moins de 30s
Merci robin d'avoir prit le temps de me répondre je comprend maintenant d'où vient l'erreur. Mais je ne comprend malheureusement pas comment la corriger ne comprenant pas comment l'on peut créer des types int**. Auriez vous des idées ou des pistes à explorer ?
Pourquoi créer des tableaux de type int** ? Tu veux que les dimensions soient variables? Ça se fait avec malloc, pas un tableau statique. Tu réserves un tableau de LIGNE_TABLEAU pointeurs Pour chaque entrée, tu réserves COLONNE_TABLEAU places pour des int
Le Tout est souvent plus grand que la somme de ses parties.
Pourquoi créer des tableaux de type int** ? Tu veux que les dimensions soient variables? Ça se fait avec malloc, pas un tableau statique. Tu réserves un tableau de LIGNE_TABLEAU pointeurs Pour chaque entrée, tu réserves COLONNE_TABLEAU places pour des int
N'est il pas possible de le faire sans utiliser l'allocation dynamique. Je veux un tableau de taille fixe ayant pour dimensions les valeurs des directives de préprocesseurs.
En déclarant le tableau dans le main, ça va suivre les indications du préprocesseur. Tu n'as qu'à passer les dimensions à la fonction. Tu as une autre option, c'est de faire un tableau à une seule dimension de ggrandeur [LIGNE_TABLEAU * COLONNE_TABLEAU] Au lieu de faire tableau[i][j], tu fais tableau[i *COLONNE_TABLEAU + j]
Le Tout est souvent plus grand que la somme de ses parties.
#include <stdio.h>
#define LIGNE_TABLEAU 5
#define COLONNE_TABLEAU 4
typedef int(*PTCol)[COLONNE_TABLEAU];
PTCol cree_tableau(void);
int main(void)
{
PTCol tab = cree_tableau();
for (int i = 0; i < 5; ++i)
{
for(int j = 0; j < COLONNE_TABLEAU; j++)
{
printf("[%d] ",tab[i][j]);
}
}
return 0;
}
PTCol cree_tableau(void)
{
static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
for (int i = 0; i < LIGNE_TABLEAU; ++i)
{
for (int j = 0; j < COLONNE_TABLEAU; ++j)
{
tableau_entier[i][j] = i + j * 3;
}
}
return tableau_entier;
}
ça évite les vilains transtypage.
GuillaumePerez2 a écrit:
rouIoude a écrit:
En revanche que signifie cette ligne j'ai du mal à la comprendre
int (*tab)[COLONNE_TABLEAU] = (int(*)[COLONNE_TABLEAU])cree_tableau();
et je me demandais si ça marche aussi pour les tableaux de char.
ça déclare un pointeur tab sur des tableaux de COLONNE_TABLEAU élément, puis ça lui affecte l'adresse du tableau retourné par la fonction, mais comme elle retourne un pointeur sur int il faut le transtyper en pointeur sur des tableau de COLONNE_TABLEAU éléments.
Je pense que le plus simple est de déclarer le tableau dans le 'main' et de le passer en paramètre des fonctions. En paramètre : pas en valeur de retour.
Exemple :
#include <stdio.h>
#include <stdlib.h>
#define NB_LIG 5
#define NB_COL 4
void initialise_tableau(int tab[NB_LIG][NB_COL]);
void affiche_tableau(int tab[NB_LIG][NB_COL]);
int main(void)
{
int tableau[NB_LIG][NB_COL];
initialise_tableau(tableau);
affiche_tableau(tableau);
return 0;
}
void initialise_tableau(int tab[NB_LIG][NB_COL])
{
for (int i = 0; i < NB_LIG; ++i)
{
for (int j = 0; j < NB_COL; ++j)
{
tab[i][j] = i + j * 3;
}
}
}
void affiche_tableau(int tab[NB_LIG][NB_COL])
{
for (int i = 0; i < NB_LIG; ++i)
{
for (int j = 0; j < NB_COL; ++j)
{
printf("%2d ", tab[i][j]);
}
printf("\n");
}
}
Pas besoin de * partout (moins j'ai de *, mieux je me porte...)
#include <stdio.h>
#define LIGNE_TABLEAU 5
#define COLONNE_TABLEAU 4
typedef int(*PTCol)[COLONNE_TABLEAU];
PTCol cree_tableau(void);
int main(void)
{
PTCol tab = cree_tableau();
for (int i = 0; i < 5; ++i)
{
for(int j = 0; j < COLONNE_TABLEAU; j++)
{
printf("[%d] ",tab[i][j]);
}
}
return 0;
}
PTCol cree_tableau(void)
{
static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
for (int i = 0; i < LIGNE_TABLEAU; ++i)
{
for (int j = 0; j < COLONNE_TABLEAU; ++j)
{
tableau_entier[i][j] = i + j * 3;
}
}
return tableau_entier;
}
ça évite les vilains transtypage.
GuillaumePerez2 a écrit:
rouIoude a écrit:
En revanche que signifie cette ligne j'ai du mal à la comprendre
int (*tab)[COLONNE_TABLEAU] = (int(*)[COLONNE_TABLEAU])cree_tableau();
et je me demandais si ça marche aussi pour les tableaux de char.
ça déclare un pointeur tab sur des tableaux de COLONNE_TABLEAU élément, puis ça lui affecte l'adresse du tableau retourné par la fonction, mais comme elle retourne un pointeur sur int il faut le transtyper en pointeur sur des tableau de COLONNE_TABLEAU éléments.
Ça marche avec des char ou ce que tu veux.
- Edité par rouIoude il y a environ 1 heure
Merci beaucoup ça marche au poil.
On s'éloigne peut être du sujet initial du topic mais qu'est ce que c'est que "transtyper"
Je pense que le plus simple est de déclarer le tableau dans le 'main' et de le passer en paramètre des fonctions. En paramètre : pas en valeur de retour.
Exemple :
#include <stdio.h>
#include <stdlib.h>
#define NB_LIG 5
#define NB_COL 4
void initialise_tableau(int tab[NB_LIG][NB_COL]);
void affiche_tableau(int tab[NB_LIG][NB_COL]);
int main(void)
{
int tableau[NB_LIG][NB_COL];
initialise_tableau(tableau);
affiche_tableau(tableau);
return 0;
}
void initialise_tableau(int tab[NB_LIG][NB_COL])
{
for (int i = 0; i < NB_LIG; ++i)
{
for (int j = 0; j < NB_COL; ++j)
{
tab[i][j] = i + j * 3;
}
}
}
void affiche_tableau(int tab[NB_LIG][NB_COL])
{
for (int i = 0; i < NB_LIG; ++i)
{
for (int j = 0; j < NB_COL; ++j)
{
printf("%2d ", tab[i][j]);
}
printf("\n");
}
}
Pas besoin de * partout (moins j'ai de *, mieux je me porte...)
On s'éloigne peut être du sujet initial du topic mais qu'est ce que c'est que "transtyper"
C'est changer le type d'une variable lors de l'affectation à une variable d'un autre type.
Il est impossible de changer le type d'une variable en C; il est fixé à la déclaration de la variable (on peut compléter certains types, mais on s'éloigne du sujet). Le transtypage est l'opération consistant à produire une valeur de type Y à partir d'une valeur de type X. Par exemple
123; // 123 (implicitement de type int)
(long)123; // 123 transtypé en type long
On peut utiliser le transtypage dans toutes les expressions, pas seulement les affectations.
- Edité par Marc Mongenet 2 septembre 2021 à 1:26:35
Oui, tout à fait, je ne me suis pas bien exprimé. J'aurais du dire changer le type d'une expression.
...
Fonction de création de tableau2D
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le Tout est souvent plus grand que la somme de ses parties.