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 :

qu'est ce que c'est ? *(int *)a;


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Novembre 2005
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 75
    Points : 62
    Points
    62
    Par défaut qu'est ce que c'est ? *(int *)a;
    salut à tous, voilà j'ai un probleme, je n'arrive pas à comprendre ce ceci:
    *(int *)a; pouvez vous m'eclairssir là-dessus ? je l'ai vu en cherchant des infos sur la fonction qsort, dans cette fonction qsort se trouve un appel à une fonction compare et c'est dans la fonction compare que j'ai vu cette ligne.
    pour etre claire voici un lien où trouver cette fonction qsort pour ceux qui ne l'ont pas encore vu : http://www.cplusplus.com/ref/cstdlib/qsort.html
    Merci d'avance

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Février 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2005
    Messages : 88
    Points : 107
    Points
    107
    Par défaut
    Salut,

    a est un pointeur sur n'importe quoi (void *).

    Or on travaille sur des entiers, donc on veut que a soit un pointeur d'entier.
    On cast donc a,
    a devient donc un pointeur d'entier

    Puis on accède à la valeur pointée par a grçace à l'opérateur *

    *(int *)a renvoie la valeur pointé par a (un int).

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int compare (const void * a, const void * b)
    {
      return ( *(int*)a - *(int*)b );
    }
    Ici les argument sont des pointeur générique donc en fait il faut caster les donner dans leur type d'origine pour pouvoir effectuer une comparaison, ce qu'on fait avec:
    vu qu'il s'agit d'un pointeur.

    Ensuite, pour récupérer la valeur stockée par un pointeur tu le fait naturellement comme ceci

    Tu entrevois la chose ?

  4. #4
    Membre du Club
    Inscrit en
    Novembre 2005
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 75
    Points : 62
    Points
    62
    Par défaut
    Ah ok, si je comprends bien, dans le cas où on aurait plutot declaré compare comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int compare ( const int *a,const int *b)
    {
      return (*a - *b);
    }
    ?
    et donc on juste convertir le pointeur generique void* en un pointeur d'entier ?

  5. #5
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par salif98
    Ah ok, si je comprends bien, dans le cas où on aurait plutot declaré compare comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int compare ( const int *a,const int *b)
    {
      return (*a - *b);
    }
    ?
    et donc on juste convertir le pointeur generique void* en un pointeur d'entier ?
    Oui

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Sauf que le (int*) peut convertir n'importe quoi en pointeur d'entier.
    En C, je trouve qu'il est plus propre d'utiliser:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int compare ( void const * pcgA, void const * pcgB)
    {
    int const * pcA = pcgA;
    int const * pcB = pcgB;
     
    return (*pcA - *pcB);
    }
    Ici en C, aucun cast n'est nécessaire, donc aucun risque changement intempestif de niveau d'indirection...

  7. #7
    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 Médinoc
    En C, je trouve qu'il est plus propre d'utiliser:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int compare ( void const * pcgA, void const * pcgB)
    {
    int const * pcA = pcgA;
    int const * pcB = pcgB;
     
    return (*pcA - *pcB);
    }
    Ici en C, aucun cast n'est nécessaire, donc aucun risque changement intempestif de niveau d'indirection...
    +1

  8. #8
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Oui et c'est surtout plus lisible

  9. #9
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Médinoc
    Ici en C, aucun cast n'est nécessaire, donc aucun risque changement intempestif de niveau d'indirection...
    Ah? Ceci n'est pas un changement intempestif de niveau d'indirection?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int compare ( void const * pcgA, void const * pcgB)
    {
    int const ** pcA = pcgA;
    int const * pcB = pcgB;
     
    return (**pcA - *pcB);
    }

  10. #10
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Franck.H
    Oui et c'est surtout plus lisible
    Vous me permettrez un avis divergent. Je n'aime pas trop les conversions implicites quand elles ne sont pas garanties statiquement d'être valables. void* -> X* n'est pas garanti valable et je préfère expliciter le cast.
    X* -> void* est garanti valable, je préfère l'absence de cast (en fait il y a des conversions garanties où je préfère aussi le cast, il faudra que je réfléchisse une fois au pourquoi).

  11. #11
    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 Jean-Marc.Bourguet
    Vous me permettrez un avis divergent. Je n'aime pas trop les conversions implicites quand elles ne sont pas garanties statiquement d'être valables. void* -> X* n'est pas garanti valable et je préfère expliciter le cast.
    X* -> void* est garanti valable, je préfère l'absence de cast (en fait il y a des conversions garanties où je préfère aussi le cast, il faudra que je réfléchisse une fois au pourquoi).
    A ma connaissance les conversions sont garanties dans les 2 sens en C.

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Ah? Ceci n'est pas un changement intempestif de niveau d'indirection?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int compare ( void const * pcgA, void const * pcgB)
    {
    int const ** pcA = pcgA;
    int const * pcB = pcgB;
     
    return (**pcA - *pcB);
    }
    Oups J'avais oublié que void* était aussi compatible avec les pointeurs de pointeurs... Le seul niveau d'indirection qu'il interdit, c'est le niveau zéro...

  13. #13
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    A ma connaissance les conversions sont garanties dans les 2 sens en C.
    Par pas garanti, je faisais allusion à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char foo[4];
    char *bar = &foo[1];
    void *baz = bar;
    int *bat = baz;
    int qux = *bat;
    Boum! sur ma machine et pas la moindre indication d'une conversion douteuse.

  14. #14
    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 Jean-Marc.Bourguet
    Par pas garanti, je faisais allusion à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char foo[4];
    char *bar = &foo[1];
    void *baz = bar;
    int *bat = baz;
    int qux = *bat;
    Boum! sur ma machine et pas la moindre indication d'une conversion douteuse.
    La souplesse implique de nouvelles responsabilités ! On ne peut évidemment pas faire n'importe quoi.

    Il me semble qu'un compilateur pour machines à alignement pair (Freescale, 68k, PPC), il y aurait eu un warning sur les risques de 'misalignment'... Mais le compilateur ne peut pas toujours tout voir et il est dangereux de compter dessus...

  15. #15
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    La souplesse implique de nouvelles responsabilités ! On ne peut évidemment pas faire n'importe quoi.
    Je préfère que les endroits dangereux soient marqués, même si ce n'est pas obligatoire. J'aurais préféré que ce soit obligatoire, un void* qui se transforme en autre chose que ce qu'on désire -- parce qu'on a inversé deux arguments dans un appel de fonction par exemple -- c'est un peu trop facile à avoir.

  16. #16
    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 Jean-Marc.Bourguet
    Je préfère que les endroits dangereux soient marqués, même si ce n'est pas obligatoire. J'aurais préféré que ce soit obligatoire, un void* qui se transforme en autre chose que ce qu'on désire -- parce qu'on a inversé deux arguments dans un appel de fonction par exemple -- c'est un peu trop facile à avoir.
    On ne peut pas non plus être assisté tout le temps... Parfois, il faut accepter de vivre dangereusement, sinon, à la longue, c'est chi*nt...

  17. #17
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    On ne peut pas non plus être assisté tout le temps... Parfois, il faut accepter de vivre dangereusement, sinon, à la longue, c'est chi*nt...
    Pour vivre dangereusement, les schedules qu'on a me suffisent amplement. Passer du temps à débugger à cause de ce genre d'erreur, j'aime pas. Si tu veux te passer de la vérification de type, tu peux essayer BCPL si tu veux.

  18. #18
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 582
    Points
    41 582
    Par défaut
    C'est pour ça que j'ai tendance à préférer les casts C++ (bien que là encore, ils ne soient pas assez restrictifs à mon gout)
    • static_cast<>() pour les conversions de nombres, ou de void* vers type*, ou ClasseDeBase* vers ClasseDerivee*
    • reinterpret_cast<>() pour les conversions truc* vers machin*, mais hélas, aussi pour les conversions pointeur/entier : j'aurais préféré deux opérateurs différents, dont l'un restreint aux pointeurs...
    • const_cast<>() pour éliminer un attribut const ou volatile

  19. #19
    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 Médinoc
    C'est pour ça que j'ai tendance à préférer les casts C++ <...>
    Ben oui, mais en C, on fait comme on peut...

Discussions similaires

  1. est-ce que python est ce que je cherche
    Par SILICONE dans le forum Général Python
    Réponses: 5
    Dernier message: 21/12/2007, 14h23
  2. Qu'est ce que c'est qu'un Trigger ?
    Par shingo dans le forum Requêtes
    Réponses: 2
    Dernier message: 22/10/2003, 22h09
  3. Un daemon qu'est ce que c'est exactement ?
    Par CedricYhuel dans le forum Administration système
    Réponses: 5
    Dernier message: 01/08/2003, 11h56
  4. Qu'est ce que c'est : Le GateA20 ?
    Par le mage tophinus dans le forum x86 16-bits
    Réponses: 5
    Dernier message: 24/02/2003, 15h09
  5. Qu'est-ce que c'est que Nessus, ça fait quoi exactement ?
    Par PeterT dans le forum Développement
    Réponses: 3
    Dernier message: 24/07/2002, 11h23

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