我有这两种结构:
#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;
}
我有几个问题:
{pAttr_Element* getXmlAttr....}
它可以工作,但我不明白为什么。在我的struct中,我有一个指向数组的指针,其中每个单元格都是pAttr_Element类型的指针吗?或者它不是指向数组的指针?我输了:(
如果我将功能更改为Attr_Element getXmlAttrArray(..)
,为什么它不起作用?
当我返回时:node->attr_arr
什么是返回类型?
如何更改结构以返回指向pAttr_elements数组的指针?
谢谢!
答案 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指针的指针。