误解了传递给C中函数的数组指针

时间:2012-02-09 00:06:19

标签: c arrays function

为什么函数中的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 

2 个答案:

答案 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]的指针(因此,阵列的其余部分)。你通过它获得的任何价值都是垃圾。