Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
961 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Problème courant du tableau 2D

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème courant du tableau 2D

n°1812716
sherminato​r+
Rock'n'Roll Damnation
Posté le 16-11-2008 à 15:39:05  profilanswer
 

Bonjour,
 
Je galère un peu sur les tableaux 2D... J'ai déjà cherché et trouvé pleins de choses sur google mais je comprend pas tout...
 
Je dois déclarer un tableau 2D de int dont les dimensions nbl et nbc sont connues :
 
Allocatation statique

Code :
  1. int tab2D[nbl][nbc];
  2. int ic,il;    // index colonnes , lignes
  3. // Affichage
  4.     for(il=0 ; il<nbl ; pl++)     
  5.     {
  6.         for(ic=0 ; ic<nbc ; ic++)   
  7.                 printf("%d ",tab2D[il][ic]);
  8.         printf("\n" );
  9.     }


 
Je voudrais remplacer tab2D[il][ic] par *(tab2D + ...) impossible de trouver les ... qui vont bien.
 
Allocation dynamique
Maintenant nbl et nbc ne sont connus qu'à l'exécution du programme.
Sachant que je veux pourvoir utiliser un adressage type tab2D[il][ic] et *(tab2D + ...), comment déclarer l'alloc ?
 

Code :
  1. int** tab2D;    // Je dois bien déclarer comme ca pour pouvoir ensuite faire du tab2D[il][ic] = x;
  2.     if((tab2D = (int**) malloc(nbc*nbl*sizeof(int)))==NULL)
  3.     {
  4.         printf("Allocation fail\n" );
  5.         exit(EXIT_FAILURE);
  6.     }


=> Marche pas...
 

Code :
  1. int** tab2D;    // Je dois bien déclarer comme ca pour pouvoir ensuite faire du tab2D[il][ic] = x;
  2.     if((tab2D = (int**)malloc(nbl*sizeof(int*)))==NULL)
  3.     {
  4.         printf("Allocation fail\n" );
  5.         exit(EXIT_FAILURE);
  6.     }
  7.     for(pl=0;pl<nbl;pl++)
  8.     {
  9.         if((tab2D[pl] = (int*)malloc(nbc*sizeof(int)))==NULL)
  10.         {
  11.             printf("Allocation fail\n" );
  12.             exit(EXIT_FAILURE);
  13.         }
  14.     }


=> Ceci est un tableau de pointeurs, et non un tableau 2D ?
 
Merci d'avance pour votre aide

mood
Publicité
Posté le 16-11-2008 à 15:39:05  profilanswer
 

n°1812795
olivthill
Posté le 16-11-2008 à 20:12:08  profilanswer
 

Si je me souviens bien, on peut remplacer

tab2D[il][ic]

par

*(tab2D + il * nbc + ic)

EDIT : Je me suis trompé, il manque une étoile, c'est :

*(*tab2D + il * nbc + ic)


Pour l'allocation dynamique, il faut imaginer un arbre plutôt qu'un damier. Cela devrait aider à comprendre, par exemple, que le premier tableau (le tableau des pointeurs de pointeurs, en **) n'a pas besoin d'avoir nbc * nbl éléments, que nbl éléments suffit.
 
Par ailleurs, il faudrait soigner la présentation, par exemple en ayant des indentations de taille fixe (en préférant utiliser toujours trois ou quatre espaces plutôt que la touche de tabulation qui donne des résultats aléatoires) en ne mettant pas d'espace avant les points virgules et les virgules, mais en mettant toujours un espace après ces deux signes, et en mettant un espace avant et après les signes arithmétiques.
 


Message édité par olivthill le 18-11-2008 à 07:38:05
n°1812797
sherminato​r+
Rock'n'Roll Damnation
Posté le 16-11-2008 à 20:20:04  profilanswer
 

Citation :

*(tab2D + il * nbc + ic)


Marche pas (à ma grande surprise justement !) ... Ce qui marche, c'est ça (avec un tab2D déclaré en statique ou en dynamique avec la 2ème méthode) :
 

Citation :

*(*tab2D + il * nbc + ic)

n°1812880
Joel F
Real men use unique_ptr
Posté le 17-11-2008 à 09:42:17  profilanswer
 

On peut aussi faire les choses proprement et alloué des tableaux 2D qui ne nécessitent pas cette gymnastique :

 
Code :
  1. float** alloc_array( int h, int w )
  2. {
  3.   /* Allocation des h pointeurs sur les debuts de lignes */
  4.   float** m = (float**)malloc(h*sizeof(float*));
  5.   /* La premiere ligne pointe vers le debut de l'espace memoire contigu du tableau */
  6.   m[0] = (float*)malloc(h*w*sizeof(float));
  7.   /* Pre-calcul des debut de lignes 1 à h-1 */
  8.   for(int i=1;i<h;i++) m[i] = m[i-1]+w;
  9.   return m;
  10. }
  11. void release_array(float** m)
  12. {
  13.   free( m[0] );
  14.   free( m);
  15. }
 

