Désolé de poser la question déjà répondue, je suis un débutant en C et ne comprends pas les solutions .
int rotateArr(int *arr) {
int D[4][4];
int i = 0, n =0;
for(i; i < M; i ++ ){
for(n; n < N; n++){
D[i][n] = arr[n][M - i + 1];
}
}
return D;
}
Il jette une erreur
main.c | 23 | error: la valeur indiquée n'est ni tableau ni pointeur ni vecteur |
en ligne
D [i] [n] = arr [n] [M - i + 1];
Qu'est-ce qui ne va pas? Je ne fais que définir la valeur d'un élément de tableau sur un autre élément de tableau.
L'arr passé est déclaré comme
int S[4][4] = { { 1, 4, 10, 3 }, { 0, 6, 3, 8 }, { 7, 10 ,8, 5 }, { 9, 5, 11, 2} };
C vous permet d’utiliser l’indicateur []
sur les tableaux et les pointeurs. Lorsque vous utilisez cet opérateur sur un pointeur, le type résultant est le type vers lequel le pointeur pointe. Par exemple, si vous appliquez []
à int*
, le résultat serait une int
.
C’est précisément ce qui se passe: vous passez int*
, ce qui correspond à un vecteur d’entiers. L'utilisation de l'indice dessus une fois le rend int
, vous ne pouvez donc pas lui appliquer le second indice.
D'après votre code, il apparaît que arr
devrait être un tableau à deux dimensions. S'il est implémenté en tant que tableau "en dents de scie" (c'est-à-dire un tableau de pointeurs), le type de paramètre doit être int **
.
De plus, il semble que vous essayez de retourner un tableau local. Afin de le faire légalement, vous devez allouer le tableau dynamiquement et renvoyer un pointeur. Cependant, une meilleure approche consisterait à déclarer une struct
spéciale pour votre matrice 4x4 et à l'utiliser pour envelopper votre tableau de taille fixe, comme ceci:
// This type wraps your 4x4 matrix
typedef struct {
int arr[4][4];
} FourByFour;
// Now rotate(m) can use FourByFour as a type
FourByFour rotate(FourByFour m) {
FourByFour D;
for(int i = 0; i < 4; i ++ ){
for(int n = 0; n < 4; n++){
D.arr[i][n] = m.arr[n][3 - i];
}
}
return D;
}
// Here is a demo of your rotate(m) in action:
int main(void) {
FourByFour S = {.arr = {
{ 1, 4, 10, 3 },
{ 0, 6, 3, 8 },
{ 7, 10 ,8, 5 },
{ 9, 5, 11, 2}
} };
FourByFour r = rotate(S);
for(int i=0; i < 4; i ++ ){
for(int n=0; n < 4; n++){
printf("%d ", r.arr[i][n]);
}
printf("\n");
}
return 0;
}
This imprime ce qui suit :
3 8 5 2
10 3 8 11
4 6 10 5
1 0 7 9
Vous ne passez pas correctement votre tableau 2D. Cela devrait fonctionner pour vous
int rotateArr(int *arr[])
ou
int rotateArr(int **arr)
ou
int rotateArr(int arr[][N])
Plutôt que de renvoyer le tableau, passez le tableau cible en argument. Voir la réponse de John Bode.
Sauf s’il s’agit de l’opérande de l’opérateur sizeof
ou unary &
, ou d’un littéral utilisé pour initialiser un autre tableau dans une déclaration, une expression de type "tableau N-élément de T
" est convertie en un expression de type "pointeur sur T
", et la valeur de l'expression est l'adresse du premier élément du tableau.
Si la déclaration du tableau en cours de passage est
int S[4][4] = {...};
alors quand tu écris
rotateArr( S );
l'expression S
a le type "tableau à 4 éléments d'un tableau à 4 éléments de int
"; étant donné que S
n'est pas l'opérande des opérateurs sizeof
ou unaire &
, il sera converti en une expression de type "pointeur sur un tableau à 4 éléments de int
", ou int (*)[4]
, et ce pointeur valeur est ce qui est réellement transmis à rotateArr
. Votre prototype de fonction doit donc être l’un des suivants:
T rotateArr( int (*arr)[4] )
ou
T rotateArr( int arr[][4] )
ou même
T rotateArr( int arr[4][4] )
Dans le contexte d'une liste de paramètres de fonction, les déclarations de la forme T a[N]
et T a[]
sont interprétées comme T *a
; tous les trois déclarent a
comme pointeur sur T
.
Vous vous demandez probablement pourquoi j'ai changé le type de retour de int
à T
. Comme vous l'avez écrit, vous essayez de renvoyer une valeur de type "tableau à 4 éléments d'un tableau à 4 éléments de int
"; Malheureusement, vous ne pouvez pas faire ça. Les fonctions C ne peuvent pas renvoyer les types de tableaux, ni affecter les types de tableaux. IOW, vous ne pouvez pas écrire quelque chose comme:
int a[N], b[N];
...
b = a; // not allowed
a = f(); // not allowed either
Les fonctions peuvent renvoyer pointeurs aux tableaux, mais ce n'est pas ce que vous voulez ici. D
cessera d'exister une fois la fonction retournée, ainsi tout pointeur que vous renverrez sera invalide.
Si vous souhaitez affecter les résultats du tableau pivoté à un autre tableau, vous devrez alors passer le tableau cible en tant que paramètre à la fonction:
void rotateArr( int (*dst)[4], int (*src)[4] )
{
...
dst[i][n] = src[n][M - i + 1];
...
}
Et appelez comme
int S[4][4] = {...};
int D[4][4];
rotateArr( D, S );
Le problème est que arr
n'est pas (déclaré comme) un tableau 2D et vous le traitez comme s'il s'agissait de 2D.
le second opérateur en indice n'est pas valide ici . Vous avez passé un pointeur int * dans function, qui est un tableau 1-d Donc, un seul opérateur en indice peut être utilisé.
Solution: vous pouvez passer le pointeur int ** dans funciton
Vous avez "int * arr" alors "arr [n]" est un int, non? Ensuite, votre bit "[M - 1 + 1]" tente d'utiliser cet int en tant que tableau/pointeur/vecteur.