我现在正在使用这段代码,而且工作正常,但实际上让我头疼不已。它使用Flexible Array Member(FAM)又名Struct Hack。既然C99有可能使用可变长度数组(VLA),我想知道如何才能利用这一部分?
typedef struct nO
{
int oper; /* some operator */
int nops; /* number of args */
struct nO *ptn[1]; /* expansible array <=== HERE */
} nodoOper;
nodoOper *operator(int o, int n, ...)
{
va_list ap;
nodoOper *tn;
size_t tam;
int i;
tam = sizeof(nodoOper) + (n - 1) * sizeof(nodoOper *); /* <=== AND HERE */
if((tn=malloc(tam))==NULL)
yyerror("Memory fault (cod. 4)");
tn->oper = o;
tn->nops = n;
va_start(ap, n);
for(i=0; i<n; i++)
tn->ptn[i] = va_arg(ap, nodoOper*);
va_end(ap);
return tn;
}
(我在这里简化了整个结构和代码,因为它使用了两个对问题不重要的结构,所以这个例子可能有错误)
现在,struct定义位于头文件(.h)中,代码为编译器创建语法树。如何更改数组以使用可变长度?
谢谢! BECO。
编辑:将最后一个编辑回滚到Flexible Array Member。
第2版。假设我在函数内添加了这段代码:
struct nOp
{
int oper; /* some operator */
int nops; /* number of args */
struct nOp *ptn[n]; /* Variable Length Array (VLA) */
};
struct nOp tnop;
struct nOp *tn2;
tn2 = &tnop;
return tn2;
我看到第一个问题,我正在返回一个指向局部变量的指针。但除此之外,是否富有成效? 感谢
答案 0 :(得分:3)
实际上,它不是你想在这里使用的可变长度数组,而是struct
hack,又名“不完整类型”,又称“灵活数组成员”:
typedef struct nO
{
int oper;
int nops;
struct nO *ptn[]; // <== look ma, no index!
} nodoOper;
// skip a bit
// no more (n-1) --------\
tam = sizeof(nodoOper) + n * sizeof(nodoOper *);
只有struct
的最后一个成员可以“灵活”。
可变长度数组是一个不同的特性:
void foo(int size)
{
float a[size]; // run-time stack allocation
printf("%lu\n", sizeof(a)); // and run-time sizeof (yuck)
}
(哦,这些东西叫做数组,而不是矩阵。)
答案 1 :(得分:0)
该构造的C
名称是“灵活的数组成员”(它可能有助于您的搜索),或“结构黑客”在C99 之前。
查看Standard中的6.7.2.1;文中有示例用法。
您可能也对“可变长度阵列”感兴趣。见标准中的6.7.5.2。