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 :

Type de variable


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut Type de variable
    Bonjour,
    je voudrai comprendre un truc, le type est lié à l'adresse de la variable, ou c'est autrement ?
    par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main ()
    {
    int a;
    g (&a);
    }
     
    void g (double * b)
    {
    double * c = malloc(sizeof(b));
    }
    qu'est ce que j'aurai comme retour de malloc (int, double ?) ? est ce que le type de retour est vraiment important avec malloc ? qu'est ce que ça changeait si j'avais fait g(a) ?

    je comprends peut-être mal un truc, et j'aimerai le comprendre correctement.
    car je fais un programme avec pleins de structures différentes, mais qui ont des points communs (nom de variables - mais pas toutes), il n'y a pas d'héritage, donc je pensais utilisé des structures types, qui engloberait par exemple toutes les structures ayant comme paramètres 'data', et je voulais les utiliser exclusivement pour les allocation de mémoire ou de libération de mémoire, mais j'ai peur que ça cache des problèmes, et que je comprenne pas forcement ce qui va pas.

    merci de m'aider.
    j'ai dû mal à m'exprimer correctement, donc si vous n'avez pas compris, n'hésitez pas.

    @ bientôt

  2. #2
    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 : 48
    Localisation : Suisse

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    malloc() ne retourne ni un entier de type int, ni un entier de type double. Cette fonction retourne l'adresse d'un espace mémoire alloué dynamiquement dans lequel il est possible de placer la valeur d'une variable, éventuellement de type int ou de type double en fonction de la taille mémoire de l'espace alloué. Le type de la variable retournée par malloc() est un pointeur générique de type (void *) qui peut être converti, implicitement ou explicitement, en n'importe quel autre type de pointeur.

    Dans ton exemple, malloc() alloue l'espace mémoire pour stocker une variable de type pointeur sur double et retourne l'adresse de cet espace mémoire. Ta variable c doit par conséquent avoir le type de pointeur sur un pointeur sur double, à savoir double **. Nous avons donc:

    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
    int main(void)
    {
        /* -tc- Si on suppose que a est de type double, et non int comme
            dans ton exemple */
        double a;
        /* -tc- On passage a la fonction g() l'adresse de la variable a, de type 
            pointeur sur double (double *) */
        g(&a);
    }
     
    /* -tc- La fonction g() prend en argument une variable de type pointeur sur 
       double  */
    void g(double * b)
    {
        /* -tc- malloc() retourne l'adresse d'un espace memoire alloue pour
            un pointeur sur double et retourne l'adresse de cet espace mémoire */
        double ** c = malloc(sizeof b);
        /* -tc- Toujours tester la validite de l'adresse retournee par malloc()
        if (c != NULL)
        {
            /* -tc- Eventuellement faire qqch avec c */
     
            /* -tc- Une fois qu'on quitte la fonction g(), la variable c est perdue,
                mais l'espace alloue n'est pas libere. Ne pas oublier de liberer l'espace
                alloue par malloc() avec free(). */
            free(c), c = NULL;
        }
    }
    Si c'est l'espace mémoire pour un flottant de type double que tu désires allouer, tu peux écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    double * c = malloc(sizeof *b);
    Le reste du code reste identique. Ne perd pas de vue que si l'adresse stockée dans le pointeur c n'est pas retournée d'une manière ou d'une autre à la fonction appelante, l'adresse de cet espace mémoire est perdue alors que l'espace lui-même n'est pas libéré.

    Avec mes meilleures salutations

    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++

    +

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 497
    Billets dans le blog
    1
    Par défaut
    Petite question pour Thierry : la taille d'un objet de type "pointeur sur X" dépend-elle de la nature de X ?

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Je ne crois pas que la norme dise quoi que ce soit au sujet de la taille des pointeurs. En particulier, je pense qu'il est théoriquement possible que des pointeurs vers des données et des pointeurs vers du code ne fassent pas la même taille.

    En pratique je ne pense pas qu'il existe des architectures où tous les types de pointeurs n'ont pas la même taille.

  5. #5
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    merci pour vos réponses, je vois un peu mieux les choses.

    je vois comment je vais faire ce que je voulais faire

    >et désolé pour l'oubli de balise 'code'

  6. #6
    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 : 48
    Localisation : Suisse

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Petite question pour Thierry : la taille d'un objet de type "pointeur sur X" dépend-elle de la nature de X ?
    A mon avis, c'est indéfini. Ce que dit la norme, c'est qu'un pointeur générique de type (void *) doit pouvoir être converti vers n'importe quel type de pointeur. Il semble qu'il soit possible de convertir un type pointeur vers un autre type pointeur, et retour, sans perte d'info si l'adresse contenue dans le pointeur satisfait les contraintes d'alignement du nouvel objet pointé. En cas de violation des contraintes d'alignement, le comportement semble indéfini. Cette question est discutée au §6.3.2.3 de n1256.

    Avec mes meilleures salutations

    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. #7
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    en faite je préfère reposer une question, histoire d'être sûr
    si on alloue de la mémoire et que l'on cast pas, cela convertira automatiquement de void * (le retour d'adresse de malloc) au type de la variable qui reçoit l'allouement de mémoire ? donc si c'est oui, le type de la variable est lié á la variable, lors de l'execution, donc si on alloue de la mémoire avec une variable d'un autre type mais qui pointe vers l'autre d'un autre type, est ce que allouer de la mémoire sur cette dernière variable changera qqchose ?

    --> surement que non, il n'y a que la taille du type qui compte, mais je veux être sûr, c'est que c'est sûrement pas forcement clair dans ma tête.

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 853
    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 : 12 853
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dafpp Voir le message
    en faite je préfère reposer une question, histoire d'être sûr
    si on alloue de la mémoire et que l'on cast pas, cela convertira automatiquement de void * (le retour d'adresse de malloc) au type de la variable qui reçoit l'allouement de mémoire ? donc si c'est oui, le type de la variable est lié á la variable, lors de l'execution, donc si on alloue de la mémoire avec une variable d'un autre type mais qui pointe vers l'autre d'un autre type, est ce que allouer de la mémoire sur cette dernière variable changera qqchose ?
    Salut
    C'est pas faux...

    Citation Envoyé par dafpp Voir le message
    c'est que c'est sûrement pas forcement clair dans ma tête.
    Oui je vois ça.

    Ce qu'il faut bien comprendre, c'est que pour le C, une adresse n'est qu'un nombre. A priori, rien ne t'interdit d'écrire
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int x;
    x=malloc(sizeof(double));   // Stocker l'adresse de la zone allouée dans un entier

    Le problème vient de ce que tu en fais après. Parce que avoir une adresse d'une zone mémoire ne se justifie que si tu vas travailler avec la zone mémoire concernée. Et l'opérateur "utiliser le contenu" est l'étoile single. Donc si tu veux stocker pi à l'adresse allouée, la suite logique du code ci-dessus sera la suivante
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int x;
    x=malloc(sizeof(double));   // Stocker l'adresse de la zone allouée dans un entier
    *x=3.1416;         // Stocker un double dans la zone allouée
    Et, là est le problème, tu n'as rien précisé de ce qu'était "étoile x". Il est bien écrit "x est un nombre" mais rien sur "étoile x". Et donc le compilo ne peut pas travailler avec "étoile x" s'il ne sait pas ce que c'est.

    Donc pour régler le problème, il te faut revenir au début de ton code et préciser que "étoile x" est un double. D'où la syntaxe suivante

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double *x;        // J'informe le compilo de ce qu'est "étoile x"
    x=malloc(sizeof(double));   // Stocker l'adresse de la zone allouée dans x qui, reste un entier
    *x=3.1416;         // Stocker un double dans la zone allouée qui est maintenant connue comme un double
    Maintenant, le compilo sait que "étoile x" est un double et peut travailler avec.

    Toutefois, rien ne t'interdit de modifier le typage de la zone après coup (voire de l'utiliser différemment)
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    double *x;
    int *y;                         
    x=malloc(sizeof(double));
    *x=3.1416;
    printf("contenu de *x: %f\n", *x);    // Je regarde ce qu'il y a dans la zone
     
    y=x;           // Je copie l'adresse de la zone dans y (x et y étant 2 pointeurs donc deux objets identiques, c'est autorisé)
    printf("contenu de *y: %d\n", *y);       // Je regarde ce qu'il y a dans la zone
    Bien entendu, la façon de coder les int et les double étant totalement différente, le compilo tentant de décoder à la façon d'un int ce qui a été codé à la façon d'un double te sortira n'importe quoi. Mais il n'y a aucune irrégularité vis à vis de la norme dans ce code (surtout qu'un int étant plus petit qu'un double, le compilo ne dépassera pas la zone allouée pendant qu'il récupère ce qu'il y a...)
    Mon Tutoriel sur la programmation «Python»
    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
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Type et variable
    Par cloogy dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 28/12/2004, 15h07
  2. [SQL S 2000] Type de variable ?
    Par Tankian dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 29/06/2004, 14h03
  3. Assembleur et type de variable delphi
    Par declencher dans le forum Langage
    Réponses: 5
    Dernier message: 20/06/2004, 23h21
  4. Comparer les types de variable
    Par onipif dans le forum ASP
    Réponses: 11
    Dernier message: 27/05/2004, 18h07
  5. Types de variables entre mysql/php et flash
    Par ramses83 dans le forum Flash
    Réponses: 2
    Dernier message: 06/10/2003, 18h35

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