34 votes

Double [] [] n'est-il pas équivalent à ** double?

Je vous pose cette question parce que mon programme ont deux fonctions de multiplier les matrices, ils se multiplient uniquement en 4x4 et 4x1 matrices. Les en-têtes sont:

 double** mult4x1(double **m1, double **m2);
 double** mult4x4(double **m1, double **m2);

Ils n'm1*m2 et retourner dans une **double, ci-dessous est un extrait de 4x4 de multiplication.

 double** mult4x4(double **m1, double **m2){
      double** result = (double**) malloc(sizeof(double)*4);
      for (int i = 0; i < 4; i++) {
           result[i] = (double*) malloc(sizeof(double)*4);
      }
      ...multiply...
      return result;
 }

La différence entre mult4x1 et mult4x4 ne sont que dans les index utilisés à l'intérieur d'eux.

J'ai ces 3 matrices:

double m1[4][4] = {
    {2, 3, 5, 6},
    {9, 8, 1, 7},
    {5, 4, 3, 1},
    {7, 6, 1, 2}
};

double m2[4][4] = {
    {1, 0, 0, 0},
    {0, 1, 0, 0},
    {0, 0, 1, 0},
    {0, 0, 0, 1}
};

double m3[4][1] = {
    {2},
    {3},
    {3},
    {1}
};

En essayant de multiplier ces matrices, une erreur se produit.

double** test = mult4x4(m1, m2);
double** test2 = mult4x1(identity4x4(), m3);
//identity4x4() creates a 4x4 identity matrix - double** identity4x4();

Rendements:

erreur: impossible de convertir double (*)[4]' todouble*' for argument 1' todouble* mult4x4(double*double*)'

erreur: impossible de convertir double (*)[1]' todouble*' for argument 2' todouble* mult4x1(double*double*)'

N'est-ce pas double[][] censé être égal à **double? Un tableau de tableaux de double. Toutes les clarifications, les idées fausses et les erreurs sont les bienvenus.

51voto

Yochai Timmer Points 19802

Non.
A double** est un pointeur sur un pointeur sur un double ( double* ).

Donc, en réalité, il devrait être créé comme ceci (notez le supplément * dans le premier malloc sizeof ()):

   double** result = (double**) malloc(sizeof(double*)*4);
  for (int i = 0; i < 4; i++) {
       result[i] = (double*) malloc(sizeof(double)*4);
  }
 

Donc, en mémoire, cela ressemblerait à ceci:

 [] -> { d,d,d,d }
[] -> { d,d,d,d }
[] -> { d,d,d,d }
[] -> { d,d,d,d }
 

Il y a 4 tampons qui contiennent 4 doubles, mais ne sont pas continus.

Alors que votre double [4] [4] est un tampon continu en mémoire, comme ceci:

  { { d,d,d,d } { d,d,d,d } {d,d,d,d} {d,d,d,d} }
 

24voto

dasblinkenlight Points 264350

Bien que les deux double[N][M] et double** laissez-vous traiter avec les tableaux 2D, les deux ne sont pas équivalents: le premier représente un tableau 2D de doubles, tandis que le plus tard représente un pointeur de pointeur de double, qui peut être interprété (avec l'aide de la pratique crochet de la syntaxe de C/C++) comme un tableau de pointeurs doubleou comme un tableau de tableaux de double.

L' double[N][M] représente 2D tableaux de "rectangulaire" forme, tandis qu' double** vous permet de construire de "forme libre" (déchiqueté) tableaux par l'allocation d'une quantité de mémoire différente pour chaque ligne de la matrice.

La différence pour le compilateur, c'est que compte tenu de double[N][M] et d'une paire d'entiers {r,c} il est possible de calculer l'emplacement de l'élément par le calcul du décalage de l'origine de la matrice, sans lire quoi que ce soit à partir de la mémoire. Étant donné un double**, cependant, le compilateur doit calculer l'adresse du pointeur à une ligne, lire le pointeur, et seulement ensuite de calculer l'adresse de l'élément cible. En raison de cette différence, les deux ne sont pas interchangeables.

3voto

Ivaylo Strandjev Points 38924

Il n'y a pas de type [][] . Ce que vous avez est en fait m2 qui est un tableau de tableaux de taille 4 de type double et m1 qui est un tableau de tableaux de taille 1. Un tableau de tableaux de taille 4 n'est pas équivalent à double pointeur.

2voto

luk32 Points 5567

J'espère que je ne deviendrai pas stupide ici, mais la notation double [][] est également utilisée lorsque vous vous adressez à un bloc de mémoire continu, alors que double** n'est pas nécessairement continu.

Je pense que c'est la raison derrière l'erreur. Même si vous pouvez utiliser la même sémantique pour accéder aux valeurs, elles sont en réalité de types différents.

2voto

Raxvan Points 2693

[][] n'est pas équivalent à **; double ** var; est un pointeur de pointeurs et comme vous pouvez le voir à partir de votre allocation en mémoire un tableau de pointeurs et chaque pointeur à l'intérieur des points d'un tableau de valeurs de double

double var [4][4]; est conservé dans la mémoire dans la place, et c'est un peu l'équivalent de la double *; Dans ce cas, le sait la taille de la matrice ( 4 x 4 ) ainsi, lorsque vous utilisez var[2][2], par exemple, de savoir où est située dans la mémoire; var[x][y] se traduit par quelque chose comme ceci: var[x + y * 4] et la déclaration peut être interprétée comme double var [16];

Raxvan.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X