L'accès en en l,c se fait via : tab[l][c].
Les gens intelligents trouveront aussi par eux mêmes comment en modifiant ce code, on peut gérer des tableaux à indices négatifs ;)


Message édité par Joel F le 17-11-2008 à 14:33:27
n°1812892
h0taru
Posté le 17-11-2008 à 10:01:16  profilanswer
 

Salut,
 

sherminator+ a écrit :

Ceci est un tableau de pointeurs, et non un tableau 2D ?


 
Il me semble qu'en C les tableaux dit 2D sont des tableaux de pointeurs.
 
Pour ton premier exemple d'allocation dynamique, tu crée un tableau à une dimension. En toute logique tu devrais declarer un simple pointeur et non un pointeur sur pointeur. Apres c'est "ton esprit" qui va le découper pour en faire un tableau 2D.
 
edit pour au dessus:
je croyais que les gens intelligents étaient ceux qui savaient écrire du code propre et commenté!

Message cité 2 fois
Message édité par h0taru le 17-11-2008 à 10:11:32
n°1813000
Joel F
Real men use unique_ptr
Posté le 17-11-2008 à 14:32:34  profilanswer
 

h0taru a écrit :


je croyais que les gens intelligents étaient ceux qui savaient écrire du code propre et commenté!


 
Oui, correction faite. Les gens intelligents m'auraient indiqué la fautes de frappe dans sizeof au lieu de faire genre ;)
 

n°1813018
matafan
Posté le 17-11-2008 à 15:00:42  profilanswer
 

h0taru a écrit :

Il me semble qu'en C les tableaux dit 2D sont des tableaux de pointeurs.


Non justement, les tableaux 2D (du genre tab[i][j]) sont un seul bloc de i*j éléments.

n°1813221
h0taru
Posté le 17-11-2008 à 23:50:06  profilanswer
 

Au temps pour moi. je dois manquer d'intelligence  :)

n°1813626
sligor
Posté le 18-11-2008 à 20:45:16  profilanswer
 

matafan a écrit :


Non justement, les tableaux 2D (du genre tab[i][j]) sont un seul bloc de i*j éléments.


oui mais ce sont également des tableaux de pointeurs même en allocation statique.
tab[i] est bien un pointeur vers le début de la colonne.

Message cité 1 fois
Message édité par sligor le 18-11-2008 à 20:45:36
n°1813702
matafan
Posté le 19-11-2008 à 10:07:34  profilanswer
 

sligor a écrit :


oui mais ce sont également des tableaux de pointeurs même en allocation statique.
tab[i] est bien un pointeur vers le début de la colonne.


Je trouve que présenter les choses comme tu le fais est un peu trompeur. Oui, tab[i] a bien le type int *, mais la valeur de tab[i] n'est stockée nul part en mémoire. Seul le compilo connait la connait. C'est pour ça qu'on ne peut pas dire ce qu'a dit h0taru, c'est à dire que "les tableaux dit 2D sont des tableaux de pointeurs". Ce n'est pas vrai.  
 
Ce que je veux dire, c'est que quand on fait "int tab[2][2]", tout ce qu'on a en mémoire c'est 4 int consécutifs. Il n'y a pas de pointeur là dedans.

mood
Publicité
Posté le 19-11-2008 à 10:07:34  profilanswer
 

n°1814104
h0taru
Posté le 20-11-2008 à 07:51:29  profilanswer
 

Ca dépend comment on voit les choses, matafan.
 
Une succession de 4 int est fondamentalement un tableau à 1 dimension. Le C permet d'écrire tab[2][2] mais considérer que c'est de la 2D est selon moi un abus de langage.
 
Dans le doute, j'vais regarder le K&R dans la journée :)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Problème courant du tableau 2D

 

Sujets relatifs
pointeur sur un tableau ? est-ce faisable ?tri d'un tableau
[resolu]préremplir une case de FORMulaire : probleme avec guillemetsSupprimer une ligne d'un tableau en javascript
Petite loupe dans case d'un tableau no javascriptProblème IE6, et oui, encore 15% des internautes !!
probleme de css avec inputprobleme css dans fichier .php
[Batch] xcopy et le changement d'heure, problème "à la con" !Problème avec la dernière version d'EasyPHP
Plus de sujets relatifs à : Problème courant du tableau 2D


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR