0

I have these 2 structs:

#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;

and I wrote this function:

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

I have a couple of questions:

  1. Why is it illegal? If I change the function to: {pAttr_Element* getXmlAttr....} it works but I don't understand why.

Inside my struct I have a pointer to an array, where every cell is a pointer of type pAttr_Element right? Or it's not a pointer to an array? I'm lost :(

  1. Why is it not working if I change the function to: Attr_Element getXmlAttrArray(..)? When I return: node->attr_arr what is the return type?

  2. How can I change the struct in order to return a pointer to an array Of pAttr_elements?

Thank you!

4

3 回答 3

1

attr_arr字段是 的数组pAttr_Element,而不是pAttr_Element。所以你不能把它作为pAttr_Element.
在 C 中,数组不是指针,但在许多情况下它们会衰减为指针。当您写入return node->attr_arr时,数组衰减为一个指针,然后返回该指针。

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

于 2012-08-05T07:56:16.117 回答
0

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

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

理解存储类分类器typedef非常重要。对于宏定义可以实现的功能,它不是一个方便的名称。当您可以创建一个非常复杂的类型并使用一个简单的名称来引用它时,真正的力量就会得到回报。typedef

例子 :

typedef void (*ptr_to_fun)(char *p)

该语句表示, 可以从现在调用指向以 char 指针为参数且不返回任何内容的函数的指针 ptr_to_fun

所以我可以有这样的陈述

ptr_to_fun ptr = my_fun

但有点遗憾的是,大多数情况下,typedef都是用来隐藏struct关键字的。在我看来,这是一种不好的做法,因为它完成的很少,但会让新的 c 程序员感到困惑。(这可能是因为面向对象的人群压倒性地抱怨语法胜过语义。)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一种实际上是 type 的新类型struct xml_Element *

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

你的功能是

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

所以它会返回pAttr_Element类型。你已经typedef编辑了它。所以它实际上代表类型struct attrElem *

现在你的初始结构有pAttr_Element数组。所以你要做的是返回一个数组。你不能退回这个。您可以返回指向该数组的指针。现在你的数组是 type 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 字节宽的寄存器,可以保存本机指针变量。就是这样了。如果要返回数组,则必须返回大块内存的副本。机器无法有效地完成。但是如果你只是返回一个指向它的指针,那么你可以很容易地从调用者那里读取返回的指针。

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

于 2012-08-05T12:25:45.603 回答
-3

pAttr_Element 是指向 Attr_Element 的指针。

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

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

于 2012-08-05T07:56:36.460 回答