C - 返回一个指向二维数组的指针

Dan*_*Bak 0 c arrays

我正在尝试为结构的二维数组编写吸气剂。我尝试了各种解决方案,而我的 IDE 抱怨所有这些。

static history_t history[3][6];

history_t **get_history(){
    return history;
};
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这是正确的。数组数组是指向指针的指针。但是,我的 IDE 抱怨指针类型不兼容。我一直无法找到任何历史签名和访问器的组合,这使我能够返回任何有用的东西。

这在 C 中是可能的吗?

warning: returning 'history_t (*)[6]' {aka 'struct <anonymous> (*)[6]'} from a function with incompatible return type 'history_t **' {aka 'struct <anonymous> **'} [-Wincompatible-pointer-types]
     return history;
Run Code Online (Sandbox Code Playgroud)

所以,我的函数不是返回history_t **,而是history_t *[6]。但是,重新定义要返回的签名history_t*[6]也不起作用。

小智 7

关于数组、多维数组和指针有很多误解。我将尝试解释它们之间的差异,然后回答问题。下面,T表示类型名称。

T x[3]; /* the type of x is "array of T" */
Run Code Online (Sandbox Code Playgroud)

x是一个数组。它具有三个要素。每个元素都是一个T.

T *x[3]; /* the type of x is "array of pointer to T" */
Run Code Online (Sandbox Code Playgroud)

x是一个数组。它具有三个要素。每个元素都是一个pointer-to-T.

T (*x)[3]; /* the type of x is "pointer to an array of three Ts" */
Run Code Online (Sandbox Code Playgroud)

x是一个指针。它指向一个数组。该数组具有三个元素。每个元素是一个T

T x[3][6]; /* the type of x is "array of array of six Ts" */
Run Code Online (Sandbox Code Playgroud)

x是一个数组。它具有三个要素。每个元素都是一个包含 6 个Ts的数组。因此x是一个多维数组,或者更准确地说,是一个二维数组,一个 3×6 的 T 数组。

现在,C 中有一条非常重要的规则:类型为“T 的数组”的表达式被转换为指向数组对象初始元素的“指向 T 的指针”,除非它是sizeofor 地址的操作数运营商。所以,

void f(T*);

void g(void)
{
    T x[3];
    /* ... */
    f(x); /* equivalent to f(&x[0]); */
}
Run Code Online (Sandbox Code Playgroud)

指向数组第一个元素的指针xf(x)上面的函数调用中作为参数传递。数组通过。在 C 中无法将数组作为参数直接传递给函数(可以通过将数组包装在结构中来间接完成)。从函数返回具有相同的语义:不能从函数返回数组(除非它被包装在结构中):

T *f(void)
{
    static T x[3];
    /* ... */
    return x; /* Equivalent to return &x[0]; */
}
Run Code Online (Sandbox Code Playgroud)

x返回指向数组初始元素的指针。

你的数组被定义为

static history_t history[3][6]; /* static is not relevant in this discussion */ 
Run Code Online (Sandbox Code Playgroud)

类型history是“六个数组的数组history_t”。history_t如上所述,当它从函数返回时,它将被转换为“指向 6 个数组的指针”。x类型为“指向 6 个数组的指针”的对象history_t定义为

history_t (*x)[6];
Run Code Online (Sandbox Code Playgroud)

要声明返回该类型的函数,x由函数声明符替换。

history_t (*get_history())[6]; /* function returning pointer to array of six history_ts */
Run Code Online (Sandbox Code Playgroud)

The 的()优先级高于*,因此不需要括号get_history()。要定义这样的函数,需要添加函数体:

static history_t history[3][6];

history_t (*get_history())[6]
{
    /* ... */
    return history;
}
Run Code Online (Sandbox Code Playgroud)