【问题标题】:misunderstanding array pointers passed to functions in C误解 C 中传递给函数的数组指针
【发布时间】:2012-02-09 00:06:18
【问题描述】:

为什么函数中的打印语句与顶层打印不匹配?

#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 

【问题讨论】:

  • 你为什么使用 &foo 和 &ptr?
  • 我显然做错了...我要做的就是弄清楚如何将二维浮点数组传递给我的函数...
  • 阅读comp.lang.c FAQ的第6部分。
  • 这样做:void bar(float foo[5][])

标签: c arrays function


【解决方案1】:

您应该使用%p 打印指针。不是%f。此外,演员 (float**)mat 没有任何意义。

当你说&amp;((float**)mat)[0][0]时,你实际上是在mat的地址中寻找一个指针。如果指针比浮点数宽,您将从堆栈中的其他一些字节中读取,并且在您调用函数时它们可以更改。

【讨论】:

    【解决方案2】:

    其他几个人已经让你知道mat[0][0]float 类型和&amp;ptr[0][0]float * 类型之间的混淆,但你还有另一个更微妙的问题:数组不是指针。

    通常数组很像指针,但由于非常微妙的原因,float [][]float ** 不兼容,就像 float []float * 一样。

    在许多情况下(例如传递给函数),数组衰减指向其第一个元素的指针。因此,mat 衰减为&amp;mat[0]。数组T []的类型衰减为指针T *,这意味着mat的类型衰减为(以及&amp;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 |
                +-----+     +-----+-----+
    

    这些类型从左到右依次是:pointer-to-pointer-to-float、array-of-pointers-to-float、array-of-arrays-of-floats 和指向floats 的数组的指针。 &amp;float[0] 的地址,转换为 float **,被解除引用两次作为指针,即使只有一个指针 - 指向 float[0] 的指针(因此,数组的其余部分)。你通过这个获得的任何价值都是垃圾。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多