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 :

Quelques précisions. . .


Sujet :

C

  1. #121
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Oui, mais on commence par caster un simple void*, et on finit par caster le retour de malloc()...
    (ce qui, si on n'a pas inclut stdlib.h, peut cacher l'erreur, menant à la catastrophe sous Win64 ou sur des systèmes basés sur processeur 68k...)
    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.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Array Voir le message
    Qu'ais-je dis d'incorrect dans cette affirmation? :
    Combien va-t-il falloir répéter qu'on ne peut pas déréférencer un pointeur de type void, tout simplement parce que le compilateur n'a pas d'information sur la taille de l'objet pointé et ne peut donc pas mettre en oeuvre l'arithmétique des pointeurs. Tout cela est expliqué dans le moindre livre de C.
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par PsychoH13 Voir le message
    Relis son message ! Il dit que le pointeur void pour le compilateur ne veut rien dire,
    OK.
    il faut donc faire un cast !
    Euh, non. Il suffit d'utiliser un pointeur local du bon type qu'il suffit d'initialiser avec la valeur du pointeur void.
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par PsychoH13 Voir le message
    C'était pour lui montrer le principe, et ce n'est pas une erreur, c'est juste pas utile dans ce cas là en tout cas, ce qui est une grosse nuance, rien ne t'empêche d'écrire le cast.
    Certes, mais l'erreur est de dire "il faut donc faire un cast". C'est pas 'il faut" mais "on peut". Mais ce n'est pas le point le plus important. Ce qui compte, c'est qu'il faut[1] un pointeur local du type 'utilisateur'.

    -------------------
    [1] Certes, on peut s'en passer, mais au prix d'un extrême complication du code qui le rend illisible et inmaintenable...
    Pas de Wi-Fi à la maison : CPL

  5. #125
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Je crois comprendre!
    C'est que &gpln[0] est un comprtement indéfini, alors que gpln ne sous-entend pas de comportement indéfini, puisque c'est l'addresse emmagasinée dans le pointeur void!

    Cependant, en lisant vos derniers post, je m'interroge sur cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int character = *((unsigned char *) c);
    Thierry aurait t-il pu remplacer cette ligne par :

    int *character = c;

    Et utiliser *character pour le déréférencer?


    Voilà...

    Merci,

    Array

  6. #126
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par Array Voir le message
    Je crois comprendre!
    C'est que &gpln[0] est un comprtement indéfini, alors que gpln ne sous-entend pas de comportement indéfini, puisque c'est l'addresse emmagasinée dans le pointeur void!

    Cependant, en lisant vos derniers post, je m'interroge sur cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int character = *((unsigned char *) c);
    Thierry aurait t-il pu remplacer cette ligne par :

    int *character = c;

    Et utiliser *character pour le déréférencer?


    Voilà...

    Merci,

    Array
    Non, c'est équivalent à:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void print_char(void *c)
    {
        if (c != NULL)
        {
            /* -tc- affectation de l'adresse du caractere a afficher a un pointeur
                local du type qui va bien */
            unsigned char *pc = c;
            /* -tc- dereferencement de ce pointeur pour recuperer la valeur du
                caractere a afficher */
            int character = *pc;
            /* -tc- affichage */
            printf("%c ", character);
        }
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  7. #127
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Bonjour,

    J'aurais deux questions...

    1)Comme vous le savez, le type "double" prend plusieurs case de mémoire pour une seule variable.

    Je voulais savoir si, à l'aide de pointeurs, il serait possible d'accéder individuellement les cases qui forment le "double".


    2)J'aimerais savoir pourquoi la calculatrice Windows ne fait pas d'erreurs lorsqu'elle traite des nombres à virgule...

    Merci,

    Array

  8. #128
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    308
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 308
    Points : 373
    Points
    373
    Par défaut
    Pour la première question tu peux éventuellement t'aider d'une union comme celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    union DoubleChar
    {
        double d;
        char c[sizeof(double)];
    } DoubleChar;
    Ensuite, tu peux accéder aux valeurs comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DoubleChar var;
    var.d = 5.5;
    var.c[2] // accès au troisième octet du double.
    Sinon, la calculatrice Windows peut utiliser des flottants avec une plus grande précision, ou alors elle utilise des types à elles.

  9. #129
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par Array Voir le message
    Bonjour,

    J'aurais deux questions...

    1)Comme vous le savez, le type "double" prend plusieurs case de mémoire pour une seule variable.

    Je voulais savoir si, à l'aide de pointeurs, il serait possible d'accéder individuellement les cases qui forment le "double".
    Oui, c'est possible, mais cela ne te sert à rien, car ce n'est la représentation au niveau binaire dépend du système (représentation, boutisme). Il n'est donc pas conseillé de te servir de cette possibilité.

    Citation Envoyé par Array Voir le message
    2)J'aimerais savoir pourquoi la calculatrice Windows ne fait pas d'erreurs lorsqu'elle traite des nombres à virgule...

    Merci,

    Array
    Elle en fait certainement.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  10. #130
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par PsychoH13 Voir le message
    Pour la première question tu peux éventuellement t'aider d'une union comme celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    union DoubleChar
    {
        double d;
        char c[sizeof(double)];
    } DoubleChar;
    Ensuite, tu peux accéder aux valeurs comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DoubleChar var;
    var.d = 5.5;
    var.c[2] // accès au troisième octet du double.
    C'est un comportement indéfini. Tu ne peux pas retirer d'une union autre chose que ce que tu as mis dedans. Ainsi, dans le cas du code ci-dessus, tu ne peux initialiser var via le champ d de l'union et accéder à sa valeur via le c. La seule exception à cette règle, c'est lorsque tu as une union de structures ayant une séquence initiale commune.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Array Voir le message
    1)Comme vous le savez, le type "double" prend plusieurs case de mémoire pour une seule variable.
    Par case mémoire, je suppose que tu parles de 'byte'...
    Je voulais savoir si, à l'aide de pointeurs, il serait possible d'accéder individuellement les cases qui forment le "double".
    Oui, avec un 'hack' horrible comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       double d = 12.34;
       unsigned char *p = (unsigned char *)&d;
    je ne vois pas bien à quoi ça peut servir...
    2)J'aimerais savoir pourquoi la calculatrice Windows ne fait pas d'erreurs lorsqu'elle traite des nombres à virgule...
    Tu peux le prouver ?
    Pas de Wi-Fi à la maison : CPL

  12. #132
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Tu peux le prouver ?
    Eh, j'y tâcherai.
    Mais je n'ai pas le temps là maintenant.
    J'en suis presque sûr...

    Merci pour vos réponses.
    ---
    Toutefois, quelque chose me tracasse à nouveau.

    Voici un code:
    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    void fonction(const int atest[][1]) {
    	putchar('\0');
    	return;
    }
     
    int main(void) {
    	int atest[2][1];
    	atest[0][1] = 192;
    	atest[1][1] = 324;
    	fonction(atest);
    	return 0;
    }
    Voici des erreurs :
    Code icc : 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
    Intel(R) C++ Compiler for applications running on IA-32, Version 10.0
    Build 20070613 Package ID: W_CC_C_10.0.026
    Copyright (C) 1985-2007 Intel Corporation.  All rights reserved.
    
    cplc.c
    cplc.c(13): warning #167: argument of type "int (*)[1]" is incompatible with parameter of type "const int (*)[1]"
      	fonction(atest);
      	         ^
    
    ipo: remark #11001: performing single-file optimizations
    ipo: remark #11005: generating object file C:\DOCUME~1\YANNIC~1\LOCALS~1\Temp\ipo_148.obj
    Microsoft (R) Incremental Linker Version 6.00.8168
    Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
    
    -out:cplc.exe 
    -nodefaultlib:libguide_stats.lib 
    -nodefaultlib:libguide40_stats.lib 
    -defaultlib:libguide.lib 
    C:\DOCUME~1\YANNIC~1\LOCALS~1\Temp\ipo_148.obj

    J'ai essayé différents casts... mais... déception.

    Comment faire pour ne plus avoir cette erreur, le plus possible avec un cast.

    Merci,

    Sincèrement,

    Array

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Array Voir le message
    Voici des erreurs :
    Code icc : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Intel(R) C++ Compiler for applications running on IA-32, Version 10.0
    Déjà, tu compiles en C++ qui est un autre langage. Ici, on parle du C.
    Pas de Wi-Fi à la maison : CPL

  14. #134
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    lol.
    Eh oui, je l'admets, cela peut enegndrer de la confusion, mais ce compilateur est bien un compilateur de C. En fait, on a tendance à appeller ICC "Intel C/C++ Compiler", mais le vrai nom officiel du compilateur est Intel C++ Compiler. Donc... ce compilateur est valable pour les deux.
    Me crois tu assez ignorant pour faire une telle bévue?
    Je sais différencer le C du C++!

    D'autre part, en faisant des recherches, j'ai trouvé la cast qu'il me fallait.
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    void fonction(const int atest[][1]) {
    	putchar('\0');
    	return;
    }
     
    int main(void) {
    	int atest[2][1];
    	atest[0][1] = 192;
    	atest[1][1] = 324;
    	fonction((const int (*)[1]) atest);
    	return 0;
    }
    Ce que je me demande, c'est cela : Si j'avais eu un tableau à trois dimensions, aurais-je pu faire "const int (*)[SIZE][SIZE2]"???

    De même, selon Emmanuel :
    Pour définir un paramètre de type pointeur sur un tableau à 2 dimensions, on serait tenté d'écrire type p[][], ce qui serait une erreur de syntaxe. En effet, la notation [] est une notation abrégée de [TAILLE] dans les cas où cette taille est ignorée par le compilateur, c'est à dire lorsque la dimension concernée est la plus à gauche. Les syntaxes suivantes sont légales :

    type_retour fonction (int p[])
    type_retour fonction (int p[12])
    type_retour fonction (int p[][34])
    type_retour fonction (int p[56][78])
    etc.
    Ainsi, ce n'est que la première taille qui peu ne pas être spécifiée.

    Voilà,

    Merci,

    Array

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Array Voir le message
    D'autre part, en faisant des recherches, j'ai trouvé la cast qu'il me fallait.
    Pas besoin de cast. Il suffit de mettre le bon type. Si tu tiens au 'const', il doit s'appliquer aux données du tableau, on est donc obligé d'utiliser la notation 'pointeur de tableau'. Et attention aux débordements de tableau... :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    void fonction (int (*const atest)[1], size_t lin, size_t col)
    {
       size_t i;
     
       for (i = 0; i < lin; i++)
       {
          size_t j;
     
          for (j = 0; j < col; j++)
          {
             printf ("%4d", atest[i][j]);
          }
          printf ("\n");
       }
       return;
    }
     
    int main (void)
    {
       int atest[2][1];
       atest[0][0] = 192;
       atest[1][0] = 324;
       fonction (atest, sizeof atest / sizeof *atest,
                 sizeof *atest / sizeof **atest);
       return 0;
    }
    Pas de Wi-Fi à la maison : CPL

  16. #136
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Merci pour cette réponse.
    J'aime bien mieux utiliser la notation 'pointeur de tableau' que de faire de longs cast comme je faisais.

    Voilà que m'interroge maintenant au sujet de...

    ...les structures.

    Je me suis documenté sur les structures.
    Mais j'ai de la difficulté à saisir le principe.

    Alors, voilà la question :

    À quoi servent les structures?
    Pourquoi les utilsent-on?
    Comment les utiliser?
    Quel est l'intérêt d'utiliser une structure?

    Si vous pouviez me prêter secours...


    Merci,

    Array

  17. #137
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    308
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 308
    Points : 373
    Points
    373
    Par défaut
    Citation Envoyé par Array Voir le message
    À quoi servent les structures?
    Pourquoi les utilsent-on?
    Comment les utiliser?
    Quel est l'intérêt d'utiliser une structure?
    Il y a 3 questions qu'on peut regrouper en une.

    Une structure permet de regrouper plusieurs variables des liens entre elles dans une seul et des les déplacer/utiliser/modifier en une seule variable.

    Par exemple, pour un carnet d'adresse on va faire une structure "Personne" qui va contenir une chaîne de caractère pour le nom, une pour le prénom, une pour l'adresse, le numéro de rue, le code postale, la ville et le numéro de téléphone.
    Ce qu'on manipulera ce sont des Personne et pas 5 variables différentes.

    Donc on définit une structure comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct nomStruct {
        type_champ1 nom_champ1;
        type_champ2 nom_champ2;
        ...
    }; // ne pas oublier le ; à la fin
    Pour créer une variable de ce type de structure, on va simplement écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct nomStruct maVar;
    Et comme "struct nomStruct" et lourd à écrire, on va créer un type avec le mot clé typedef :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct nomStruct nomType;
    Et là on pourra simplement écrire :
    maVar sera de type nomType qui correspond au type struct nomStruct.

    Ensuite, pour accéder aux champs, on utilise l'opérateur ".", exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // autre façon d'écrire le typedef avec une struct
    typedef struct Rationnel {
        int numerateur;
        unsigned denominateur;
    } Rationnel;
     
    // ...
     
    Rationnel nombre;
     
    nombre.numerateur = 5;
    Si, maintenant tu fais un pointeur sur ton type, tu peux utiliser l'opérateur "->", par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Rationnel nombre;
    Rationnel *ptr = &nombre;
    ptr->numerateur = 5;
    // équivaut à :
    (*ptr).numerateur = 5;
    Après tu peux utiliser tes structures dans des types de retour de fonctions ou dans des paramètres de fonctions.

  18. #138
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    J'en déduis donc que c'est plus pratique qu'essentiel?

    Sinon, donnez moi un exemple où un struct est essentiel au fonctionnement du programme... s.v.p.


    De plus...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    nombre.numerateur = 5;
    Dans l'exemple de psychoH13, est-ce nombre qui aura la valeur de 5 ou nombre est-il moyen d'accéder à numerateur? Autrement dit, qu'est-ce qui prendra la valeur de 5 ?

    Ce que j'aimerais également savoir, c'est :
    - Pourquoi je ne peux pas faire de "size_t i = 273;" dans une fonction?!
    - Peut-on modifier une valeur d'une structure en permanence, où une structure n'est-elle qu'une déclaration?


    En tout cas ça m'a l'air utile!

    EDIT :

    Dans un snippet de code comme celui-ci
    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
     
    	while (lntype < 4) {
    		switch (lntype) {
    			case DESCENDING:
    				fdim_i = 0;
    				sdim_i = 0;
    				fdim_i_addv = 1;
    				sdim_i_addv = 1;
    				taskind = DESCENDING;
    				fdim_ind = dim_sz-1;
    				break;
    			case ASCENDING:
    				fdim_i = dim_sz-1;
    				sdim_i = 0;
    				fdim_i_addv = -1;
    				sdim_i_addv = 1;
    				taskind = ASCENDING;
    				fdim_ind = 0;
    				break;
    			case VERTICAL:
    				fdim_i = dim_sz-1;
    				sdim_i = 0;
    				fdim_i_addv = 0;
    				sdim_i_addv = 1;
    				taskind = VERTICAL;
    				sdim_ind = dim_sz-1;
    				break;
    			case HORIZONTAL:
    				fdim_i = 0;
    				sdim_i = 0;
    				fdim_i_addv = 1;
    				sdim_i_addv = 0;
    				taskind = HORIZONTAL;
    				fdim_ind = dim_sz-1;
    				break;
    		}
    Serait-il mieux d'utiliser une structure?

    Que d'interrogations!

  19. #139
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    308
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 308
    Points : 373
    Points
    373
    Par défaut
    Citation Envoyé par Array Voir le message
    J'en déduis donc que c'est plus pratique qu'essentiel?

    Sinon, donnez moi un exemple où un struct est essentiel au fonctionnement du programme... s.v.p.
    Tu peux toujours te passer des structures, les structures te permettent de pouvoir utiliser plusieurs variables différentes comme si c'était qu'un seul bloc.

    Par exemple, si tu écris mes nombres rationnels sans structure ça te donnera :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int nbnum;
    unsigned nbden;
    La seule relation entre les deux variables c'est le début du nom, c'est pas suffisant, toi tu vois la relation, mais pas le compilateur... Si tu veux faire un tableau de nombres rationnels, tu es soit obligé de doubler la taille du tableau et de stocker alternativement un numérateur puis un dénominateur, ou alors de faire 2 tableaux séparés et faire correspondre les indices...
    Je peux te dire, un informaticien se fait pas chier autant, il cherche toujours à simplifier au maximum, les structures sont là pour ça, tu peux faire un tableau de Rationnel de la même manière qu'un tableau d'entier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Rationnel tab[10]; // tableau de 10 Rationnels
    .

    Imagine par exemple tu veux faire la multiplication de deux rationnels, voilà le prototype de ta fonction sans structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void multiplicationRationnels(int num1, unsigned den1,
                                  int num2, unsigned den2,
                                  int *resNum1, unsigned *resNum2);
    En plus, comme tu peux pas retourner deux valeurs à la fois... Bah tu dois utiliser des pointeurs pour les valeurs de retour. Et une fonction à 6 arguments qui ne fait que la multiplication de deux nombres rationnels... C'est chiant, alors avec une structure voilà ce que ça donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Rationnel multiplicationRationnels(Rationnel nombre1, Rationnel nombre2);
    C'est déjà beaucoup plus propre, tu vois clairement que tu multiplies 2 entités distinctes, alors qu'avec le premier t'avais 6 paramètres pour seulement 3 entités distinctes. Et la structure te permet en plus de retourner les deux valeurs en un seul bloc. Donc, c'est pas forcément indispensable, mais du point de vue de la clarté et de la facilité d'écriture, ça l'est.

    Citation Envoyé par Array Voir le message
    De plus...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    nombre.numerateur = 5;
    Dans l'exemple de psychoH13, est-ce nombre qui aura la valeur de 5 ou nombre est-il moyen d'accéder à numerateur? Autrement dit, qu'est-ce qui prendra la valeur de 5 ?
    "nombre" c'est une variable agglomérée, ça signifie qu'elle contient plusieurs variables, en mémoire et sur un processeur 32 bits, ta variable "nombre" prendra 64 bits. En binaire (je ne vais écrire que 8 bits) ça donne ça :

    nombre {5/3}: [0000 0101|0000 0011], mais bon tu n'as pas cette séparation nette, ça donne en fait 0000 0101 0000 0011, l'opérateur . va permettre d'accéder à l'une des deux sous-variables :
    nombre.numerateur: 0000 0101 et
    nombre.denominateur: 0000 0011.

    Donc, "nombre" sera un agglomérat des valeurs 5 et 3 qui sont considérées dans le programme comme un seul bloc, mais pour pouvoir accéder à ces valeurs séparément afin de connaître la valeur ou de la modifier, on utilise les noms des champs de la structure.

    Citation Envoyé par Array Voir le message
    Ce que j'aimerais également savoir, c'est :
    - Pourquoi je ne peux pas faire de "size_t i = 273;" dans une fonction?!
    Pourquoi ne pourrait-on pas le faire ?

    Citation Envoyé par Array Voir le message
    - Peut-on modifier une valeur d'une structure en permanence, où une structure n'est-elle qu'une déclaration?
    On peut modifier les valeurs des champs d'une variable de type structure à n'importe quel moment. La déclaration d'une structure et figée, tu ne peux pas la modifier pendant l'exécution du programme.
    En revanche, tu peux définir des variables qui ont pour type la structure en question, par exemple "nombre" est une variables de type "Rationnel" qui est une structure, donc tu peux accéder à chacun de ses champs et en modifier la valeurs.


    Citation Envoyé par Array Voir le message
    En tout cas ça m'a l'air utile!

    EDIT :

    Dans un snippet de code comme celui-ci
    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
     
    	while (lntype < 4) {
    		switch (lntype) {
    			case DESCENDING:
    				fdim_i = 0;
    				sdim_i = 0;
    				fdim_i_addv = 1;
    				sdim_i_addv = 1;
    				taskind = DESCENDING;
    				fdim_ind = dim_sz-1;
    				break;
    			case ASCENDING:
    				fdim_i = dim_sz-1;
    				sdim_i = 0;
    				fdim_i_addv = -1;
    				sdim_i_addv = 1;
    				taskind = ASCENDING;
    				fdim_ind = 0;
    				break;
    			case VERTICAL:
    				fdim_i = dim_sz-1;
    				sdim_i = 0;
    				fdim_i_addv = 0;
    				sdim_i_addv = 1;
    				taskind = VERTICAL;
    				sdim_ind = dim_sz-1;
    				break;
    			case HORIZONTAL:
    				fdim_i = 0;
    				sdim_i = 0;
    				fdim_i_addv = 1;
    				sdim_i_addv = 0;
    				taskind = HORIZONTAL;
    				fdim_ind = dim_sz-1;
    				break;
    		}
    Serait-il mieux d'utiliser une structure?

    Que d'interrogations!
    C'est-à-dire qu'ici fdim_i, sdim_i, fdim_i_addv, sdim_i_addv, taskind et fdim_ind semblent être des variables qui sont utilisées en groupe, tu peux effectivement les mettre dans une structure, ça te permettra de voir que ce sont des variables qui définissent un même objet, cependant ça ne réduira pas le nombre de ligne dans ce switch.

  20. #140
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Merci Psycho.

    Toutefois, pourquoi je ne peux, dans une structure, faire cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    [...]
    struct hello {
          int i = 273;
          int j;
          char k;
    };
    [...]
    Pourquoi mon compilateur me retourne une erreur?

    Ensuite, les deux suls opérateurs pour exploiter les structures sont-ils uniquement "." et "->" ?


    Les champs de la structure, est-ce les variables déclarées à l'intérieur?


    Merci!

    Array

Discussions similaires

  1. Réponses: 1
    Dernier message: 23/12/2007, 19h44
  2. Entrées.. Sorties.. quelques précisions..
    Par Djef-69 dans le forum SL & STL
    Réponses: 2
    Dernier message: 28/11/2007, 23h16
  3. [Fabrique] Quelques Précisions
    Par djflex68 dans le forum Design Patterns
    Réponses: 8
    Dernier message: 20/12/2006, 13h34
  4. Quelques "précisions" sur Struts
    Par Atma_ dans le forum Struts 1
    Réponses: 19
    Dernier message: 03/11/2006, 15h20

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