为什么函数中的print语句不匹配顶级打印?
#include<stdio.h>
#include <stdlib.h>
#include<math.h>
void bar(float **foo)
{
printf(" &foo[0][0] %f \n", &foo[0][0]);
}
int main()
{
float mat[5][5], **ptr;
mat[0][0] = 3.0f;
ptr = (float **)mat;
printf(" mat[0][0] %f \n", mat[0][0]);
printf(" &ptr[0][0] %f \n", &ptr[0][0]);
bar(ptr);
}
结果:
mat[0][0] 3.000000
&ptr[0][0] 3.000000
&foo[0][0] -0.005548
答案 0 :(得分:1)
您应该使用%p
打印指针。不是%f
。此外,演员(float**)mat
没有任何意义。
当您说&((float**)mat)[0][0]
时,您实际上在mat
的地址中寻找指针。如果指针比浮点宽,你将从堆栈中的其他一些字节读取,并且当你调用函数时它们可以改变。
答案 1 :(得分:1)
其他几个人让你感到mat[0][0]
类型float
和&ptr[0][0]
类型float *
之间的混淆,但你还有另一个更微妙的问题: ARRAYS不是指针。
通常数组很像指针,但由于非常微妙的原因,float [][]
与float **
float []
和float *
的方式不兼容。
在许多上下文中(例如传递给函数),数组衰减到指向其第一个元素的指针。因此,mat
衰减到&mat[0]
。数组T []
的类型衰减为指针T *
,这意味着类型mat
衰减到(&mat[0]
的类型)是float (*)[]
- 也就是说,指向一个固定大小的数组。
以下是float *
和float[]
:
float * float[]
+-----+ +-----+-----+
| ptr | --> | 0.0 | 1.0 |
+-----+ +-----+-----+
现在,这是float **
和float[][]
之间的差异:
float ** float *[] float[][] float (*)[]
+-----+ +-----+ +-----+-----+ +-----+ (imagine this
| ptr | --> | ptr | --> | 0.0 | 1.0 | <-- | ptr | pointing to
+-----+ +-----+ +-----+-----+ +-----+ the 0.0 cell)
| ptr | --> | 2.0 | 3.0 |
+-----+ +-----+-----+
这些类型是从左到右,指针到指针 - float
,指针数组到 - float
,数组 - 数组 - {{ 1}} s和float
的指向数组的指针。转换为float
的{{1}}地址被取消引用两次作为指针,即使只有一个指针 - 指向&float[0]
的指针(因此,阵列的其余部分)。你通过它获得的任何价值都是垃圾。