0
votes

Pourquoi une erreur est générée lorsque je tape jette un pointeur et soustrayez-le?

Pourquoi ne peut-il pas faire fonctionner ici ..

#include<stdio.h>
int main(){
   int x = 5;
   float y = 7.0;
   float *p = &y;
   int *q = &x;
   printf("p is %d\nq is %d\np - q is %d", p, q, (p - q));
   return 0;  
  }


4 commentaires

Cela signifie que vous ne pouvez pas soustraire un pointeur sur int à partir d'un pointeur sur float car ils pointent sur différents types. En outre, quel est le point de les soustraire quand même?


Vous n'avez pas de typast


Les comparaisons du pointeur ne sont valides que lorsque les deux pointeurs sont des pointeurs sur le même objet ou un élément au-delà de l'extrémité de même objet , dans laquelle un objet peut être un tableau.


Qu'essayez-vous de faire?


4 Réponses :


0
votes

EDIT: Comme il a été signalé dans les commentaires, soustrayer deux points nuls * NOV * n'est pas approprié standard C. Si vous souhaitez soustraire deux pointeurs pour trouver la distance entre eux, la bonne approche consiste à les jeter à un entier de taille appropriée , puis faire de l'arithmétique entier.

E.g.:

printf ("P est% p \ nq est% p \ np - q est% ld \ n", p, q, ((intptr_t) p - (intptr_t) q));

Réponse originale:

Cela signifie que l'opérateur moins n'est pas défini pour les types de pointeurs mixtes. Si vous souhaitez soustraire ces deux pointeurs, par exemple pour trouver la quantité d'espace entre eux, la meilleure option serait de les jeter à la fois à Void * Pointants.

En outre, vous devez imprimer des valeurs de pointeur avec le spécificateur % p au lieu de % d .

E.g.:

printf ("p est% p \ nq est% p \ np - q est% ld \ n", p, q, (vide *) p - (vide *) q));


6 commentaires

La meilleure option serait de les jeter à la fois aux points nuls * Pointeurs. NO . Vous ne pouvez pas faire du pointeur arithmétique sur void * des pointeurs. Certaines implémentations offrent une extension non portable.


Je ne pense pas que vous soyez autorisé à soustraire deux void des pointeurs de la norme C, bien que je pense que GCC le permet comme une extension.


Le pointeur arithmétique sur vide * est une extension non standard (introduite par GCC), donc char * serait préférable pour le pointeur arithmétique. (Il s'agit toujours d'un comportement techniquement indéfini de soustraire des pointeurs à différents objets, sauf dans le même tableau, mais il est probable qu'il suffit d'afficher la différence de valeurs d'adresse plutôt que d'exploser votre ordinateur sur la plupart des implémentations.)


@Ian Abbott, si l'on veut traiter les pointeurs comme des chiffres, les jeter dans des chiffres ( uintptr_t ) a plus de sens pour moi que de les jeter dans char * .


Techniquement, l'argument correspondant à % p doit être un vide * , plutôt qu'un int * ou un flotteur * .


@ikegami ou plutôt intPTR_T puisque le résultat de la soustraction pourrait être négatif.



3
votes

L'erreur signifie que le compilateur est incapable de déduire le type commun de deux opérandes dont l'un a le type float * et d'autres int * . Il n'y a pas de conversion implicite entre ces types.

Mais dans tous les cas, le programme a un comportement indéfini car au moins vous ne pouvez pas soustraire deux pointeurs qui ne pointent pas les éléments du même réseau ou à une mémoire après le dernier élément du même tableau.

à partir de la norme C (6.5.6 Opérateurs additifs)

9 Lorsque deux pointeurs sont soustraits, les deux doivent pointer vers des éléments de le même objet de tableau, ou un passé le dernier élément de la matrice objet; Le résultat est la différence des sous-domescents des deux Éléments de tableau.

et en utilisant des spécificateurs de conversion incorrects (comme par exemple % d avec un pointeur) pour les arguments fournis dans la fonction printf invoque également un comportement indéfini.

de la norme C (7.21.6.1 la fonction FPRRTINF)

9 Si une spécification de conversion n'est pas valide, le comportement est indéfini.275) Si un argument n'est pas le type correct pour le Spécification de conversion correspondante, le comportement n'est indéfini.


0 commentaires

1
votes

Je suppose que vous souhaitez soustraire les valeurs réelles que vos pointeurs montrent. C convertit int sur float implicitement lorsque vous utilisez float et int .

aussi, vous programmez. a des problèmes comme

  • n'utilise pas % f Spécificateur de type pour imprimer float Pointeur

  • n'utilise pas l'opérateur * pour accéder aux valeurs du pointeur.

    Voici votre programme, fonctionnant: xxx

    avec les sorties: xxx


0 commentaires

1
votes

Vous ne pouvez pas soustraire les pointeurs comme ça et obtenir un résultat significatif dans la norme C.

par 6.5.6 Opérateurs additifs , paragraphe 9 de la norme C11 :

Lorsque deux pointeurs sont soustraits, les deux doivent pointer vers des éléments du même objet de tableau, ou un autre élément du dernier élément de l'objet réseau; Le résultat est la différence des indignes des deux éléments de tableau.

Dans ce cas, un seul int ou float est considéré comme une matrice de taille 1 .

donné xxx

tentative de calcul de la valeur p - q entraîne un comportement non défini.

par J.2 comportement non défini :

Le comportement n'est pas défini dans les circonstances suivantes:

...

  • Les pointeurs qui ne font pas partie, ni juste au-delà, le même objet de tableau sont soustraits

    Cependant, le code comme celui-ci ne causera probablement pas de problèmes car il s'agit simplement de soustraire deux valeurs entières (bien que je n'ai pas vérifié à fond), mais le résultat ne doit pas nécessairement être significatif: xxx


0 commentaires