从结构列表中我们如何删除其中的一些。删除结构后,不应留下任何空白空间。
尝试使用以下代码来完成任务,但它无效。
struct symtab *sp;
for(sp = symtab; sp < &symtab[NSYMS]; sp++)
if(sp->scope == scope) // delete
{
sp = sp+1;
}
答案 0 :(得分:2)
您可以使用memmove():
//pseudocode, not tested
struct symtab* end = &symtab[NSYMS];
for(sp = symtab; sp < end; sp++) {
if(sp->scope == scope) {
memmove( sp, sp + 1, (end - sp) * sizeof(struct symtab);
sp++;
end--;
}
}
请注意,end
可以更改,因为数组可能变得“更短”。与该数组一起使用的其他代码必须仅访问缩短的区域。
答案 1 :(得分:1)
使用C风格的数组(*)无法做到这一点。最好是将其作为链表实现,可以是任何单链接或双链接。
(*)如果必须使用数组,则可以从下一个元素到要删除的元素进行memmove。但是,在这种情况下,您还必须更新NSYMS的值,从而看起来它是#define,不可能。
答案 2 :(得分:1)
你可以向后穿过阵列。但是,向前或向后,根据必须移动的内存量,删除列表开头的元素会增加惩罚。因此,首先删除数组末尾的条目可能会略微优化性能。
struct symtab *sp;
struct symtab *endp; // end of array pointer
endp = symtab + NSYMS;
for ( sp = symtab + NSYMS - 1; sp >= symtab; sp-- ) {
if ( sp->scope = scope ) {
int numelems = endp - (sp + 1);
if ( numelems > 0 ) {
memmove( sp, sp + 1, numelems );
endp--; // adjust end of array pointer
}
}
}
答案 3 :(得分:0)
有几个选择:
继续使用固定大小的数组,但对关键字段使用sentinel值(例如-1),以便了解哪些条目未使用。需要添加条目时,请搜索下一个未使用的插槽。这仍然受限于具有固定大小的阵列。
使用其他答案中提到的memmove
。这不是很有效。
使用链接列表而不是固定数组,然后您可以轻松(并且便宜地)删除条目,以及添加。
基本上,除非您为某些具有严重内存限制的嵌入式系统编写代码,否则可能没有充分的理由在数组上设置任意上限。其他结构(例如链表)可以很容易地添加到或删除,并且有大量的库提供这样的容器。
毕竟,如果您正在管理符号表,您确定不需要哈希表(或字典)吗?
答案 4 :(得分:0)
最好的解决方案是使用包含结构的链表。如上所述,这对数组非常有效,因为如果数据最后没有被删除,你必须移动数据。