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 | pointeurs | fonctions | structures


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Agronome
    Inscrit en
    septembre 2018
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Agronome
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : septembre 2018
    Messages : 97
    Points : 60
    Points
    60
    Par défaut C | pointeurs | fonctions | structures
    Bonjour, j'ai déjà vu les pointeurs mais là je m'y perd malgré les schémas ! Je vous met en gras la partie qui me pose des difficultés.

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #include <stdio.h>
    #include <stdlib.h>
    
    struct PADDOCK { 
      unsigned int paddock_size ; 
      char const *someString; 
      float someSample; 
    }paddock_data; 
    
    void export_row(int number_of_data,char const *fileName, int data_array){
            for (int i = 0 ; i < number_of_data ; i++)
        {
            FILE *fic = fopen(fileName, "a"); 
            if (fic == NULL)
            {
                exit(1);
            }      
            fprintf(fic, "%d ;", data_array); 
            //printf("P%d : %d\n", i+1, paddock_data[i].paddock_size);
            fclose(fic); 
        }
    }
    
    int main(int argc, char** argv)
    {
        printf("je suis un programme test sur les structures.\n");
        struct PADDOCK *paddock_data = NULL;
        unsigned int number_of_paddock = 0;
        unsigned int i;
    
        printf("\t1.- Combien de parcelles ? ");
        scanf("%d", &number_of_paddock);
    
        if(number_of_paddock > 0)
        {
            paddock_data = malloc(sizeof(int)*number_of_paddock);
    
            /* si l`alloc a echoue, on quitte le programme. */
    	    if(paddock_data == NULL)
    		    exit(1); 
                
            /* Premier paramètre : la taille des parcelles */
            for (i = 0 ; i < number_of_paddock ; i++)
            {
                printf("\tQuel est la taille de parcelle %d ? ", i + 1);
                scanf("%d", &paddock_data[i].paddock_size);
                //write_paddock_to_file(1,,"Data.csv");
            }
            export_row(number_of_paddock,"Data.csv",paddock_data[i].paddock_size);
    
        }
        return 0;
    }
    Merci d'avance,

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    6 824
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 6 824
    Points : 31 261
    Points
    31 261
    Billets dans le blog
    4
    Par défaut
    Et la difficulté est ?
    Nommer une variable array quand il s'agit d'une valeur unique ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre éprouvé Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2011
    Messages
    456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : mai 2011
    Messages : 456
    Points : 1 115
    Points
    1 115
    Par défaut
    Hello,

    C'est quoi ce machin: dans un boucle for(), tu ouvres et fermes ton fichier ?

  4. #4
    Nouveau membre du Club Avatar de ethan007
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2015
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : mars 2015
    Messages : 20
    Points : 31
    Points
    31
    Par défaut
    Citation Envoyé par Magnum8760 Voir le message
    Bonjour, j'ai déjà vu les pointeurs mais là je m'y perd malgré les schémas ! Je vous met en gras la partie qui me pose des difficultés.

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #include <stdio.h>
    #include <stdlib.h>
    
    struct PADDOCK { 
      unsigned int paddock_size ; 
      char const *someString; 
      float someSample; 
    }paddock_data; 
    
    void export_row(int number_of_data,char const *fileName, int data_array){
            for (int i = 0 ; i < number_of_data ; i++)
        {
            FILE *fic = fopen(fileName, "a"); 
            if (fic == NULL)
            {
                exit(1);
            }      
            fprintf(fic, "%d ;", data_array); 
            //printf("P%d : %d\n", i+1, paddock_data[i].paddock_size);
            fclose(fic); 
        }
    }
    
    int main(int argc, char** argv)
    {
        printf("je suis un programme test sur les structures.\n");
        struct PADDOCK *paddock_data = NULL;
        unsigned int number_of_paddock = 0;
        unsigned int i;
    
        printf("\t1.- Combien de parcelles ? ");
        scanf("%d", &number_of_paddock);
    
        if(number_of_paddock > 0)
        {
            paddock_data = malloc(sizeof(int)*number_of_paddock);
    
            /* si l`alloc a echoue, on quitte le programme. */
    	    if(paddock_data == NULL)
    		    exit(1); 
                
            /* Premier paramètre : la taille des parcelles */
            for (i = 0 ; i < number_of_paddock ; i++)
            {
                printf("\tQuel est la taille de parcelle %d ? ", i + 1);
                scanf("%d", &paddock_data[i].paddock_size);
                //write_paddock_to_file(1,,"Data.csv");
            }
            export_row(number_of_paddock,"Data.csv",paddock_data[i].paddock_size);
    
        }
        return 0;
    }
    Merci d'avance,
    • la synthaxe pour interdire la modification du paramètre est:
      Code c : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      void print_only(const char *valeur_fixe){
        printf("Value is %s", valeur_fixe);
      }
    • Voici une bonne façon d'écrire les structures:
      Code C : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
       
      typedef struct Paddock{ 
        unsigned int paddock_size ; 
        const char *someString; 
        float someSample; 
      }Paddock; 
       
      Paddock mon_paddock1;
      Paddock mon_paddock2;
      //....
    • La majorité des compilateurs exigent de faire un cast sur le type de retour de la fonction malloc() (le type de retour par défaut est void*), de plus tu multiplie number_of_paddock par la taille d'un int au lieu de multiplier par la taille d'un Paddock!! tu devrait écrire ceci:
      Code c : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
       
      paddock_data = (Paddock*)malloc(sizeof(Paddock) * number_of_paddock);
      //La structure Paddock a été réecirtte à ma façon
    • A la ligne 49 tu accèdes à une case qui n'existe pas!! (le compteur i dépasse le nombre de Paddock que l'utilisateur avait entré...et même si tu fais un i-1 seul le dernier paddock_size sera envoyé à la fonction export_row() car tu n'est pas dans la boucle.
    • Ligne 13: Je ne vois pas trop l'interêt à ouvrir un même fichier dans une boucle..


    J'espère t'avoir aidé, à bientôt.

  5. #5
    Membre éprouvé Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2011
    Messages
    456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : mai 2011
    Messages : 456
    Points : 1 115
    Points
    1 115
    Par défaut
    Citation Envoyé par ethan007 Voir le message
    La majorité des compilateurs exigent de faire un cast sur le type de retour de la fonction malloc()
    Non, jamais en C. En C, on ne caste pas le retour de malloc()

  6. #6
    Nouveau membre du Club Avatar de ethan007
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2015
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : mars 2015
    Messages : 20
    Points : 31
    Points
    31
    Par défaut
    Citation Envoyé par edgarjacobs Voir le message
    Non, jamais en C. En C, on ne caste pas le retour de malloc()
    Dire
    Citation Envoyé par edgarjacobs Voir le message
    jamais
    c'est comme si c'est interdit de le faire...
    Avantages du cast
    • L'inclusion du cast peut permettre à un programme ou une fonction C de compiler en C ++.
    • Le cast autorise les versions antérieures à 1989 de malloc ayant à l'origine renvoyé un caractère *.
    • Caster peut aider à identifier les incohérences dans le dimensionnement des types si le type de pointeur de destination change, en particulier si le pointeur est déclaré loin de l'appel malloc () (bien que les compilateurs modernes et les analyseurs statiques puissent avertir de ce comportement sans requérir le transfert).

    Inconvénients

    le cast est redondant(ANSI C).

    L'ajout du cast peut masquer l'échec d'inclure l'en-tête stdlib.h, dans lequel le prototype de malloc se trouve, la norme exige que le compilateur C suppose que malloc renvoie un int. S'il n'y a pas de conversion, un avertissement est émis lorsque cet entier est affecté au pointeur. Cependant, avec le casting, cet avertissement n'est pas produit. Sur certaines architectures et certains modèles de données (tels que LP64 sur les systèmes 64 bits, où longs et les pointeurs sont 64 bits et int est 32 bits), cette erreur peut en réalité entraîner un comportement indéfini, car le malloc déclaré implicitement renvoie un message de 32bits alors que la fonction réellement définie renvoie une valeur de 64 bits. Selon les conventions d’appel et la structure de la mémoire, cela peut entraîner un désordre de la pile. Surtout les compilateurs modernes, car ils produisent uniformément des avertissements indiquant qu'une fonction non déclarée a été utilisée. Par conséquent, un avertissement apparaîtra.
    Si le type du pointeur est modifié lors de sa déclaration, il peut également être nécessaire de modifier toutes les lignes où malloc est appelé et converti.

    DONC
    Bien que malloc sans casting soit la méthode préférée et que la plupart des programmeurs expérimentés le choisissent, chacun utilise celui qui le convient le mieux

    PS: Wikipedia

  7. #7
    Membre éprouvé Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2011
    Messages
    456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : mai 2011
    Messages : 456
    Points : 1 115
    Points
    1 115
    Par défaut
    Citation Envoyé par ethan007
    [b
    La majorité des compilateurs exigent de faire un cast sur le type de retour de la fonction malloc()
    Le "jamais" porte la-dessus, pas sur la casting, débat sans fin que je n'ai pas l'intention d'alimenter.

  8. #8
    Expert éminent
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    mai 2010
    Messages
    3 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : mai 2010
    Messages : 3 089
    Points : 9 686
    Points
    9 686
    Par défaut
    Citation Envoyé par ethan007 Voir le message
    Avantages du cast
    [list][*]L'inclusion du cast peut permettre à un programme ou une fonction C de compiler en C ++.
    [*]Le cast autorise les versions antérieures à 1989 de malloc ayant à l'origine renvoyé un caractère *.
    1) Pas certain que ça soit un avantage , n'utilise jamais un malloc en C++ , si tu ne veux pas te faire brûler sur la place public
    2) Je déconseille vivement d'utiliser un compilateur qui ne fait que de l'ANSI C , et je conseille au moins le C99.
    (Après dans les faits , je doute qu'il y'ai un avantage d'utiliser un vieux compilateur , même pour une plateforme exotique GCC a pas mal de chance deviser cette plateforme).

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    9 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 9 633
    Points : 26 312
    Points
    26 312
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Magnum8760 Voir le message
    Bonjour, j'ai déjà vu les pointeurs mais là je m'y perd malgré les schémas ! Je vous met en gras la partie qui me pose des difficultés.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void export_row(int number_of_data,char const *fileName, int data_array){
    ...
    }
    
    int main(int argc, char** argv) {
            export_row(number_of_paddock,"Data.csv",paddock_data[i].paddock_size);
    }
    Bonjour

    Un pointeur c'est simplement une variable contenant une adresse. Ni plus, ni moins.
    Donc dans les types disponibles en C, tu as le (par exemple) float qui contient un nombre représenant une valeur en virgule flottante... et le pointeur qui contient un nombre représentant une adresse (sous-entendu "adresse d'une zone mémoire").

    Concrètement ici ta fonction va recevoir un paramètre. Ce paramètre étant une adresse, il faudra le ranger dans un pointeur. Cette adresse étant celle d'un caractère il faudra la ranger dans un pointeur sur caractère. Et ce pointeur étant une variable il lui faut un nom donc le développeur l'a appelé "fileName".

    Lors de l'appel, la chaine "Data.csv" est convertie en adresse (l'adresse de début de la zone contenant ladite chaine) donc c'est cette adresse qui part réellement dans la fonction appelée.


    Citation Envoyé par ethan007 Voir le message
    Voici une bonne façon d'écrire les structures:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct Paddock{ 
      unsigned int paddock_size ; 
      const char *someString; 
      float someSample; 
    }Paddock;
    Voici la bonne façon d'écrire les structures
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct s_Paddock{ 
      unsigned int paddock_size ; 
      const char *someString; 
      float someSample; 
    } t_Paddock;

    Et si la structure devient un type (comme ici) et n'est pas réutilisée pendant sa création (ce qui est le cas de structures qui pointent vers elles-même comme les éléments d'une liste) alors son nom "s_Paddock" devient inutile.

    Citation Envoyé par edgarjacobs Voir le message
    Le "jamais" porte la-dessus, pas sur le casting...
    Tu aurais écrit (par exemple) "non, aucun compilateur C n'exige de cast de malloc" ça aurait été immédiatement plus clair...

    Citation Envoyé par ethan007 Voir le message
    Bien que malloc sans casting soit la méthode préférée et que la plupart des programmeurs expérimentés le choisissent, chacun utilise celui qui le convient le mieux
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  10. #10
    Expert confirmé
    Inscrit en
    mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par ethan007 Voir le message
    Avantages du cast
    • L'inclusion du cast peut permettre à un programme ou une fonction C de compiler en C ++.
    • Le cast autorise les versions antérieures à 1989 de malloc ayant à l'origine renvoyé un caractère *.
    • Caster peut aider à identifier les incohérences dans le dimensionnement des types si le type de pointeur de destination change, en particulier si le pointeur est déclaré loin de l'appel malloc () (bien que les compilateurs modernes et les analyseurs statiques puissent avertir de ce comportement sans requérir le transfert).
    Les deux premiers cas d'usage sont hautement situationnels. Ici, on compile en C11 avec des compilateurs C qui respectent la norme.

    Le troisième est la solution d'un bien hypothétique problème XY. Si l'on ne veut pas repasser sur les appels d'allocation, il suffit de prendre en charge le type du pointeur de destination au moment de celle-ci : p = malloc(n * sizeof *p); , par exemple.

    Il reste plus grand chose en faveur du cast.

    Évite d'embrouiller les débutants : on ne cast pas la valeur de retour des fonctions d'allocation, point barre.

  11. #11
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : juin 2002
    Messages : 2 165
    Points : 4 605
    Points
    4 605
    Par défaut
    Deux petites remarques :

    Citation Envoyé par ethan007 Voir le message
    la synthaxe pour interdire la modification du paramètre est:
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void print_only(const char *valeur_fixe){
      printf("Value is %s", valeur_fixe);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char const* valeur_fixe
    est correct et équivalent. Et présente l'avantage de la cohérence avec l'emplacement des autres const (p.ex. sur le pointeur) puisque const s'applique à ce qui le précède et ce n'est que lorsqu'il n'est précédé de rien qu'il s'applique à ce qui le suit.
    Mais généralement, on trouve effectivement plus facilement le const en début.

    Citation Envoyé par ethan007 Voir le message
    La majorité des compilateurs exigent de faire un cast sur le type de retour de la fonction malloc() (le type de retour par défaut est void*), de plus tu multiplie number_of_paddock par la taille d'un int au lieu de multiplier par la taille d'un Paddock!! tu devrait écrire ceci:
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    paddock_data = (Paddock*)malloc(sizeof(Paddock) * number_of_paddock);
    //La structure Paddock a été réecirtte à ma façon
    Indépendamment du cast, qui n'est effectivement pas exigé en C mais seulement en C++ et qui n'est généralement pas considéré comme une bonne pratique, j'aurais tendance à privilégier l'usage de la variable plutôt que de son type pour la détermination de la taille, ce qui rend le code plus simple à faire évoluer, donc :

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    Paddock* paddock_data = malloc(sizeof(*paddock_data) * number_of_paddock);

Discussions similaires

  1. Probléme structure pointeur fonction
    Par babouoles dans le forum Bibliothèque standard
    Réponses: 9
    Dernier message: 14/05/2008, 18h34
  2. Réponses: 6
    Dernier message: 29/04/2008, 18h24
  3. paramètres fonction structures pointeurs
    Par tom31 dans le forum Débuter
    Réponses: 2
    Dernier message: 12/01/2008, 19h22
  4. Fonction, structure, pointeurs et scanf
    Par exhortae dans le forum C
    Réponses: 13
    Dernier message: 27/02/2007, 18h31
  5. Réponses: 7
    Dernier message: 08/04/2006, 13h18

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