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 :

Déclaration tableau de chaine de caractères


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 28
    Par défaut Déclaration tableau de chaine de caractères
    Bonjour,

    Je voudrai vous demander des éclaircissements pourquoi un tableau de chaine de caractères (=matrice) char string[][50] fonctinne (avec l'utilisation directe d'une constante) en revanche char string[][M] ne fonctionne pas dans le cas ou on a la déclaration const int M=50;

    Par avance merci.

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 035
    Par défaut
    Bonjour,

    À première vue, cette déclaration semble équivalente à la première. Cependant, en C, bien que M soit déclaré comme une constante, il est considéré comme une constante "variable" au moment de la compilation. Cela signifie que sa valeur n'est pas intégrée dans le code à la compilation comme une constante littérale (comme le serait 50 directement dans le code). Par conséquent, utiliser M de cette manière dans la définition d'une taille de tableau n'est pas permis par la norme C pour la déclaration de tableaux à taille fixe au niveau global ou dans le contexte d'une fonction où la taille doit être connue au moment de la compilation.

    Le langage C a été conçu pour être proche de la machine et très efficace, ce qui implique que certaines décisions doivent être prises au moment de la compilation. La taille des tableaux à allocation statique en fait partie, car elle détermine comment l'espace mémoire est alloué et comment les accès à cet espace sont calculés.

    Les solutions possibles :

    Utiliser des macros : Contrairement aux variables const, les macros sont remplacées par leur valeur au moment de la précompilation, ce qui les rend utilisables pour déclarer la taille d'un tableau.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define M 50
    char string[][M];
    Allocation dynamique : Si vous avez besoin d'une taille variable pour vos tableaux, envisagez d'utiliser l'allocation dynamique avec malloc ou calloc. Cela vous permet d'utiliser des variables pour définir la taille du tableau, mais cela implique aussi que vous devrez gérer manuellement la mémoire (allocation et libération).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const int M = 50;
    char (*string)[M] = malloc(N * sizeof(*string));
    Où N est le nombre de chaînes que vous souhaitez allouer. Cette méthode offre plus de flexibilité mais nécessite une gestion attentive de la mémoire pour éviter les fuites.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 28
    Par défaut
    Re-bonjour,

    Merci beaucoup pour la réponse, c'est claire et nette.

    Juste un petit point l'écriture (cas allocation dynamique) si j'ai bien compris : char (*string)[M] = char* string[M] => c.à.d (*string) est un pointeur sur un tableau de char de taille M.

    En revanche quand j'essaye de compiler : char (*string)[M] = malloc(N * sizeof(*string));

    J'obtiens le message suivant : [Error] invalide conversion from 'void' to 'char(*)[50]' .

    Donc, il doit y avoir une conversion de type (cast) que je n'aarive pas à résoudre.

    Merci.

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 035
    Par défaut
    Vous compilez avec ?

    Vous souhaitez allouer dynamiquement un tableau de N éléments, où chaque élément est un tableau de M caractères. Le type de votre pointeur string est donc un pointeur sur un tableau de M caractères, c'est-à-dire char (*)[M].
    Essayez cette ligne avec le cast :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char (*string)[M] = (char (*)[M])malloc(N * sizeof(*string));
    Le standard C permet l'affectation d'un pointeur void* à n'importe quel autre type de pointeur sans cast. Cependant, certains compilateurs ou certaines configurations de compilateurs (par exemple, avec des avertissements stricts activés) peuvent émettre un avertissement ou une erreur si le cast est omis.

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    La ligne char (*string)[M] = malloc(N * sizeof(*string)); est valide en C et doit compiler.
    Par contre un compilateur C++, lui la refuserait en indiquant qu'il manque un cast. Es-tu sûr de compiler en C?
    Si la ligne suivante char (*string)[M] = static_cast<char(*)[M]>(malloc(N * sizeof(*string))); est acceptée, c'est du C++!!

  6. #6
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 748
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 748
    Par défaut
    Citation Envoyé par hogar Voir le message
    En revanche quand j'essaye de compiler : char (*string)[M] = malloc(N * sizeof(*string));
    Reste à la bonne vieille syntaxe

    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
    29
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define G_STR_LENGTH 50 // global
     
    #define G_ARRAY_GET_ELT(ARRAY, X) (ARRAY + ((G_STR_LENGTH + 1) * X))
     
    // ...
     
        size_t nb_str = 30;
     
        char* tab_strs = malloc(nb_str * ((G_STR_LENGTH + 1) /* * sizeof(char) */)); // +1 with '\0' and sizeof(char) is always 1
     
        if (tab_strs != NULL) {
            strcpy(tab_strs,                     "To be");
            strcpy(G_ARRAY_GET_ELT(tab_strs, 1), "or not");
            strcpy(G_ARRAY_GET_ELT(tab_strs, 2), "to be");
     
            printf("str1: %s, str2: %s, str3: %s\n", tab_strs, G_ARRAY_GET_ELT(tab_strs, 1), G_ARRAY_GET_ELT(tab_strs, 2));
     
            char* tmp_tab[30] = {tab_strs, G_ARRAY_GET_ELT(tab_strs, 1), G_ARRAY_GET_ELT(tab_strs, 2)};
     
            printf("str1: %s, str2: %s, str3: %s\n", tmp_tab[0], tmp_tab[1], tmp_tab[2]);
     
            free(tab_strs); // don't forget free(tab_strs)
        } else {
    //      Allocation failed
        }
    Édit: ici tu alloues 1 gros bloc. Mais tu peux faire 1 tableau de pointeurs char* tab_strs[30] et allouer chaque chaîne de caractères séparément (par contre niveau gestion mémoire c'est long, et si tu utilises 1 variable pour définir la taille de ton tableau, c'est 1 VLA)

    documentation de stdlib.h, la partie "Dynamic memory management" avec essentiellement malloc et realloc (<- cstdlib, c'est la bibliothèque C en C++, on retire l'extension et on préfixe 1 c: cXXX)

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 31/05/2007, 15h10
  2. [C] tableau de chaines de caractères
    Par kitsune dans le forum C
    Réponses: 18
    Dernier message: 01/04/2006, 18h18
  3. tableau de chaine
    Par florantine dans le forum C++
    Réponses: 1
    Dernier message: 18/01/2006, 15h17
  4. Tableau de chaînes de caractères
    Par mac1 dans le forum Langage
    Réponses: 3
    Dernier message: 15/01/2006, 13h18
  5. Réponses: 11
    Dernier message: 31/12/2005, 13h00

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