[C] Tableau dynamique

Tableau dynamique [C] - C - Programmation

Marsh Posté le 05-01-2005 à 11:03:49    

Salut à tous,
 
J'aurais une petite question à vous poser concernant les tableaux dynamiques en C.
A partir d'une variable que l'on saisi à l'intérieur d'un programme : nombre par exemple, je souhaiterais créer un tableau ayant pour taille le "nombre" que l'on a saisi dans le programme.
 
Merci de votre aide

Reply

Marsh Posté le 05-01-2005 à 11:03:49   

Reply

Marsh Posté le 05-01-2005 à 11:40:23    

arnaudm57 a écrit :

Salut à tous,
 
J'aurais une petite question à vous poser concernant les tableaux dynamiques en C.
A partir d'une variable que l'on saisi à l'intérieur d'un programme : nombre par exemple, je souhaiterais créer un tableau ayant pour taille le "nombre" que l'on a saisi dans le programme.
 
Merci de votre aide

Tu devras sûrement utiliser la fonction malloc().
Bon maintenant à toi de chercher comment faire !


Message édité par darkoli le 05-01-2005 à 11:40:40

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 05-01-2005 à 11:51:54    

Hello !
 
Pour un tableau de doubles par exemple, soit tu fais :
 
- alloc dynamique :
// déclaration du pointeur sur la première case du tableau
double * tab;  
 
// allocation des cases
tab=(double *)malloc(NbElements*sizeof(double));
 
// acces à la case i
tab[i]   ou  *(tab+i)
 
// acces au pointeur de la case i
&tab[i] ou (tab+i)
 
// libération mémoire après utilisation
free(tab);
 
- allocation statique
 
// déclaration du tableau de doubles de taille fixée
double tab[NbElements];  
 
// allocation des cases (pas besoin)
 
// acces à la case i
tab[i]   ou  *(tab+i)
 
// acces au pointeur de la case i
&tab[i] ou (tab+i)
 
// libération mémoire après utilisation (pas besoin)
 
Voili voili !

Reply

Marsh Posté le 05-01-2005 à 12:39:50    

allawos a écrit :


 
- alloc dynamique :
// déclaration du pointeur sur la première case du tableau
double * tab;  
 
// allocation des cases
tab=(double *)malloc(NbElements*sizeof(double));


pourquoi cast tu ? qu'est-ce qui se passe si tab n'est plus un pointeur de double mais de float ? N'oublie pas de gérer le cas ou malloc retourne NULL. N'oublie pas '#include <stdlib.h>'

Reply

Marsh Posté le 05-01-2005 à 13:07:14    

c'est OBLIGATOIRE de faire un cast comme ça si il y a incompatibilité en le cast et la variable de réception il y aura probablement un warning du compilo (même si ça dépend du compilo).

Reply

Marsh Posté le 05-01-2005 à 13:22:17    

dreameddeath a écrit :

c'est OBLIGATOIRE de faire un cast comme ça si il y a incompatibilité en le cast et la variable de réception il y aura probablement un warning du compilo (même si ça dépend du compilo).


Pas en C (ou alors avec un très vieux compilateur qui ne connait pas 'void').
 
http://mapage.noos.fr/emdel/notes.htm#malloc
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-01-2005 à 14:11:33    

je n'ai pas voulu dire qu'il est obligatoire d'un point de vue syntaxique mais plutôt d'un point de vue sureté du code (vérication du compilateur de la compatibilité du cast et de la variable de destination)

Reply

Marsh Posté le 05-01-2005 à 14:17:31    

dreameddeath a écrit :

je n'ai pas voulu dire qu'il est obligatoire d'un point de vue syntaxique mais plutôt d'un point de vue sureté du code (vérication du compilateur de la compatibilité du cast et de la variable de destination)


Bah non, justement.  
 
Le compilo ne vérifie rien si tu castes un pointeur en un autre. Alors qu'en ne mettant rien, il va vérifier justement si tu fais des bétises ou pas (au niveau de la constness entre autres, et de void*).

