为什么类型转换在这里不起作用..?
#include<stdio.h>
int main(){
int x = 5;
float y = 7.0;
float *p = &y;
int *q = &x;
printf("p is %dnq is %dnp - 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 如果转换规范无效,则行为为 undefined.275(如果任何参数不是 相应的转换规范,行为未定义。
我想你想减去指针指向的实际值。 C 在float
和int
上操作时隐式将int
转换为float
。
此外,您的程序也存在一些问题,例如
-
不使用
%f
类型说明符打印指针float
-
不使用
*
运算符访问指针值。
这是您的程序,正在工作:
#include <stdio.h>
int main()
{
int x = 5;
float y = 7.0;
float *p = &y;
int *q = &x;
printf("p is %fnq is %dnp - 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 添加剂操作员,C11 标准第 9 段:
当减去两个指针时,两个指针都应指向同一数组对象的元素,或者一个指针指向数组对象的最后一个元素;结果是两个数组元素的下标之差。
在这种情况下,单个int
或float
变量被认为是大小1
数组。
所以给定
int x = 5;
float y = 7.0;
float *p = &y;
int *q = &x;
尝试计算值p - q
会导致未定义的行为。
根据J.2 未定义的行为:
在以下情况下未定义该行为:
。
- 不指向或刚好指向同一数组对象的指针将被减去
但是,像这样的代码可能不会引起问题,因为它只是减去两个整数值(尽管我没有彻底检查(,但结果不一定有意义:
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 %pnq is %pnp - q is %ldn", p, q, ((intptr_t)p - (intptr_t)q));
原答案:
这意味着没有为混合类型的指针定义减号运算符。如果要减去这两个指针,例如要查找它们之间的空间量,更好的选择是将它们都强制转换为指针void*
。
此外,您应该使用%p
说明符而不是%d
打印指针值。
例如:
printf("p is %pnq is %pnp - q is %ldn", p, q, ((void*)p - (void*)q));