返回值类型在C中不匹配

时间:2012-08-05 07:48:54

标签: c arrays pointers struct typedef

我有这两种结构:

#define M 100
#define N 100

typedef struct xml_Element {
pData_Element           data;
pAttr_Element           attr_arr[M];
struct xml_Element      *parent;
struct xml_Element      *children[N];
int                     depth;
int                     num_of_children;
int                     num_of_attr;
} Xml_Element,*pXml_Element;

  typedef struct attrElem {
      char *attrName;
      char *attrValue;
   }Attr_Element,*pAttr_Element;

我写了这个函数:

pAttr_Element getXmlAttrArray(pXml_Element node) {
    return node->attr_arr;
}

我有几个问题:

  1. 为什么这是非法的?如果我将函数更改为:{pAttr_Element* getXmlAttr....}它可以工作,但我不明白为什么。
  2. 在我的struct中,我有一个指向数组的指针,其中每个单元格都是pAttr_Element类型的指针吗?或者它不是指向数组的指针?我输了:(

    1. 如果我将功能更改为Attr_Element getXmlAttrArray(..),为什么它不起作用? 当我返回时:node->attr_arr什么是返回类型?

    2. 如何更改结构以返回指向pAttr_elements数组的指针?

    3. 谢谢!

3 个答案:

答案 0 :(得分:1)

attr_arr字段是pAttr_Element的数组,而不是pAttr_Element。因此,您无法将其作为pAttr_Element返回 在C中,数组不是指针,但在许多情况下它们会衰减为指针。当您编写return node->attr_arr时,数组会衰减为指针,然后返回该指针。

xml_Element结构不包含指向pAttr_Element数组的指针。它实际上包含100个这样的结构。

答案 1 :(得分:0)

关于编码风格的一些想法:

这是对typedef含义的常见误解。人们使用它就像使用宏定义一样。

了解typedef 存储类分类器非常重要。它不是宏定义可以实现的方便的名称。 typedef的真正威力是值得的,当你可以用一个简单的名称来创建一个非常复杂的类型来引用它时。

示例:

typedef void (*ptr_to_fun)(char *p)

这句话说指向函数的指针,该函数将指向char的指针作为参数并且不返回任何内容,可以从现在开始调用ptr_to_fun

所以我可以有像

这样的陈述
ptr_to_fun ptr = my_fun

但是大多数情况typedef用来隐藏struct关键字有点遗憾。在我看来,这是一种不好的做法,因为它实现了很少但却让新的程序员感到困惑。 (可能是因为压倒性的面向对象的人群更多地抱怨语法超过语义。)C可以很容易地面向对象。看看linux内核代码。它有多重继承和东西。他们不需要隐藏struct关键字。 typedef并不意味着隐藏struct关键字。它有更重要的应用。

您的代码是......

#define M 100
#define N 100

typedef struct xml_Element {
pData_Element           data;
pAttr_Element           attr_arr[M];
struct xml_Element      *parent;
struct xml_Element      *children[N];
int                     depth;
int                     num_of_children;
int                     num_of_attr;
} Xml_Element,*pXml_Element;

所以它说xml_Element是一种实际上struct xml_Element的新类型。此外,pxml_Element是一种新类型,实际上是struct xml_Element *类型。

现在让我们来解决你的问题。

你的职能是

pAttr_Element getXmlAttrArray(pXml_Element node) {
    return node->attr_arr;
}

因此它将返回pAttr_Element类型。你有typedef编辑它。所以它实际上代表struct attrElem *类型。

现在您的初始结构有pAttr_Element数组。所以你要做的就是返回一个数组。你不能归还这个。你可以返回一个指向这个数组的指针。现在您的数组类型为struct attr_Elem *pAttr_Elem[M]。它是一个指向struct attr_elem 的指针数组。因此,与指向此数组的指针兼容的返回类型将类似于' struct attr_Elem ** pAttr_Elem [M] . after typedef it will be like 'pAttr_Element *

在c中无法返回数组。虽然数组可能包含指针(如你的情况)。但那没关系。你不能返回一个数组。

想想为什么c不允许这样做。

一个函数可以通过两种方式返回东西。它可以使用指定用于保存返回值的寄存器。它也可以操纵帧指针并在堆栈中推送东西,这些东西在它的框架被遗忘之后可以访问(但不是标准的练习)。

在x86_64架构中,你有8字节宽的寄存器,可以保存本机指针变量。这就是它。如果要返回数组,则必须返回大块内存的副本。这不能由机器有效地完成。但是如果你只是返回一个指向它的指针,那么你可以轻松地从调用者那里读回返回的指针。

智慧的最后一句话,数组是数组,指针是指针。在某些情况下,它们是可以互换的,但如果不考虑上下文,则认为它们是相同的是错误的。

答案 2 :(得分:-3)

pAttr_Element是指向Attr_Element的指针。

在C中,数组是一个指针。

attr_arr是一个pAttr_Element数组,这意味着它是指向一堆pAttr_Elements的指针,换句话说,它是一个指向Attr_Element指针的指针。