Reply

Marsh Posté le 05-01-2005 à 14:23:32    

il va vérifier quoi sans cast?
malloc rendant un (void *) comment le compilo sait ce que ça représente réellement? Alors qu'en "castant", tu dis explicitement ce que représente ce que tu a alloué, et ensuite lors de l'affectation le compilo peut comparer. le void * n'est qu'un fourre tout pas beau :p !

Reply

Marsh Posté le 05-01-2005 à 14:23:51    

Lam's a écrit :

Bah non, justement.  
 
Le compilo ne vérifie rien si tu castes un pointeur en un autre. Alors qu'en ne mettant rien, il va vérifier justement si tu fais des bétises ou pas (au niveau de la constness entre autres, et de void*).


 
+1
 
Un cast ça sert à "forcer" le type. Donc le compilo il ferme sa gueule dans ce cas.
Il n'y a pas besoin d'utiliser un cast lorsque le type de départ est void * !

Reply

Marsh Posté le 05-01-2005 à 14:23:51   

Reply

Marsh Posté le 05-01-2005 à 14:34:46    

pour moi il ne doit y avoir aucun transtypage implicite car ça peut être dangereux.  
 
Par exemple avec le code :

Code :
  1. // déclaration du pointeur sur la première case du tableau  
  2. double * tab;
  3. /* 100 lignes de code */
  4. ...
  5. // allocation des cases  
  6. tab=(double *)malloc(NbElements*sizeof(double));


 
tu te dis que double n'est pas le bon type mais c'est mieux un int ou autre (evolutivité du code), tu remplace double par int mais tu oublie certains endroits :

Code :
  1. // déclaration du pointeur sur la première case du tableau  
  2. int * tab;
  3. /* 100 lignes de code */
  4. ...
  5. // allocation des cases  
  6. tab=(double *)malloc(NbElements*sizeof(double));


 
tu recompiles et paf t'a un message alors que si tu mets pas le cast tu n'as rien ...

Reply

Marsh Posté le 05-01-2005 à 14:48:00    

dreameddeath a écrit :

pour moi il ne doit y avoir aucun transtypage implicite car ça peut être dangereux.  


C'est parce que tu mets en oeuvre des pratiques dangereuses. Le transtypage ne fait qu'ajouter à la confusion générale...

Citation :


Par exemple avec le code :

Code :
  1. // déclaration du pointeur sur la première case du tableau  
  2. double * tab;
  3. /* 100 lignes de code */
  4. ...
  5. // allocation des cases  
  6. tab=(double *)malloc(NbElements*sizeof(double));


 
tu te dis que double n'est pas le bon type mais c'est mieux un int ou autre (evolutivité du code), tu remplace double par int mais tu oublie certains endroits :

Code :
  1. // déclaration du pointeur sur la première case du tableau  
  2. int * tab;
  3. /* 100 lignes de code */
  4. ...
  5. // allocation des cases  
  6. tab=(double *)malloc(NbElements*sizeof(double));


 
tu recompiles et paf t'a un message alors que si tu mets pas le cast tu n'as rien ...


Les pratiques dangereuses sont:
 
- 100 lignes entre la définition d'un objet et son utilisation
- utilisation du type pour déterminer la taille.
 
Si tu ne mets pas de transtypage, le code est toujours correct, à condition d'utilises non pas le type, (qui peut changer, comme tu l'as fait remarqué, et c'est effectivement vrai sur le terrain) mais le pointeur pour déterminer la taille. La maintenance s'en trouve simplifiée et le code est plus sûr. D'autre part, il faut appliquer au maximum le principe de réduction de la portée des objets et des fonctions.
 
La bonne pratique est celle-ci

int *tab = malloc (NbElements * sizeof *tab);


 
Je rappelle :
 
http://mapage.noos.fr/emdel/notes.htm#malloc
 
