【问题标题】:Decayed multidimensional array return from function从函数返回的衰减多维数组
【发布时间】:2010-03-27 11:13:50
【问题描述】:

(gcc) Multi-Dim Array or Double Pointer for Warning-free Compile 相关,有没有办法从函数中返回所谓的“衰减数组指针”?总之(假设 2 dim 数组)返回int (*a)[5] 格式而不是int** 格式?

据我所知,当返回的int** 指针被发送到另一个等待(int*)[] 参数的函数时,它无法正常工作。

【问题讨论】:

  • 有机会看到一些代码吗?
  • 请注意,采用int*[] 的函数实际上是采用int**。问题是二维数组不是int**,也就是说,从一个函数返回二维数组是正确的(因为它表示内部数据)但不能用作函数void ( f *a[] )的参数>

标签: c arrays pointers


【解决方案1】:

是的,但语法看起来不太好

int(*f())[5] {
  static int a[1][5] = { { 1, 2, 3, 4, 5 } };
  return a;
}

基本上,它只是将您的 a 替换为 f()(一个函数)。使用 typedef 它变得更具可读性

typedef int inner_array[5];

inner_array *f() {
  // like before ...
}

注意,要表示抽象类型,没有名字,你需要写int(*)[5]。也就是说,您只需删除名称。 (int*)[5] 语法无效。

你是对的——你不能返回int**,因为这意味着你有一个指向指针的指针。使用f()[A][B] 访问将从返回的指针给出的地址读取,然后依次从该指针给出的地址再次读取。但实际上,您返回的数组指针仅指向一个内存块,因此如果您要进行两次间接访问,您会尝试将数据重新解释为指针。

相反,如果您返回int(*)[5] 并执行f()[A][B],您将不会从指针返回的地址中读取任何值。相反,您只需将偏移量A 添加到地址,并将类型从int(*)[5] 调整为int[5] 以在调整后的地址处拥有一个引用内存的数组。然后下一个索引将再次调整 B 并且由于它在 int* 上运行(在数组衰减之后),不再在数组指针上,然后它将读取存储在调整后地址的内容,最终产生int。这是非数组指针和数组指针的一个重要区别。

如果你愿意,你可以试验一下。考虑这两个 sn-ps。一个可能会崩溃,但另一个可能不会(但两者都会产生未定义的行为,因此不应在实际程序中这样做)

int *pi = 0; 
int(*pa)[5] = 0;

int i = *pi; // read int stored at null-pointer address!
int *a = *pa; // does not read any data from address, just adjusts the type!

【讨论】:

    【解决方案2】:
    struct thing {
       int A[10][10];
    };
    
    typedef struct thing thing_t;
    
    thing_t f1(void) {
        thing_t t;
        ...
        return t;
    }
    thing_t * f1(void) {
       thing_t * tp;
       ...
       return tp;
    }
    

    不过,你真的是走错路了。

    【讨论】:

      猜你喜欢
      • 2017-03-06
      • 2012-09-22
      • 2014-07-23
      • 1970-01-01
      • 2018-01-05
      • 2018-09-25
      • 1970-01-01
      • 2012-01-26
      相关资源
      最近更新 更多