IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Les tableaux dynamiques en C


Sujet :

C

  1. #1
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meuse (Lorraine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 317
    Par défaut Les tableaux dynamiques en C
    bonsoir,
    j'ai une question s'il vous plait: est-ce que je peux créer un tableau dynamique en C.c'est à dire créer un tableau avec une taille varie au cours du programme??
    merci pour votre aide.

  2. #2
    Invité
    Invité(e)

  3. #3
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Citation Envoyé par mido1951 Voir le message
    bonsoir,
    j'ai une question s'il vous plait: est-ce que je peux créer un tableau dynamique en C.c'est à dire créer un tableau avec une taille varie au cours du programme??
    merci pour votre aide.
    Oui, bien sur, c'est possible.

    Par contre, ce n'est pas "trivial", et un minimum de connaissances du langage sont necessaires. Je te conseille donc la lecture de tutoriels sur le C
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    En bref résumé.
    il n'y a pas de comportement réellement automatique en C.

    Pour le besoin d'un ensemble cohérent de valeurs (un tableau), tu as plusieurs situations, chacune avec sa solution.
    1. Tu connais une taille maximale de l'ensemble, et elle sera atteinte au moins une fois.
    2. L'ensemble ne change pas souvent de taille, mais cette taille est arbitraire.
    3. La taille de l'ensemble change fréquemment, et la taille connait de grande variation


    1) Taille bornée, mais variable.
    Un tableau fixe, une constante de taille maximale, et une taille actuelle suffisent.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const int TailleMax = 17;
    int taille = 0;
    int tableau[TailleMax];
    2) Une taille arbitraire, mais constante (par morceaux, comme dirait les matheux…).
    Ici, un pointeur et une taille devrait correspondre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int* tableau = NULL;//ou 0 selon ta manière de traiter ce sujet polémique
    int taille = 0;
    il faudra alors utiliser malloc, free et realloc pour respectivement créer le tableau, le supprimer et le retailler.

    3) L'ajout ou la suppression du tableau sont une opération fréquente.
    La, il te faut tout autre chose, un tableau ne convient pas vraiment.
    Il te faut une liste chainée (doublement ou pas)
    le modèle général est le suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    typedef struct intChainon {
        int valeur;
        struct intChainon * suivant;
        struct intChainon * précédent;//si le doublement chainé.
    } intChainon_t;
     
    //si doublement chainé, tu peux avoir aussi:
    struct intChaine{
    struct intChainon * premier;
    struct intChainon * dernier;
    }
    Il convient alors de créer des fonctions pour:
    • savoir si la liste est vide
    • vider une liste (généralement, vider(intChainon**liste) { while(!estVide(*liste)) supprimerPremier(*liste); *liste=null;})
    • ajouter un élément au début (malloc)
    • ajouter un élément en fin (malloc)
    • supprimer le premier élément (free)
    • supprimer le dernier élément (free)


    Il y a d'autres possibilités, mais celles-ci sont les plus courantes.
    En général, les autres solutions font appels à ces concepts.

  5. #5
    Membre chevronné Avatar de I_believe_in_code
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 219
    Par défaut
    Dans une série de vidéos de cours, j'ai montré une manière de créer un type de donnée "tableau redimensionnable". Ce type de tableau a une taille allouée (qui peut être augmentée en cas de besoin) et une taille utilisée (inférieure ou égale à la taille allouée, selon la quantité de données effectivement stockées).

    Dès qu'on souhaite écrire une donnée dans une case située au-delà de la taille allouée, celle-ci est agrandie suffisamment pour que l'opération soit possible (et même deux fois plus).

    Les deux vidéos suivantes parlent exactement de cela :





    Trois remarques :

    1- il s'agit d'une implémentation naïve, c'est à dire ni la plus performante ni la plus joliment codée. La raison est que c'est un cours réservé à des débutants et que je n'ai utilisé que des choses que nous avions déjà vues dans les cours précédents.

    2- les vidéos montrent comment faire cela sur des tableaux d'int. Bien sûr la méthode est généralisable, et, idéalement, il vaudrait mieux des tableaux de void* plus réutilisables (mais c'est un cours pour les débutants, je le répète)

    3- si ton bagage sur le langage C, voire sur la programmation en général est faible, tu risques aussi d'avoir besoin de suivre certains des cours précédents.

    En particulier :

    - sur les pointeurs :


    - sur l'allocation dynamique :


    - sur les struct :

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Par défaut
    Il reste encore une dernière solution par rapport à ce qu'a dis leternel : un arbre binaire de recherche. Mais ça demande bien plus de travail, et cela dépend de ce que tu veux faire de ton tableau

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct _abin {
      [type] value; // Où type désigne... le type !
      struct _abin* sag; // Le sous arbre gauche.
      struct _abin* sad // Le sous arbre droit.
    } *abin;

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Wow, c'est un cours très intéressant.

    Ce qui est regrettable, c'est qu'il y a des informations voisines qui ne peuvent pas vraiment être abordées dans un tel cours (elles n'apporteraient que confusion), notamment le problème du nombre d'or qui empêche de réutiliser la mémoire libérée quand on double la longueur du tableau à chaque fois.

    vPersonnellement, j'utilise racine de 2, mais en trichant un peu pour être sur que deux agrandissements multiplient bien par 2 et non pas 1.999...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Merci!
    Je connaissais le fait que 1,5 soit un bon ratio, mais pas la raison.

  9. #9
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    En fait, on a intérêt à avoir un facteur de croissance inférieur au nombre d'or si on veut que le mécanisme de récupération évoqué dans le post signalé par Médinoc puisse fonctionner :

    On cherche à allouer successivement 1, puis k puis k^2, k^3,...k^n (k>1)
    Si on veut que le critère fonctionne pour l'allocation k^n, (n>=3) il faut avoir
           k^n <= Sn = 1+k+k^2+..k^(n-2)
    soit   k^n <= (k^(n-1)-1)/(k-1)
           k^(n+1) - k^n - k^(n-1)+ 1 <=0
    ou     k^2 - k -1 + 1/(k^(n-1))<=0
    
    Soit n0, la plus petite valeur de n (si elle existe), qui, pour un k donné, satisfait ce critère. Alors, il sera également satisfait pour n>n0
    Si on admet vouloir cette condition pour n0 très grand, k^(n0-1)>>1 , k tend vers le nombre d'or, racine de k^2-k-1 =0. Mais si on veut que ce critère soit satisfait pour des valeurs petites de n0, il faut diminuer k.
    Ainsi,
    n0     3        4       5       6      10    ... 
    k<=  1.3247   1.465   1.534   1.57    1.61         1.618
    Par exemple,
    k = 1.5
    n =    0     1        2       3        4        5
    k^n    1    1.5      2.25   3.375    5.0625   7.5938
    Sn     -     -        -      2.5      4.75     8.125
    k = 1.414
    n =    0     1        2       3         4        5
    k^n    1   1.414      2     2.818       4      5.6569                                   
    Sn     -     -        -     2.414     4.414    7.2426
    k = 1.3247
    n =    0     1        2       3        4     
    k^n    1   1.3247  1.7548   2.3246   3.0794
    Sn     -     -        -     2.3247   4.0795

Discussions similaires

  1. [Langage] Probleme avec les tableaux dynamiques
    Par wawa84 dans le forum Langage
    Réponses: 7
    Dernier message: 19/11/2008, 17h18
  2. Les types composites et les tableaux dynamiques
    Par pierre_luvier dans le forum SQL
    Réponses: 4
    Dernier message: 03/11/2007, 11h33
  3. Panique avec les Tableaux dynamiques
    Par Swiper dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 27/06/2007, 15h52
  4. Réponses: 12
    Dernier message: 17/12/2006, 11h46
  5. Article sur les tableaux dynamiques
    Par Eric Sigoillot dans le forum Langage
    Réponses: 2
    Dernier message: 16/04/2004, 22h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo