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 :

C et les tableaux [Débutant(e)]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Mysti¢
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 155
    Par défaut C et les tableaux
    Bonjour, je suis un débutant en C et j'ai quelques questions à propos des tableaux. (de Python au C ça change pas mal :/)

    Tout d'abord je voulais savoir si on est obligé de définir la taille d'un tableau (ou allouer un espace) quand on le cree, ou est ce que c'est possible de faire par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int tab[0]; /* ou même d'une autre manière */
    et ensuite d'ajouter des entrée à l'aide d'une fonction (qui donc modifierai la taille du tableau automatiquement)
    Et seconde question, est ce que c'est possible de lister toutes les entrées d'un tableau ou de recupérer sa taille (nombre d'entrées) dans une variable.

    J'ai déjà lu le terme "tableau dynamique" mais je ne sais pas si c'est approprié pour ce que je souhaite faire.
    Si quelqu'un a de la documentation dessus ...
    J'ai parcouru la rubrique "tableaux" de la FAQ C mais ça ne m'a pas trop aidé.

    Pour finir un exemple concret:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
    /* Imaginons que je veuille stocker tous les diviseurs d'un nombre dont le reste est égal à 0 dans un tableau */
    main() {
      int a;
      int i;
      a = 88;
      for (i = a; i > 0; i--)
        if ((a % i) == 0) {
          printf("%d \n",i);   /* Ici à la place d'afficher la valeur de la variable a, la stocker dans un tableau */
        }
    }
    Merci.

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mysti¢
    Tout d'abord je voulais savoir si on est obligé de définir la taille d'un tableau (ou allouer un espace) quand on le cree, ou est ce que c'est possible de faire par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int tab[0]; /* ou même d'une autre manière */
    et ensuite d'ajouter des entrée à l'aide d'une fonction (qui donc modifierai la taille du tableau automatiquement)
    De façon native, il n'y a pas grand chose d'automatique en C, et certainement pas les tableaux. Il faut donc définir une taille, soit au codage (taille fixe), soit à l'exécution (mémoire dynamique : malloc() / free()).
    Et seconde question, est ce que c'est possible de lister toutes les entrées d'un tableau ou de recupérer sa taille (nombre d'entrées) dans une variable.
    Oui. En général, on utilise une boucle for. Il faut bien sûr connaitre (ou déterminer) le nombre d'éléments du tableau. Rappelons que les indices valides d'un tableau de N éléments vont de 0 à N-1.
    Pour finir un exemple concret:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
    /* Imaginons que je veuille stocker tous les diviseurs d'un nombre dont le reste est égal à 0 dans un tableau */
    main() {
      int a;
      int i;
      a = 88;
      for (i = a; i > 0; i--)
        if ((a % i) == 0) {
          printf("%d \n",i);   /* Ici à la place d'afficher la valeur de la variable a, la stocker dans un tableau */
        }
    }
    Une chose est certaine, c'est que la taille du tableau ne peut excéder 88 éléments. Il suffit donc de définir un tableau de cette taille et de le remplir à la demande à l'aide d'un incide séparé de l'indice de la boucle principal.
    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
    22
    23
    24
    25
    26
    27
    28
    #include <stdlib.h>
    #include <stdio.h>
    /* Imaginons que je veuille stocker tous les diviseurs d'un nombre dont
    le reste est égal à 0 dans un tableau */
    int main (void)
    {
       enum
       { A = 88 };
       int i;
       int tab[A];
       int j = 0;
    
       for (i = A; i > 0; i--)
          if ((A % i) == 0)
          {
             /* Ici à la place d'afficher la valeur de la variable a,
                la stocker dans un tableau */
             tab[j] = i;
             j++;
          }
    
       for (i = 0; i < j; i++)
       {
          printf ("%d \n", tab[i]);
       }
    
    }
    

  3. #3
    Membre confirmé Avatar de Mysti¢
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 155
    Par défaut
    Ok, merci pour cette explication claire bien que logique.
    Ensuite créer un tableau de n éléments alors que dans certains cas il n'en contiendra qu'un j'y aurai pas pensé parce que si le nombre est très grand
    ex: 8 546 218 (bien qu'on m'ai dit que le C est rapide), on le sentirai à l'exécution non?
    D'un point de vue optimisation, plutôt bof. Mais si c'est l'unique solution, je ferai avec.
    Enfin pour l'instant c'est juste dans le but d'apprendre et comme ça me permet de continuer, problème résolu

    Merci pour le petit bout de code

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Il existe des alternatives aux tableaux de taille fixe, mais cela nécessite de maîtriser un peu les pointeurs

    Les deux alternatives sont
    • La gestion d'un tableau dont la taille évolue sur demande, d'un coefficient multiplicateur pour éviter d'avoir à réallouer la mémoire en permanence
    • La gestion sous forme d'une structure dynamique (pile, file, liste...) dont chaque élément est créé de manière dynamique


    La première solution nécessite d'avoir deux variables: le nombre d'éléments contenus dans le tableau et le nombre maximal d'éléments qu'il peut contenir, et pourrait se présenter sous une forme proche de
    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
    22
    23
    24
    25
     
    int maxelem= 10; /* à la base, on prévoit 10 elements */
    int numelem=0; /* au début, il n'y a aucun élément dans le tableau */
    int tab*=malloc(maxelem*sizeof(int));/* allocation d'un tableau de départ */
    /* sans doute toute une gestion avant d'arriver à la boucle qui 
     * effectue la vérification ;)
     */
    for(cpt=0;cpt<nb;cpt++)/* on teste toutes les valeurs comprises entre cpt
                                  * et nb */
    {
        if(nb%cpt==0) /* si le modulo de nb par cpt vaut 0, on a un multiple de
                         * cpt */
        {
             /* on vérifie si on a la place pour rajouter un élément */
             if(numelem==maxelem)
             {
                 /* on augmente la taille du tableau en deux temps:*/
                 maxelem*=1.5;
                 tab=realloc(tab,maxelem*sizeof(int));
             }
             /* on place cpt dans le tableau */
             tab[numelem]=cpt;
             ++numelem;
        }
    }
    (NOTA: une vérification de la réussite des allocations serait de bon aloi )

    La deuxième solution nécessite le recours à une structure du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct s_elem
    {
        int val;
        struct s_elem* next;
    } elem;
    On peut créer une petite fonction qui permet de compter les élément
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int count(elem* tete)
    {
        int cpt=0;
        while(tete!=NULL)
        {
            tete=tete->next;
            ++cpt;
        }
        return cpt;
    }
    On peut créer une fonction qui se charge d'ajouter un élément dans la liste
    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
    22
    23
    24
    25
    26
    27
    28
    elem* AddElem(elem* tete, int val)
    {
        /* cas particulier: c'est le premier élement de la liste */
        if(tete==NULL)
        {
             /* allocation de la mémoire pour le premier élément */
             tete=malloc(sizeof(*tete));
             /* on fournit les valeurs */
             tete->val=val;
             tete->next=NULL;
        }
        else
        {
            /* sinon, on cherche le dernier élément de la liste*/
            elem* temp=tete;
            while(temp->next!=NULL)
                temp=temp->next
            /* on alloue la mémoire pour un nouvel élément */
            elem* toadd=malloc(sizeof(*toadd));
            /* auquel on fournit les valeurs */
            toadd->val=val;
            toadd->next=NULL;
            /* et qu'on ajoute en fin de liste */
            temp->next=toadd;
        }
        /* on fini en renvoyant le premier élément de la liste  */
        return tete;
    }
    (NOTA: ici aussi, la vérification de l'allocation correcte de la mémoire est de bon aloi )

    Dans la fonction principale, on maintient "simplement" un pointeur sur le premier élément de la liste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int main()
    {
        elem* debut=NULL;/* à la base, la liste est vide */
        /* toute la gestion qui est utile avant */
        /* exemple d'ajout d'un élément à la liste */
        tete=AddElem(debut,laval);
        /* exemple d'utilisation de count */
        int combien=Count(debut);
    }
    Nota: il faudra aussi prévoir une fonction qui libérera correctement la mémoire de tous les éléments
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre confirmé Avatar de Mysti¢
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 155
    Par défaut
    ça parait un assez complexe pour un débutant, mais avec les commentaires un peu moins. je vais voir ce que je peux faire avec ça.
    Merci.
    (* sinon les pointeurs c'est à mon prochain chapitre ^^)

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Mysti¢
    ça parait un assez complexe pour un débutant, mais avec les commentaires un peu moins. je vais voir ce que je peux faire avec ça.
    Merci.
    Je te jure pourtant que j'ai essayé de le faire le plus simple possible...

    (* sinon les pointeurs c'est à mon prochain chapitre ^^)
    Quand tu te sera un peu frotté au pointeurs et à l'allocation dynamique de la mémoire, tu verra que ça a beau être un gros morceau, ce n'est malgré tout pas *si* complexe que cela...

    Et mes exemples te deviendront limpides... D'ici là, accroche toi
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Mais pourquoi ... Avec IE les tableaux sont décentrés ?
    Par nebule dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 26/11/2004, 10h04
  2. Article sur les tableaux dynamiques
    Par Eric Sigoillot dans le forum Langage
    Réponses: 2
    Dernier message: 16/04/2004, 22h00
  3. Réponses: 14
    Dernier message: 01/09/2003, 22h46
  4. Les tableaux en PL/SQL
    Par GRUMLY dans le forum PL/SQL
    Réponses: 5
    Dernier message: 12/08/2002, 18h10

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