Question programmation C

aymane -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -

Bonjour, 

Dans ce code, le compilateur place les variables sur la pile dans l'ordre de déclaration et par adresse croissante à partir de l'adresse 1000 (i.e. a est placé à l'adresse 1000, b est placé à l'adresse 1000 + sizeof (a), etc.)

#include <stdio.h>
#include <stdlib.h>

int main () {
    int a = 1;
    int * b = a;
    int * c = *a;
    int * d = &a;
    int ** e = &a;
    int ** f = &d;
    int * g = *f;
    return 0;
}

Quelqu'un peut-il me  donner  la  valeur et  l'adresse de chaque variable à la fin ? Avec  une  explication pour chacune ? Je galère...

5 réponses

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     

    bonjour,

    as-tu affiché l'adresse et la valeur de chaque variable?

    qu'as-tu essayé?

    0
  2. PierrotLeFou
     

    As-tu seulement essayé de compiler ce code? Il ne compile pas chez moi.

    Fais également afficher les warning avec les options  -Wall -Wextra

    Avant de jouer avec les pointeurs, tu aurais intérêt à revoir la section de ton cours qui en discute.

    0
  3. PierrotLeFou
     

    Je te donne un seul exemple:

        int *c = *a;

    C'est une erreur car tu as déclaré  a  comme int.  *a  veut dire que  a  est un pointeur.

    0
  4. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
     

    Salut aymane,

    La réponse à cette question suppose, en théorie, de savoir quelle est la taille d'un int en bytes et quelle est taille d'un pointeur en bytes.

    Ces tailles ne sont pas standardisées par le language, lesquelles dépendent de l'implémentation du C et concrètement du compilateur (et éventuellement du processeur).

    En pratique, cependant, même avec ces informations, répondre à ta question est hasardeux, car le standard du C ne va pas non plus te garantir :

    • que la pile commencera à une certaine adresse,
    • ni que l'ordre dans lequel tes variables apparaissent dans le code correspondra à un un même ordre en mémoire,
    • ni si pour un ordre donné la pile grandit en incrémentant les adresses mémoire ou en les diminuant,
    • ni si l'espace entre deux variables stockées correspondra exactement à leur taille en mémoire (par exemple, à des fins d'optimisation, les adresses des variables pourront être alignées sur des adresses mémoires multiples de la taille d'une adresse sur l'architecture concernée afin que la lecture prenne moins de cycles processeur).

    C'est encore ici le compilateur qui décide selon son implémentation.

    Par exemple, et chez moi :

    #include <stdio.h>
    #include <inttypes.h>
    
    int main(void) {
            int n = 12;
            int * ptr = &n;
    
            printf("Pour ce programme un int occupe \t %zu bytes\n",
                            sizeof(n));
            printf("Pour ce programme un pointeur occupe \t %zu bytes\n",
                            sizeof(void *));
            printf("Pour ce programme un int * occupe donc \t %zu bytes\n",
                            sizeof(ptr));
            printf("La variable n est à l'adresse \t\t %" PRIuPTR "\n",
                            (uintptr_t)&n);
            printf("La variable ptr est à l'adresse \t %" PRIuPTR "\n",
                            (uintptr_t)&ptr);
            return 0;
    }

    donne :

    $ gcc -Wall -Wextra 37945168.c
    $ ./a.out 
    Pour ce programme un int occupe          4 bytes
    Pour ce programme un pointeur occupe     8 bytes
    Pour ce programme un int * occupe donc   8 bytes
    La variable n est à l'adresse            140721523672508
    La variable ptr est à l'adresse          140721523672496
    

    Avec un gcc 8.3.0 64 bits sous Linux Debian 64 bits.

    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     

    Bonjour,

    Je pense qu'il s'agit d'un exercice théorique (d'où les erreurs dans le code et les hypothèses un peu approximatives).

    Sauf erreur de ma part :

    • a vaut 1 par définition
    • b est un pointeur (invalide) dont la valeur vaut 1
    • c n'a aucun sens : on ne peut pas normalement pas assigner un entier dans un pointeur (même si moralement une adresse est une sorte d'entier). Mais même si on s'affranchit de ça, ça n'a aucune sens, car a vaut 1, et donc *a signifie "lire la valeur à l'adresse 1 de type int*". Or a cette adresse, ton programme n'a pas le droit de lire, ce qui provoquera en pratique une erreur de segmentation.
    • d est initialisé à l'adresse de a, donc 1000.
    • e est aussi initialisé à 1000, mais le type du pointeur n'est pas consistent (à cette adresse se trouve un int, pas un pointeur int *)
    • f contient l'adresse de d soit 1000 + sizeof(int) + 2 * sizeof(int *) selon l'énoncé
    • g vaut la valeur pointée par f, soit ce qui se trouve à l'adresse 1000, c'est-à-dire la valeur de d donc 1000.

    Bonne chance

    0