Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1559 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] soustraire deux pointeurs

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] soustraire deux pointeurs

n°2049750
unecrepe
Keep It Simple, Stupid
Posté le 17-01-2011 à 21:40:04  profilanswer
 

Bonjour à tous,  
 
Je suis débutant en prog', je me pose une question sur l'emploi des pointeurs en C. Je la soumets à votre sagacité.  
 
Supposons donné un tableau (disons d'entiers) et un pointeur vers un entier qui se promène dans ce tableau, comme dans :

Code :
  1. int* pint = my_int_array ;
  2. while (foo){
  3.     pint++;
  4.     foo = bar(foo, *pint);
  5. }


 
Comment pourrais-je évaluer d'une manière élégante la position du pointeur dans mon tableau ? J'avais pensé à faire :

Code :
  1. int rank = (pint - my_int_array) / sizeof( int);


mais je reçois une erreur de typage.
 
J'ai lu qu'il n'existe pas d'opérateur de conversion d'un pointeur vers un entier, c'est pourtant un peu ce que je voudrais faire : obtenir la partie adresse du pointeur sous forme d'un entier (ou d'un long ptet' ) ?
 
Merci de votre lecture  
 
ced'


Message édité par unecrepe le 17-01-2011 à 21:42:23
mood
Publicité
Posté le 17-01-2011 à 21:40:04  profilanswer
 

n°2049759
philippe06
Posté le 17-01-2011 à 22:53:52  profilanswer
 

un cast ?


---------------
Aimer les femmes intelligentes est un plaisir de pédéraste. (Charles Baudelaire) - Vous vulgarisez :o (Jean-Kevin Dubois)
n°2049760
unecrepe
Keep It Simple, Stupid
Posté le 17-01-2011 à 23:00:35  profilanswer
 

merci de ta réponse, qu'a le mérite d'économiser les disques durs du serveur !
 
Tu voudrais bien développer un peu ce que tu veux dire par là (un exemple de code ou bien un lien) steup ?

n°2049764
philippe06
Posté le 17-01-2011 à 23:16:08  profilanswer
 

rank=((int)pint - (int)my_int_array) / sizeof( int);


---------------
Aimer les femmes intelligentes est un plaisir de pédéraste. (Charles Baudelaire) - Vous vulgarisez :o (Jean-Kevin Dubois)
n°2049766
unecrepe
Keep It Simple, Stupid
Posté le 17-01-2011 à 23:22:16  profilanswer
 

Merci de ton aide !
 
En fait ce truc retourne une erreur de taille d'entier donc il faut remplacer les (int) par des (long)
 

n°2049827
Un Program​meur
Posté le 18-01-2011 à 11:01:15  profilanswer
 

Donne du code complet parce qu'il ne devrait pas etre necessaire d'utiliser des cast pour ca.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°2049834
shaoyin
Posté le 18-01-2011 à 11:16:23  profilanswer
 

La division par sizeof(int) me parait curieuse (voire en trop).
Il devrait même être possible, grace à l'arithmétique des pointeurs, de faire directement :
rank = pint - my_int_array;
 
Après tout, pour accéder à l'élément de rang i dans le tableau , on fait juste :
 
pint = my_int_array + i;
 
de même que l'instruction pint++ fait avancer le pointeur sur l'élément suivant, quelle que soit sa taille.

n°2049875
unecrepe
Keep It Simple, Stupid
Posté le 18-01-2011 à 13:48:23  profilanswer
 

Merci de votre aide.
 
Vous avez raison, l'arithmétique des pointeurs fonctionne comme on s'y attend :
 
on a un opérateur - (moins) qui à un couple de pointeurs du même type associe un entier correspondant à la différence des adresses divisée par la taille du type en question.
 
On donc a en fait toujours

Code :
  1. pint - my_int_array == ((long)(pint) - (long)(my_int_array))/sizeof(int)


 
J'avais mal interprété un message d'erreur qui venait du fait que mon pointeur n'avait pas été initialisé, ou je ne sais plus trop quoi. :)
 

n°2049945
gilou
Modérateur
Modzilla
Posté le 18-01-2011 à 17:28:57  profilanswer
 

Oui: L'arithmétique des pointeurs, c'est exactement fait pour cela:

Citation :

p2 - p1 = (adresse contenue dans p2 - adresse contenue dans p1) /taille(éléments pointés par p1 et p2)
 
Le type du résultat de la soustraction de deux pointeurs est très dépendant de la machine cible et du modèle mémoire du programme. En général, on ne pourra jamais supposer que la soustraction de deux pointeurs est un entier (que les chevronnés du C me pardonnent, mais c'est une erreur très grave). En effet, ce type peut être insuffisant pour stocker des adresses (une machine peut avoir des adresses sur 64 bits et des données sur 32 bits). Pour résoudre ce problème, le fichier d'en-tête stdlib.h contient la définition du type à utiliser pour la différence de deux pointeurs. Ce type est nommé ptrdiff_t.

( http://cpp.developpez.com/cours/cpp/?page=page_6#LVI-H )
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2049967
unecrepe
Keep It Simple, Stupid
Posté le 18-01-2011 à 18:24:51  profilanswer
 

Merci pour le lien et le tuyau sur ptrdiff_t. Je conçois que les soustractions de pointeurs soient effectivement une source potentielle d'erreur sérieuse. Le type ptrdiff_t n'est pas renseigné dans K&R à la page de stdlib.h, à moins que je ne me fourvoie. C'est parce qu'il est apparu dans une version postérieure de stdlib ou bien K&R n'est pas exhaustif ?
 
J'en profite pour ajouter à tout hasard que l'on peut aussi comparer deux adresses :
 

Code :
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. int main(){
  4. int *pint, my_array[3] = { 0 ,  1 , 2 } ;
  5. pint = my_array ;
  6. pint ++ ;
  7. if (pint > my_array){
  8.  printf("Pointer comparisons DO work in C! \n" );
  9. }
  10. return 0 ;
  11. }


 
On ne peut en revanche pas multiplier un pointeur par quoi que ce soit, mais toutes les opérations définies sur le type int s'étendent naturellement à ptrdiff_t. Il faut par contre faire attention au fait que si je soustrais deux pointeurs du même type et que j'incrémente un pointeur d'un autre type de cette différence, il n'y a pas de conversions de taille. J'espère que ce morceau de code éclaire ce que je veux dire :
 

Code :
  1. char *pchar ;
  2. pchar = malloc( sizeof (char));
  3. printf("%p \n", pchar);
  4. pchar += (pint - my_array) ;
  5. printf("%p \n", pchar);


 
Merci à nouveau !
 
Ced'

mood
Publicité
Posté le 18-01-2011 à 18:24:51  profilanswer
 

n°2049990
gilou
Modérateur
Modzilla
Posté le 18-01-2011 à 19:40:07  profilanswer
 

unecrepe a écrit :

Merci pour le lien et le tuyau sur ptrdiff_t. Je conçois que les soustractions de pointeurs soient effectivement une source potentielle d'erreur sérieuse. Le type ptrdiff_t n'est pas renseigné dans K&R à la page de stdlib.h, à moins que je ne me fourvoie. C'est parce qu'il est apparu dans une version postérieure de stdlib ou bien K&R n'est pas exhaustif ?

Le K&R, c'est le C des cavernes, ça s'est quand même étoffé depuis.
Une remarque en passant:

Citation :

Pointer arithmetic cannot be performed on void pointers because the void type has no size, and thus the pointed address can not be added to, although gcc and other compilers will perform byte arithmetic on void* as a non-standard extension.


A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2050000
Un Program​meur
Posté le 18-01-2011 à 20:34:27  profilanswer
 

unecrepe a écrit :

Merci pour le lien et le tuyau sur ptrdiff_t. Je conçois que les soustractions de pointeurs soient effectivement une source potentielle d'erreur sérieuse. Le type ptrdiff_t n'est pas renseigné dans K&R à la page de stdlib.h, à moins que je ne me fourvoie. C'est parce qu'il est apparu dans une version postérieure de stdlib ou bien K&R n'est pas exhaustif ?

 

J'ai l'impression que tu te fourvoie (à moins que tu ais la première édition?): il est dans l'index de mon exemplaire qui référence la section 5.4 sur l'arithmétique des pointeurs, la section sur typedef où ptrdiff_t est donné comme un exemple et la section sur les opérateurs additifs dans la partie référence.  En passant, l'en-tête qui définit ptrdiff_t est stddef.h, pas stdlib.h.

 
Citation :

J'en profite pour ajouter à tout hasard que l'on peut aussi comparer deux adresses :[quotemsg]

 

Uniquement si elles pointent vers le même objet.

 

[quotemsg]Il faut par contre faire attention au fait que si je soustrais deux pointeurs du même type et que j'incrémente un pointeur d'un autre type de cette différence, il n'y a pas de conversions de taille.

 

L'arithmétique sur les pointeurs, c'est pour aider l'indexation.


Message édité par Un Programmeur le 18-01-2011 à 20:34:54

---------------
The truth is rarely pure and never simple (Oscar Wilde)

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] soustraire deux pointeurs

 

Sujets relatifs
Problème de la Socket en C sous linux[C] mmmmh... Un brillant codeur pourrait-il m'expliquer ?
[MATLAB] compiler un réseau de neuronne en C++[C++] Traitement d'image par pixel (bits)
FILE et Structure en C++[C++] Date limite d'utilisation d'un logiciel
[C] SurchargeVIsual Studio C# 2008 - option Type de la plateforme cible
Erreur de compilation C++Gestion d'évenement en C#
Plus de sujets relatifs à : [C] soustraire deux pointeurs


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR