用于返回多维数组的C函数的签名

时间:2017-12-04 02:37:59

标签: c multidimensional-array syntax

如果我有:

char* buffer[8][8];

在同一个文件中,我想编写一个返回此缓冲区的函数,该函数的签名是什么样的?

的情况下
char* buffer[8];

我可以写

char** get_buff() {
    return buffer;
}

但在这种情况下,我无法尊重多维数组。 C编译器会告诉我

char* buffer[8][8]

有类型

char * (*)[8]

问题是它提供的类型在签名中不是有效的语法,所以我不知道它期望去那里。签名应该是什么样的?

3 个答案:

答案 0 :(得分:1)

您可以使用typedef。这编译:

typedef char* (*tp)[8];
char* buffer[8][8];
tp get_buff()
{
    return buffer;
}

int main()
{
}

tp的类型是指向char的8指针数组的指针。所以这会返回一个指向缓冲区第一个元素的指针。缓冲区的每个元素都有8个指向char的指针的类型数组。

请注意,缓冲区的类型实际上是8个指向char的8个数组的数组。但由于数组指针衰减,它会衰减到指向第一个元素的指针,这是tp的类型。

答案 1 :(得分:1)

由于C语言的限制,您无法从函数返回数组。您只能返回指向数组的指针。

最简单的方法是使用指向第一个元素的指针。您的案例中的第一个元素是char*类型,因此指向该元素的指针将为char**。请注意,指针指针语法与数组无关。

// my recommended solution
char** get_buff (void) 
{
  return &buffer[0][0];
}

如果您希望返回指向整个数组的指针,它会变得复杂得多。高级主题如下。

指向char* buffer[8][8];类型数组的数组指针声明为char* (*ptr)[8][8]。这是指向整个数组的指针。也可以仅使用指向第一个元素的指针char* (*)[8]

如果你想返回一个数组指针,那么它的C语法真的太可怕了:

char* (*get_buff(void))[8][8]
{
  return &buffer;  // return address of array
}

这完全不可读。我们应该做些什么来避免这种C疯狂语法,就是对数组类型使用typedef,然后返回一个指向这种类型的指针:

typedef char* c_arr_8x8 [8][8];

c_arr_8x8* get_buff (void)
{
  return &buffer;
}

或者,通过参数返回指针是完全正常的,尽管我们必须通过指针传递数组指针:

void get_buff (char* (**buf)[8][8])
{
  *buf = &buffer;
}

答案 2 :(得分:0)

函数无法返回数组。在大多数情况下,数组类型的表达式会自动转换为数组第一个元素的指针,这可能正是您想要的(除非您想要返回缓冲区的副本,这是一个整个不同的故事)。

因此函数中的return语句应如下所示:

 return buffer;

类型char * (*)[8]是正确的,你绝对可以用它写一个签名。起初并不是太明显,但没有什么可怕的复杂,真的:

 char *(*get_buff())[8] {
     return buffer;
 }

经验法则是:如果某个类型中包含单个顶级(*),则可以在*之后立即粘贴您的函数名称和参数以获取签名。像这样:

      char * ( *   )[8]
                 ^
                 |
             get_buffer()

多级指针也是如此:函数名称位于*中的最后一个(*****....***)之后。

当然你可以使用typedef来简化这个问题。