为什么这里不能进行类型转换??
#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-'
;这是什么意思?
错误意味着编译器无法推断两个操作数的通用类型,其中一个具有类型float *
,另一个具有类型int *
。这些类型之间没有隐式转换。
但是在任何情况下,程序都具有未定义的行为,因为至少您不能减去两个指针,这些指针不指向同一数组的元素,也不指向同一数组的最后一个元素之后的内存。
从C标准(6.5.6加法运算符)
9当减去两个指针时,两个指针都应指向相同的数组对象,或者在数组的最后一个元素之后宾语;结果是两者的下标不同数组元素。
并且在函数%d
中为提供的参数使用不正确的转换说明符(例如,带有指针的printf
,也将调用未定义的行为。
来自C标准(7.21.6.1 fprintf函数)
9如果转换规范无效,则行为是275)如果任何参数不是正确的类型,相应的转换规范,其行为是不确定的。
我想您要减去指针所指向的实际值。当您对int
和float
进行操作时,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
您不能减去这样的指针并在标准C中获得有意义的结果。
每6.5.6 Additive operators, paragraph 9 of the C11 standard:
当减去两个指针时,两个指针都应指向同一数组对象的元素,或者指向数组对象的最后一个元素;结果是两个数组元素的下标不同。
在这种情况下,单个int
或float
变量被视为大小为1
的数组。
已给出
int x = 5;
float y = 7.0;
float *p = &y;
int *q = &x;
尝试计算值p - q
导致未定义的行为。
在以下情况下,行为未定义:
...
- 减去不指向或不指向同一数组对象的指针
但是,这样的代码可能不会引起问题,因为它只是减去两个整数值(尽管我还没有彻底检查过,但结果不一定有意义:
int x = 5;
float y = 7.0;
float *p = &y;
int *q = &x;
intptr_t diff = ( intptr_t ) p - ( intptr_t ) q;
编辑:正如注释中所指出的,减去两个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));