【问题标题】:Why can't int (*p)[] be used as an argument for C function?为什么不能将 int (*p)[] 用作 C 函数的参数?
【发布时间】:2019-02-27 03:16:47
【问题描述】:
#include <stdio.h>
void print(int (*p)[3]);
int main(void)
{
    int a[3] = {1, 2, 3};
    print(&a);

    return 0;
}
void print(int (*p)[3])
{
    for (int i = 0; i < sizeof(*p) / sizeof(**p); i++)
        printf("%d\n", (*p)[i]);
}

我写了一个 C 函数。见上文。

它可以打印数组中的所有元素。

有一件事不是那么完美:数组元素的数量似乎是预先知道的。

所以我做了一些修改,希望使功能通用:

#include <stdio.h>
void print(int (*p)[]);
int main(void)
{
    int a[3] = {1, 2, 3};
    print(&a);

    return 0;
}
void print(int (*p)[])
{
    for (int i = 0; i < sizeof(*p) / sizeof(**p); i++)
        printf("%d\n", (*p)[i]);
}

在函数中,p是指向整个数组的指针。

但是编译失败。

为什么不能将 int (*p)[] 用作 C 函数的参数?

【问题讨论】:

  • 只使用指针。但是你需要知道元素的数量或者有某种终结符。
  • 因为&amp;a的类型是int (*)[3],所以类型本身包含了数组的大小,没有大小就不能有数组。
  • “问题”的“正常”解决方案是将指针传递给第一个元素元素的数量作为参数。
  • @Someprogrammerdude 但是你可以拥有指向未知大小的数组的指针
  • 来自编译器的诊断信息必须逐字复制到问题中,否则这对未来的读者没有用处。

标签: c arrays function arguments sizeof


【解决方案1】:

int (*p)[] 可以用作函数的参数。给出错误的代码部分是sizeof *p,这显然是不可能的,因为*p 的类型是int[],这是一个不完整的类型,因此没有已知的大小。

为了让函数知道数组的长度,你必须设计一种方法让函数接收这个信息。选项包括:

  • 你在原始代码中做了什么。
  • 将长度作为另一个参数传递。
  • 包括长度作为数组元素。
  • 在数组末尾有一个标记值。

最常见的习惯用法是传递int *p, size_t n,在没有给出维度的情况下使用指向数组的指针并没有真正获得任何好处。

【讨论】:

    【解决方案2】:

    问题是int [] 是一个不完整的类型,因为数组没有定义大小,因此它的sizeof 不能被采用。

    在“现代 C”(即近 2 年)中,您可以为此使用可变长度数组 - 您可以将大小作为参数传递,然后传递数组:

    #include <stdio.h>
    #include <stdlib.h>
    
    void print(size_t n, int (*p)[*]);
    
    int main(void) {
        int a[3] = {1, 2, 3};
        print(3, &a);
    }
    
    void print(size_t n, int (*p)[n]) {
        for (size_t i = 0; i < sizeof(*p) / sizeof(**p); i++)
            printf("%d\n", (*p)[i]);
    }
    

    当然这对你没有任何好处,因为sizeof *p / sizeof **pp 将是...n。因此我们不妨使用

    void print(size_t n, int p[n]) {
        for (size_t i = 0; i < p; i++)
            printf("%d\n", p[i]);
    }
    

    打字更少。

    【讨论】:

      【解决方案3】:

      简短回答:int (*p)[] 不能用作参数,并且让函数神奇地知道数组大小,因为标准是这样说的。

      更长的答案:

      int (*p)[] 是一个指向数组的指针,但数组没有定义的大小。所以通过查看数组,不可能进行指针运算,计算 p 所指向的东西的大小等等。

      您没有数组数组,因此您不需要int (*p)[]。你有一个 int 数组,所以 int *pint p[] 就足够了。这并不能解决知道print 中数组大小的问题。为此,您基本上有 3 个选项

      1. 对函数中的值进行硬编码
      2. 在数组中放置一个标记值来标记结束
      3. 将大小作为单独的参数传递,如下所示:

        无效打印(int n,int p[n])

      请记住,无论您使用哪种方法,数组的参数传递将始终在幕后使用指针,因此您不能使用sizeof(p) 来计算数组的大小。 sizeof 在这些情况下总是会返回指针的大小

      【讨论】:

      • @M.M 是的,你是对的,它可以用作参数,但不是 OP 使用它的方式。应编辑答案以反映这一点
      猜你喜欢
      • 2013-08-31
      • 1970-01-01
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      • 2020-01-26
      • 2017-08-31
      • 2011-10-27
      • 1970-01-01
      相关资源
      最近更新 更多