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# et pointeurs [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    710
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 710
    Par défaut C# et pointeurs
    Bonjour,

    je suis en train de bosser un bouquin sur les pointeurs et il y a un truc qui m' l'air tout bête mais que je n'arrive pas à comprendre :

    voici le 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
     
            unsafe public static void Modif(int * pi)
            {
                *pi = 500; pi++; *pi = 2000;
            }
     
            unsafe static void Main(string[] args)
            {
     
                int i=1, j=100, k = 20;
                Modif(&j);
     
                Console.ReadKey();
            }
    Le fait de faire pi++ fait pointer pi non plus sur j, mais sur i... Pourquoi n'est pas sur k ? Pourquoi le fait d'incrémenter pi le fait pointer sur la variable déclarée AVANT et non après ?

    Merci de vos explications !

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par grinder59 Voir le message
    Le fait de faire pi++ fait pointer pi non plus sur j, mais sur i... Pourquoi n'est pas sur k ?
    C'est ce que tu as observé, ou ce que dit le bouquin ?

    Je viens de tester, chez moi ça pointe sur k... l'état des variables à la fin est le suivant :

    i = 1
    j = 500
    k = 2000

    après ça dépend peut-être de la version du runtime, et du fait d'être en 32 ou 64 bits (j'ai testé dans LinqPad, .NET 4.0 64 bits)

  3. #3
    Membre éclairé Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    710
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 710
    Par défaut
    c'est ce que dit le bouquin et ce que j'ai observé...

    j'ai donc refait le test suivant :

    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
     
            unsafe public static void Modif(int* pi)
            {
                *pi = 500; pi++; *pi = 2000;
            }
     
            unsafe static void Main(string[] args)
            {
     
                int i = 1, j = 100, k = 20;
                Console.WriteLine("avant : i = " + i + ", j = " + j + ", k = " + k);
                Modif(&j);
                Console.WriteLine("après : i = " + i + ", j = " + j + ", k = " + k);
     
                Console.ReadKey();
            }
    voici un copier coller de ce qui est affiché sur la console :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    avant : i = 1, j = 100, k = 20
    après : i = 2000, j = 500, k = 20
    c'est donc i qui est modifié par l'opération pi++...

    mais pourquoi ?
    J'ai testé avec VS2010 express / 64 bits

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 194
    Par défaut
    Euh pour moi ce code ne devrait pas marcher

    Rien ne dit que la réservation des int se fait de manièere consécutive, pour moi il aurait fallu déclaré un tableau d'int

  5. #5
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 269
    Par défaut
    Bonjour,
    Citation Envoyé par BenoitM Voir le message
    Euh pour moi ce code ne devrait pas marcher

    Rien ne dit que la réservation des int se fait de manièere consécutive, pour moi il aurait fallu déclaré un tableau d'int
    Exact, Sauf que la déclaration des variables local par le compilateur sur la pile (IL) se fait de manière consécutive.
    Par contre rien n'oblige le compilateur à conserver le même ordre.

    En fait cette exemple ne marche que parce que i,j,k ont la même taille.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par grinder59 Voir le message
    mais pourquoi ?
    J'ai testé avec VS2010 express / 64 bits
    Comme je le disais, ça dépend du runtime... J'ai refait le test au boulot ce matin (Win XP 32 bits, .NET 4.0), et ni i ni k n'est modifié, seulement j. Par contre ça plante sur le retour de Main, parce que ça a dû foutre la zone en modifiant autre chose sur la pile. Par contre en désactivant les optimisations du compilateur, ça passe, et c'est i qui est modifié...

    Citation Envoyé par BenoitM Voir le message
    Euh pour moi ce code ne devrait pas marcher
    Bah en fait ça depend... ça fonctionne dans des cas particuliers. Bonne illustration de pourquoi le code "unsafe" s'appelle comme ça

  7. #7
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 69
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par antoine.debyser Voir le message
    Bonjour,

    Exact, Sauf que la déclaration des variables local par le compilateur sur la pile (IL) se fait de manière consécutive.
    Par contre rien n'oblige le compilateur à conserver le même ordre.

    En fait cette exemple ne marche que parce que i,j,k ont la même taille.
    Je pense que l'ordre dans la pile est l'ordre d'utilisation des variables et non pas l'ordre de declaration (meme si ici les 2 sont identiques) mais ca depend sans doute de chaque compilo

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 489
    Par défaut
    Bonjour,

    Citation Envoyé par grinder59 Voir le message
    Le fait de faire pi++ fait pointer pi non plus sur j, mais sur i... Pourquoi n'est pas sur k ? Pourquoi le fait d'incrémenter pi le fait pointer sur la variable déclarée AVANT et non après ?

    Merci de vos explications !
    Je ne pratique pas le C# et, donc, je ne peux pas être affirmatif en ce qui concerne ce langage précis, mais en C, bien qu'il ne s'agisse pas non plus d'un prérequis de la norme, tu observeras pratiquement toujours ce comportement.

    Cela s'explique par le fait que sur tous les micro-processeurs avec lesquels j'ai travaillé, et en dehors de toute considération propre à tout langage autre que le langage machine, le pointeur de pile est décrémenté lors de l'empilement, puis la valeur stockée. À l'inverse, lors d'un dépilement, la valeur pointée est chargée dans le bon registre puis le pointeur de pile est incrémenté. Par conséquent, lorsque la pile est vide, le pointeur de pile pointe initialement la fin du segment de pile.

    C'est dû au fait que, d'une part, il a bien fallu choisir un sens de fonctionnement et que, d'autre part, ceci permet de faire cohabiter le code et la pile dans le même segment de mémoire, chacun à son extrémité.

    Par conséquent, les premières variables empilées sont les plus « lointaines » en mémoire et c'est pourquoi, en incrémentant ton pointeur, tu passes à la précédente. À noter toutefois qu'en C et C++, toujours, les tableaux déclarés avec « [ ] » sont réputés consécutifs en mémoire et dans le bon ordre, c'est-à-dire que deux tableaux distincts seront empilés comme expliqué précédemment, mais qu'à l'intérieur d'un de ces tableaux, les éléments sont bien rangés dans le sens croissant. Il est probable que le comportement soit le même en C#.

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

Discussions similaires

  1. pointeurs
    Par ghost74 dans le forum C
    Réponses: 3
    Dernier message: 14/12/2002, 02h52
  2. Pointeur vers un tableau
    Par Nikos dans le forum C
    Réponses: 3
    Dernier message: 09/12/2002, 00h43
  3. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14
  4. djgpp et pointeurs far -2
    Par elvivo dans le forum Autres éditeurs
    Réponses: 16
    Dernier message: 29/07/2002, 22h43
  5. djgpp et pointeurs far
    Par elvivo dans le forum C
    Réponses: 2
    Dernier message: 13/07/2002, 00h44

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