et j'ajoute:
 
http://mapage.noos.fr/emdel/notes.htm#portee


Message édité par Emmanuel Delahaye le 05-01-2005 à 15:11:51

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-01-2005 à 14:49:40    

d'où ma deuxième question : tu fais quoi si tab n'est plus un double * ? avec ton usage de malloc, tu te fais avoir.

Reply

Marsh Posté le 05-01-2005 à 14:52:29    

une petite question en passant, en parlant de stdlib, y sort d'ou le malloc qui oblige à caster quand on inclut pas stdlib ?

Reply

Marsh Posté le 05-01-2005 à 14:55:19    

de nulle part. En C, les convertion void* <-> T* sont implicites car sures et bien définies.
 
 
edit du message précédent : crammé

Reply

Marsh Posté le 05-01-2005 à 14:59:38    

oui mais pq cette différence de comportement quand on inclut pas stdlib ?

Reply

Marsh Posté le 05-01-2005 à 14:59:43    

push a écrit :

une petite question en passant, en parlant de stdlib, y sort d'ou le malloc qui oblige à caster quand on inclut pas stdlib ?


Parce que le programmeur neuneu de base croit qu'avec un cast il va corriger tous ses problèmes. Ce genre d'idée reçue a la vie longue et doit être combattue avec la dernière énergie. (Où est mon lance flammes)
 
La vérité est que que si il n'y a pas de prototype visible pour malloc() (qui ne retourne pas int, mais void*), le comportement est indéterminé  (int dans un pointeur, ça le fait pas) et le cast ne corrige rien. Il faut donc obligatoirement inclure <stdlib.h>, et regler son compilateur correctement pour qu'il détecte l'absence de prototype.


Message édité par Emmanuel Delahaye le 05-01-2005 à 15:01:06

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-01-2005 à 15:00:14    

je ne comprends pas ta remarque Taz? qu'entends tu exactement par : "si tab n'est plus un double *" ?
 
EDIT : oublie la question Taz j'ai rien dis ...


Message édité par dreameddeath le 05-01-2005 à 15:02:45
Reply

Marsh Posté le 05-01-2005 à 15:06:00    

:jap:  
 
(t'as oublié une petite * dans ta bonne pratique)

Reply

Marsh Posté le 05-01-2005 à 15:11:17    

push a écrit :

:jap:  
 
(t'as oublié une petite * dans ta bonne pratique)


Oui, et ça ne compile pas. Pas dangereux. Code Corrigé.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-01-2005 à 15:37:53    


Il reste encore la méthode alloca.
 
C'est pareil qu'un tableau statique de taille variable, mais ca s'ecrit comme un malloc.
 
Par contre je ne sais si c'est disponible sur toutes les plateformes... (brk doit l'être donc...)

Reply

Marsh Posté le 05-01-2005 à 15:42:02    

rolphin a écrit :


C'est pareil qu'un tableau statique de taille variable, mais ca s'ecrit comme un malloc.


Ouille non. C'est pareil qu'un tableau en variable locale. Et comme le C99 permet désormais de faire des VLA, il n'y a plus trop de raison de l'utiliser. Déjà qu'il n'y en avait pas des masses avant: portée du tableau limitée à la fonction courante, taille limitée à la taille de pile disponible (et même pas forcément la taille de pile maximale), appel non portable, etc.

Reply

Marsh Posté le 06-01-2005 à 21:25:15    

rolphin a écrit :

Il reste encore la méthode alloca.
 
C'est pareil qu'un tableau statique de taille variable, mais ca s'ecrit comme un malloc.
 
Par contre je ne sais si c'est disponible sur toutes les plateformes... (brk doit l'être donc...)


 
Alloca n'alloue rien dans le tas ;) (donc ca n'a pas rapport avec brk :o). Ca ecrit dans ta pile et il est "free" en sorti de fonction comme une variable locale. Alloca ca poutre  [:jajax]

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed