Declaration d'un tableau en langage C
Fermé
basopro
Messages postés
100
Date d'inscription
vendredi 11 mars 2011
Statut
Membre
Dernière intervention
3 juin 2015
-
4 juil. 2011 à 18:18
basopro Messages postés 100 Date d'inscription vendredi 11 mars 2011 Statut Membre Dernière intervention 3 juin 2015 - 15 juil. 2011 à 19:54
basopro Messages postés 100 Date d'inscription vendredi 11 mars 2011 Statut Membre Dernière intervention 3 juin 2015 - 15 juil. 2011 à 19:54
A voir également:
- Declaration d'un tableau en langage C
- Tableau croisé dynamique - Guide
- Tableau ascii - Guide
- Comment faire un tableau - Guide
- Trier un tableau excel - Guide
- Comment imprimer un tableau excel sur une seule page - Guide
4 réponses
Hxyp
Messages postés
401
Date d'inscription
vendredi 28 janvier 2011
Statut
Membre
Dernière intervention
27 avril 2014
54
4 juil. 2011 à 18:46
4 juil. 2011 à 18:46
Bonjour,
Il faut utiliser les pointeurs, et leur donner l'adresse de la mémoire qu'on a allouer pour le tableau. Exemple pour un tableau de char
pour changer la taille du tableau vous pouvez libérer la mémoire qui est à l'adresse qu'on a mis dans le pointeur avec free, puis refaire un malloc comme si de rien en utilisant une nouvelle taille pour récupérer une nouvelle adresse. Ou utiliser realloc...
Pouvez aussi utiliser calloc pour réserver de la mémoire et la mettre directement à zéro..
***l'adresse du premier bloc de la taille du type, ce qui fait par exemple pour :
char *tableau=malloc(sizeof(char)*4);
donne en mémoire :
[char1][char2][char3][char4]
et donc le pointeur "tableau" contient l'adresse de [char1] si on incrémente la Valeur de "tableau" (donc l'adresse) de sizeof(char) on tombe sur [char2] etc..
petit bout de code pour expliquer ça :
ça affiche :
zx
Il faut utiliser les pointeurs, et leur donner l'adresse de la mémoire qu'on a allouer pour le tableau. Exemple pour un tableau de char
char *tableau; /* un pointeur */ tableau = malloc(sizeof(char)*20); /* on demande 20 char en mémoire */ /* tableau prend alors pour valeur l'adresse retournée par malloc */ if(tableau!=NULL) /* si l'opération à réussi tableau contient l'adresse des 20char (l'adresse du premier bloc de la taille du type***) */ { /* alors on peut utiliser tableau comme un simple tableau ici par exemple */ }
pour changer la taille du tableau vous pouvez libérer la mémoire qui est à l'adresse qu'on a mis dans le pointeur avec free, puis refaire un malloc comme si de rien en utilisant une nouvelle taille pour récupérer une nouvelle adresse. Ou utiliser realloc...
Pouvez aussi utiliser calloc pour réserver de la mémoire et la mettre directement à zéro..
***l'adresse du premier bloc de la taille du type, ce qui fait par exemple pour :
char *tableau=malloc(sizeof(char)*4);
donne en mémoire :
[char1][char2][char3][char4]
et donc le pointeur "tableau" contient l'adresse de [char1] si on incrémente la Valeur de "tableau" (donc l'adresse) de sizeof(char) on tombe sur [char2] etc..
petit bout de code pour expliquer ça :
#include <stdio.h> #include <stdlib.h> int main(void) { char *tab=malloc(sizeof(char)*4); /* tab à l'adresse du premier bloc de la taille d'un char */ tab+=sizeof(char); /* incrémente d'un char l'adresse contenu dans tab */ *tab='x'; /* met la lettre x dans l'emplacement */ tab-=sizeof(char); /* décrémente d'un char l'adresse contenu dans tab */ *tab='z'; /* y met un z */ printf("%s\n",tab); free(tab); return 0; }
ça affiche :
zx
Bonjour,
Tu as une réponse de Hxyp et fiddy qui t'explique comment allouer un tableau par malloc, mais leur réponse me paraît très générale et pas forcément
facilement réalisable par quelqu'un qui n'a pas une grosse pratique du C, c'est pourquoi je me permet d'ajouter ma réponse pour t'aider un peu plus :
Si ce que tu veux est un tableau qui grandit tout seul en fonction de ce qu'on y met, ça n'existe pas en C.
En C++ par contre oui (classes de STL Vector par exemple)
En java ou .net aussi avec les ArrayList ou Vector
Mais ceci est du au fait que ces 3 langages sont des langages objet contrairement au C.
Par contre, tu peut simuler ce fonctionnement grâce à l'allocation dynamique des tableaux en C :
Créer une structure MonTableau qui contient un pointeur sur le type de données souhaitées et la dernière taille allouée.
Créer un fonction qui s'appelle affecterDonnee(int indice,typedonnee donnee,MonTableau tableau)
Cette fonction va
- vérifier si l'indice est inférieur à la taille actuelle
- Si ce n'est pas le cas elle alloue un nouveau tableau de la taille + taille grossissement (growing en anglais)
- Toujours dans le cas où la taille était insuffisante, elle fait une copie des éléments de l'ancien tableau dans le nouveau tableau et modifie la taille indiquée dans la structure
- Dans tous les cas elle affecte la donnée pour l'indice concerné.
Évidemment, ce n'est pas très souple et on peut oublier d'appeler la fonction, mais ça fait partie des raisons d'existence des langages objets.
Pour être pragmatique, j'ai fais un petit programme qui démontre ce que j'avance, à toi de l'adapter à tes besoins.
Le problème c'est que le correcteur orthographique ne laisse pas passer alors que j'ai mis les balises code. Je ne comprends pas
Je vais essayer de le joindre dans un deuxième post, où sinon, si tu veux je te l'envoie en MP.
Cordialement
Tu as une réponse de Hxyp et fiddy qui t'explique comment allouer un tableau par malloc, mais leur réponse me paraît très générale et pas forcément
facilement réalisable par quelqu'un qui n'a pas une grosse pratique du C, c'est pourquoi je me permet d'ajouter ma réponse pour t'aider un peu plus :
Si ce que tu veux est un tableau qui grandit tout seul en fonction de ce qu'on y met, ça n'existe pas en C.
En C++ par contre oui (classes de STL Vector par exemple)
En java ou .net aussi avec les ArrayList ou Vector
Mais ceci est du au fait que ces 3 langages sont des langages objet contrairement au C.
Par contre, tu peut simuler ce fonctionnement grâce à l'allocation dynamique des tableaux en C :
Créer une structure MonTableau qui contient un pointeur sur le type de données souhaitées et la dernière taille allouée.
Créer un fonction qui s'appelle affecterDonnee(int indice,typedonnee donnee,MonTableau tableau)
Cette fonction va
- vérifier si l'indice est inférieur à la taille actuelle
- Si ce n'est pas le cas elle alloue un nouveau tableau de la taille + taille grossissement (growing en anglais)
- Toujours dans le cas où la taille était insuffisante, elle fait une copie des éléments de l'ancien tableau dans le nouveau tableau et modifie la taille indiquée dans la structure
- Dans tous les cas elle affecte la donnée pour l'indice concerné.
Évidemment, ce n'est pas très souple et on peut oublier d'appeler la fonction, mais ça fait partie des raisons d'existence des langages objets.
Pour être pragmatique, j'ai fais un petit programme qui démontre ce que j'avance, à toi de l'adapter à tes besoins.
Le problème c'est que le correcteur orthographique ne laisse pas passer alors que j'ai mis les balises code. Je ne comprends pas
Je vais essayer de le joindre dans un deuxième post, où sinon, si tu veux je te l'envoie en MP.
Cordialement
basopro
Messages postés
100
Date d'inscription
vendredi 11 mars 2011
Statut
Membre
Dernière intervention
3 juin 2015
1
12 juil. 2011 à 20:51
12 juil. 2011 à 20:51
Salut java4ever , juste pour t'avouer que ta réponse ma sortir du trou et aussi ta manière de coder ma convaincu. Étant débutant je suis déjà un passionné de la programmation informatique et je souhaite avoir une bonne connaissance dans ce domaine .
J'aimerais donc savoir s'il est possible d'avoir votre contact (facebook ou mail ) pour vos demander quelques conseils de temps en temps.
merci de me comprendre et de me repondre.
Je recevrai votre eponse par dans ma boite mail.
J'aimerais donc savoir s'il est possible d'avoir votre contact (facebook ou mail ) pour vos demander quelques conseils de temps en temps.
merci de me comprendre et de me repondre.
Je recevrai votre eponse par dans ma boite mail.
basopro
Messages postés
100
Date d'inscription
vendredi 11 mars 2011
Statut
Membre
Dernière intervention
3 juin 2015
1
15 juil. 2011 à 19:54
15 juil. 2011 à 19:54
Salut java4ever , juste pour t'avouer que ta réponse ma sortir du trou et aussi ta manière de coder ma convaincu. Étant débutant je suis déjà un passionné de la programmation informatique et je souhaite avoir une bonne connaissance dans ce domaine .
J'aimerais donc savoir s'il est possible d'avoir votre contact (facebook ou mail ) pour vos demander quelques conseils de temps en temps.
merci de me comprendre et de me repondre.
Je recevrai votre eponse par dans ma boite mail.
J'aimerais donc savoir s'il est possible d'avoir votre contact (facebook ou mail ) pour vos demander quelques conseils de temps en temps.
merci de me comprendre et de me repondre.
Je recevrai votre eponse par dans ma boite mail.
Bonjour, le code promis :
#include <stdio.h> #include <stdlib.h> /***** Exemple simplifié de tableau à grossissement automatique en C Date de création : 4 juillet 2011. **/ typedef struct { int taille; long *elements; int taille_Grossissement; } TableauDeLongs; void affecterTableauDeLongs(TableauDeLongs *tab,long valeur, int index); int main() { TableauDeLongs montableau = {0, 0, 10}; // Mon tableau "intelligent" (si on l'aide un peu) // faire une boucle de saisie de nombre entiers et les mettre dans un tableau auto grossissant en C printf("Saisir autant de nombres (entiers long) que souhaité : arrêt si on rentre le nombre 9999\n"); long unnombre = 0; int indexsuivant = 0; do { printf("Saisir un nombre à mettre das le tableau : "); scanf("%ld",&unnombre); affecterTableauDeLongs(&montableau, unnombre, indexsuivant); ++indexsuivant; // pour le prochain } while (unnombre != 9999); printf("Voici la liste des saisies stockées dans le tableau rangées par 5\n"); int i,j; for (i = 0,j = 0;i < indexsuivant;++i,++j) { printf("\t%ld", montableau.elements[i]); if (j < 4) { printf(", "); } else { j = -1; printf("\n"); } } } // Gestion en C d'un grossissement de tableau "automatique" : l'index part de 0 void affecterTableauDeLongs(TableauDeLongs *tab,long valeur, int index) { if (index < 0) { fprintf(stderr, "*****index negatif interdit*********\n"); return; } printf("\nDemande affecter tableau[%d]\n", index); if (index >= tab->taille) { int nouvelle_taille; // calcul de la nouvelle taille en multiple de la taille de grossissement (on aurait pu utiliser la fonction ceil(), mais bon int nombre_unites = (index + 1)/tab->taille_Grossissement; if (((index + 1) % tab->taille_Grossissement) != 0) nombre_unites += 1; nouvelle_taille = nombre_unites * tab->taille_Grossissement; printf("\n>>>>>>>>>Augmentation de la taille du tableau de %d à %d\n",tab->taille, nouvelle_taille); // nouvelle allocation mémoire et récup des anciens éléments // on pourrait utiliser realloc, mais ça me parait plus clair comme ça, et en plus on peut initialiser à 0 les nouvelles valeurs long *nouveau_elements = calloc(nouvelle_taille,sizeof(long)); memset(nouveau_elements,0,nouvelle_taille * sizeof(long)); // met des 0 partout memcpy(nouveau_elements, tab->elements, tab->taille*sizeof(long)); // copie de l'ancien tableau if (tab->taille > 0) { free(tab->elements); } tab->elements = nouveau_elements; // remplace le tableau tab->taille = nouvelle_taille; } tab->elements[index] = valeur; }
basopro
Messages postés
100
Date d'inscription
vendredi 11 mars 2011
Statut
Membre
Dernière intervention
3 juin 2015
1
5 juil. 2011 à 13:55
5 juil. 2011 à 13:55
merci pour ce service .merci de me sortir de ce trou
while (life=continue)
{
programmation vivra et revivra
}
while (life=continue)
{
programmation vivra et revivra
}
periplasme
Messages postés
391
Date d'inscription
vendredi 22 avril 2011
Statut
Membre
Dernière intervention
5 février 2013
53
5 juil. 2011 à 09:52
5 juil. 2011 à 09:52
après, on peux aussi utilisé les listes chainés ... c'est un peu plus chiant a utilisé qu'un tableau (quoi que, avec de l'entrainement, ça devient tout aussi naturel)
mais au final, on a un simili-tableau qui peux s'étendre quasi sans limite (juste celle de la mémoire disponible)
mais au final, on a un simili-tableau qui peux s'étendre quasi sans limite (juste celle de la mémoire disponible)
basopro
Messages postés
100
Date d'inscription
vendredi 11 mars 2011
Statut
Membre
Dernière intervention
3 juin 2015
1
5 juil. 2011 à 14:19
5 juil. 2011 à 14:19
merci pour votre aide
4 juil. 2011 à 20:01
C'est plutôt tab+=1 (ou tab++) qu'il faut mettre que tab+=sizeof(char) pour décaler d'un élément (quel qu'il soit).
Ici effectivement, ça ne change rien car sizeof(char) vaut toujours 1, mais pour un autre type, ça ne marcherait pas.
Cdlt,
5 juil. 2011 à 13:49
Modifié par Hxyp le 5/07/2011 à 20:18
là avec un tableau de double et en utilisant à l'arrache un int pour calculer l'adresse :
Et là avec des short int :
Un autre avec une struct :
Modifié par fiddy le 5/07/2011 à 21:06
Dans ta nouvelle version (voir ci-dessous), tu sauvegardes l'adresse du tableau tab dans une variable unsigned int. Bien sûr qu'après, il faut que tu incrémentes de sizeof(double) pour passer à la case d'après.
Maintenant, je remets ton code initial :
Là tu incrémentes directement l'adresse du tableau. C'est très différent... C'est dans ce cas que je t'ai fait ma remarque : tab++; car si c'est sur un double, ça ne marchera pas.
Cdlt,
5 juil. 2011 à 21:15
enfin le code que j'ai donné ensuite détaille un peu mieux ce que je voulais dire.
L'erreur a été d'avoir incrémenté sur le pointeur directement, enfin je pense qu'on a tous compris la différence