为什么当我键入类型转换指针并减去它时会生成错误?

问题描述 投票:0回答:4

为什么这里不能进行类型转换??

#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;  
  }

我收到此错误invalid operands of types 'float*' and 'int*' to binary 'operator-';这是什么意思?

c pointers casting implicit-conversion
4个回答
3
投票

错误意味着编译器无法推断两个操作数的通用类型,其中一个具有类型float *,另一个具有类型int *。这些类型之间没有隐式转换。

但是在任何情况下,程序都具有未定义的行为,因为至少您不能减去两个指针,这些指针不指向同一数组的元素,也不指向同一数组的最后一个元素之后的内存。

从C标准(6.5.6加法运算符)

9当减去两个指针时,两个指针都应指向相同的数组对象,或者在数组的最后一个元素之后宾语;结果是两者的下标不同数组元素。

并且在函数%d中为提供的参数使用不正确的转换说明符(例如,带有指针的printf,也将调用未定义的行为。

来自C标准(7.21.6.1 fprintf函数)

9如果转换规范无效,则行为是275)如果任何参数不是正确的类型,相应的转换规范,其行为是不确定的。


0
投票

我想您要减去指针所指向的实际值。当您对intfloat进行操作时,C会将float隐式转换为int

此外,您的程序也有一些问题,例如

  • 不使用%f类型说明符来打印float指针

  • 不使用*运算符访问指针值。

这是您的程序,正在运行:

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

具有输出:

p is 7.000000
q is 5
p - q is 2.000000

0
投票

您不能减去这样的指针并在标准C中获得有意义的结果。

6.5.6 Additive operators, paragraph 9 of the C11 standard

当减去两个指针时,两个指针都应指向同一数组对象的元素,或者指向数组对象的最后一个元素;结果是两个数组元素的下标不同。

在这种情况下,单个intfloat变量被视为大小为1的数组。

已给出

int x = 5;
float y = 7.0;
float *p = &y;
int *q = &x;

尝试计算值p - q导致未定义的行为。

J.2 Undefined behavior

在以下情况下,行为未定义:

...

  • 减去不指向或不指向同一数组对象的指针

但是,这样的代码可能不会引起问题,因为它只是减去两个整数值(尽管我还没有彻底检查过,但结果不一定有意义:

int x = 5;
float y = 7.0;
float *p = &y;
int *q = &x;

intptr_t diff = ( intptr_t ) p - ( intptr_t ) q;

-1
投票

编辑:正如注释中所指出的,减去两个void *指针不是正确的标准C。如果要减去两个指针以查找它们之间的距离,正确的方法是将它们转换为适当大小的整数,然后进行整数运算。

例如:

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

原始答案:

这意味着没有为混合类型的指针定义减号运算符。如果要减去这两个指针,例如查找它们之间的空间量,更好的选择是将它们都转换为void*指针。

此外,您应该使用%p指定符而不是%d打印指针值。

例如:

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

© www.soinside.com 2019 - 2024. All rights reserved.