Bonjour,
je voudrais juste savoir quelle est la difference entre un tableau de 200 caracteres et une allocation dynamique de 200 caracteres? Est ce la possibilite de reallouer de la place alors que pour un tableau ce n'est pas possible?
Merci.
Bonjour,
je voudrais juste savoir quelle est la difference entre un tableau de 200 caracteres et une allocation dynamique de 200 caracteres? Est ce la possibilite de reallouer de la place alors que pour un tableau ce n'est pas possible?
Merci.
L'avantage de l'allocation dynamique, c'est de pouvoir allouer une zone de taille inconnue lors de la compilation du programme.
Par exemple quand tu lis un fichier, tu ne sais pas lorsque tu écris le programme quelle taille il va faire.
Maintenant si c'est pour écrire :
Y a pas beaucoup d'intérêt, le seul éventuellement est de disposer d'une zone qu'on peut aggrandir par la suite avec realloc(). Mais bon là comme ça, je ne trouve pas d'exemple valable dans lequel on pourrait procéder ainsi.
Code : Sélectionner tout - Visualiser dans une fenêtre à part un_type *p = malloc(200 * sizeof *p);
Un tableau de 200 caracteres et un pointeur vers un espace pouvant contenir 200 caracteres sont deux choses differentes.
- la taille du tableau est fixee est la compilation, alors que le pointeur se voit donner l'adresse d'un bloc alloue a l'execution
- la taille du tableau n'est pas modifiable, celle de l'espace vers lequel le pointeur pointe est eventuellement modifiable
- avant initialisation, le pointeur peut contenir n'importe quelle adresse, valide ou non.
- l'espace alloue doit etre libere explicitement par un free()
En resume, char a[200] et char *a ne sont pas la meme chose. a[200] demande qu'un espace de 200 caracteres soit nomme "a". char *a demande qu'un espace d'un certaine taille puisse contenir un pointeur, nomme "a". Ce pointeur a pourra contenir l'adresse d'un char, d'un tableau de char, ou rien.
Par contre, on dit qu'un tableau et un pointeurs sont equivalents car leur usage est similaire, et le nom d'un tableau est souvent (mais pas toujours) interchangeable avec un pointeur de meme type.
Ok merci.
Mais bon je pense que pour ton exemple il peut y avoir un interet.
Par exemple, on alloue une taille de 50 caracteres et on y ecris un chemin de destination d'un fichier par defaut.
Mais par la suite l'utilisateur peut modifier ce chemin et s'il ecrit un chemin plus long que 50 caracteres comment je fais??
Merci.
Faux. En C99, on a les Variable Length Array, i.e. des tableaux dont la taille est inconnue a la compilation:Envoyé par DaZumbaest un code C99 conforme (pour autant que je sache sur les types autorises sur n pour donner la taille du tableau).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <stdio.h> #include <stdlib.h> int main(void) { char buf[10]; long int n; printf("taille du tableau ? "); if (fgets(buf, sizeof buf, stdin) != NULL) { n = strtol(buf, NULL, 10); /* un beau tableau.. */ int tab[n]; for (int i = 0; i < n; i++) tab[i] = i; for (int i = 0; i < n; i++) printf("tab[%d] = %d\n", i, tab[i]); } }
Par contre, je n'ai pas la norme sous la main pour savoir comment il gere une valeur negative... (gcc ne se lamente pas que n soit signe, et si je donne un n negatif a l'execution je n'ai pas de plantage...)
Non: l'adresse d'un char, ou NULL. Ou alors l'adresse d'un element d'un taleau de char, qui est juste un cas particulier du premier (&tab[0], par exemple). Pas tout a fait pareil.Envoyé par DaZumba
Entre autres, oui.Envoyé par davkick
Implémenter un getline()...Envoyé par Gamdwin
En théorie, oui. Mais tant que je vois écrit 'broken' dans l'état d'avancement de gcc 3.x, je n'en recommande pas l'usage.Envoyé par alveric
(pas mieux en gcc 4.0)
http://gnu.tutorgig.com/software/gcc/gcc-4.0/c99status.html
D'autre part, à ma connaissance, un VLA, n'est pas retaillable, et son utilisation ne remplace pas un malloc()...
Comme l'indique Emmanuel, l'implementation de ces tableaux est compliquee. Ils ont tente de corriger le fiasco de alloca(), mais ce n'est decidement pas si facile que cela. Pour l'instant, malloc() + free(), qui ne posent pas de probleme a un utilisateur averti.Envoyé par alveric
En fait, c'est l'adresse d'un char, d'un espace contigu de plusieurs chars, NULL ou n'importe quoi. Si tu admets que char a[200] est un espace contigu de 200 chars nomme a, alors faire char *p = a mets l'adresse d'un espace contigu de 200 chars dans p. Cette adresse est egalement celle du premier element de a, en effet.Envoyé par alveric
C'est parce que '&a[0]' s'écrit aussi 'a + 0', ou encore 'a'.Envoyé par DaZumba
Je ne pensais pas que c'etait autant pas avance dans gcc... Bon, au moins je ferais attentionEnvoyé par Emmanuel Delahaye
Je ne disais pas le contraire, je signalais juste que la taille d'un tableau peut ne pas etre connue a la compilation. Apres, ce n'est pas la solution miracle universelle...Envoyé par Emmanuel Delahaye
alveric a écrit
Qui a raison ? Je ne sais pas trop, c'est tout en nuances. Qui a tort ? je sais : Le concept des tableaux en C. Je ne crois pas à la notion d'objet tableau en C (aucune opération n'est définie sur les tableaux, uniquement sur les objets du tableau, ( à part peut être sizeof et & qui ne sont pas vraiment des opérations dynamiques)) . Ils correspondent simplement à un arrangement mémoire d'un groupe d'objets du même type associé à une syntaxe simplificatrice []. On aurait du s'arreter là et ce serait simple.DaZumba a écrit:
Non: l'adresse d'un char, ou NULL. Ou alors l'adresse d'un element d'un taleau de char, qui est juste un cas particulier du premier (&tab[0], par exemple). Pas tout a fait pareil.char *a demande qu'un espace d'un certaine taille puisse contenir un pointeur, nomme "a". Ce pointeur a pourra contenir l'adresse d'un char, d'un tableau de char, ou rien.
La complexité vient du fait qu'il y a le "vrai" type de la variable dont on a l'adresse , et ici a contient bien l'adresse d'un char et un type "apparent" utilisé par le compilateur pour le calcul des adresses. Par exemple, a+1 est l'adresse du deuxième élément du tableau. &a+1 désigne quoi ? (d'ailleurs quel est le sens de &a puisque a n'est pas un objet (c'est une rvalue) ?) . Si la discussion reste assez académique pour les tableaux à une dimension, elle devient cruciale pour les tableaux à plusieurs dimensions et du coup ces tableaux sont des entités complexes à gérer
Les tableaux ne sont pas des objets a part entiere, notamment parce que le passage d'arguments aux fonctions se fait par valeur, et on se retrouverait avec une copie qui nuierait aux performances. Cependant, certaines operations font des tableaux des objets, comme la prise d'un pointeur vers un tableau (*array)[N].Envoyé par diogene
Sans optimisation, le code genere par a[3] sera different si a est declare comme int a[N] ou int *a. Dans le premier cas, a[3] est trois elements apres le debut de l'objet nomme a, dans le second, c'est trois elements apres l'objet pointe par a. Un tableau est donc un objet different d'un pointeur.
Mais la encore on est un peu piege par la norme pour les tableaux a plusieurs dimensions. Le code suivant:
avec
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 int arr[NB_LINES][NB_COLS]; function(&arr[0][0], NBLINES, NBCOLS);
invoque un comportement indefini. La norme ANSI ne definit pas l'acces a (&arr[0][0])[i] pour i >= NBCOLS (meme si la plupart des implementations donnent le resultat attendu). Donc un tableau n'est pas completement vu comme un espace contigu - j'ai un peu beaucoup tort sur ce point.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 void function(int *arr, int nlines, int ncols) { arr[i * ncols + j] = 5; }
DaZumba a écrit:Si tu évoque la déclaration de pointeur sur tableau, il n'y a pas là d'opération. Sinon, il y a là un déréférencement de pointeur classique associé à la notation []certaines operations font des tableaux des objets, comme la prise d'un pointeur vers un tableau (*array)[N].
Ce qui présuppose le caractère objet du tableau (ce que je conteste). a[3] : Je crois que ceci est tout à fait équivalent à écrire *(a+3). Quelle est la différence entre les deux ? Dans le premier cas, c'est trois éléments après celui dont l'adresse est a et dans le second cas également . Je ne vois pas la nuanceDans le premier cas, a[3] est trois elements apres le debut de l'objet nomme a, dans le second, c'est trois elements apres l'objet pointe par a
Ca c'est sur. Mais est-ce un objet ou une valeur adresse pour le C ? Si tu écrit Tab = ..., le compilateur ne dira pas que l'opération = n'est pas définie ou interdite pour un tableau mais que Tab est une rvalueUn tableau est donc un objet different d'un pointeur.
Mais comment, en pratique, le compilateur peut-it savoir si cette condition est vraie ou fausse ?La norme ANSI ne definit pas l'acces a (&arr[0][0])[i] pour i >= NBCOLS
Si c'est vrai, c'est grave et ça remet en cause beaucoup de choses . Comment es tu arrivé à cette conclusion ?Donc un tableau n'est pas completement vu comme un espace contigu
Non. Un tableau est un objet et une lvalue. Pas contre, ce n'est pas une lvalue modifiable. La norme est claire sur ce point:Envoyé par diogene
Envoyé par norme C99Il ne peut pas. De toute facon, quelque-soit la dimension d'un tableau et sa portee, le C ne fait pas de bound-checking. Cela accelere les traitements, mais peut etre cause de bugs.Envoyé par diogene
Je me suis mal exprime, je ne parlais que des tableaux a plusieurs dimensions. La norme donne un exemple (et parle d'objet tableau, d'ailleurs):Envoyé par diogene
A aucun moment ils n'assurent que les 3 tableaux d'entiers qui forment le tableau 2D sont contigus, meme si je l'ai toujours verifie dans la pratique...Envoyé par C99
Enfin, c'est tout de meme une discussion un peu theorique
Si. Il est dit ailleurs qu'un tableau est une suite contigüe d'objets identiques. Il n'est pas précisé de restrictions concernants les dimensions.Envoyé par DaZumba
La notion de dimension est humaine et non informatique. Sur le plan de la représentation mémoire, un tableau est toujours continu quelque soit son nombre de dimensions (évidemment, sinon, l'arithmétique des pointeurs ne fonctionnerait pas et on ne pourrait jamais calculer l'adresse d'un élément avec les dimensions...).
Ne pas confondre avec les tableaux de pointeurs représentant des pseudos-tableaux à n dimensions... Ceux-ci ne sont pas continus.
Ok, ce doit etre pour cela qu'il faut se mefier des (&array[0][0])[x]...Envoyé par Emmanuel Delahaye
C'est la norme C99 que tu évoques. Une récente discussion sur le forum montrait que les tableaux avaient évolué dans cette norme. Leur concept de base peut être aussi? (ce ne serait pas un mal). Si on considère que les tableaux peuvent être de longueur variable, ils ne peuvent être créés qu'à l' exécution donc de façon dynamique. Leur adresse ,notamment, doit donc être mise dans quelque chose , dans un objet. Il y a donc là nécessairement un objet associé au tableau, qu'on peut appeler l'objet (constant) de type Tableau. Mais auparavant, la situation n'impose pas d'associer un objet spécial à un tableau (en dehors de ses éléments bien sur)
Ce n'est pas le diagnostic du compilateur (Non C99 il est vrai) En C++, un objet constant est assimilé par le compilateur à une valeur, mais en C (non C99) je ne crois pas. Tout indique que Tab est une valeur.diogene a écrit:
Mais est-ce un objet ou une valeur adresse pour le C ? Si tu écrit Tab = ..., le compilateur ne dira pas que l'opération = n'est pas définie ou interdite pour un tableau mais que Tab est une rvalue
Non. Un tableau est un objet et une lvalue. Pas contre, ce n'est pas une lvalue modifiable.
C'est exact . Mais comment expliquer correctement le concept des tableaux en CEnfin, c'est tout de meme une discussion un peu theorique
Je me trompe peut etre, mais il me semble qu'un tableau a toujours ete une unmodifiable lvalue. Je n'ai pas la norme C90 sous la main, donc je ne peux pas le certifier.
Les variable-length arrays sont en effet une introduction du C99, mais je ne pense pas qu'ils necessitent une redefinition de la notion de tableau - on peut les voir comme une redefinition plus propre et plus utilisable d'alloca().
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager