从结构列表中,我们如何删除其中的一些结构条目。删除结构后,不应该留下任何空白空间。如何删除C中的结构条目
下面的代码是试图实现的任务,但没有奏效。
struct symtab *sp;
for(sp = symtab; sp < &symtab[NSYMS]; sp++)
if(sp->scope == scope) // delete
{
sp = sp+1;
}
从结构列表中,我们如何删除其中的一些结构条目。删除结构后,不应该留下任何空白空间。如何删除C中的结构条目
下面的代码是试图实现的任务,但没有奏效。
struct symtab *sp;
for(sp = symtab; sp < &symtab[NSYMS]; sp++)
if(sp->scope == scope) // delete
{
sp = sp+1;
}
你可以使用的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
是可以改变的,因为数组会成为 “短”。与该数组一起工作的其他代码只能访问缩短的区域。
你是否正在复制一个太多的数组元素? – 2009-12-03 09:58:43
这大多是正确的。虽然有一些小错误。解决这些问题之后,我才得以实施。 – neuromancer 2009-12-03 10:18:21
最好三重检查要移动的元素的数量。当你最不期待的时候,像这样的小错误可能会导致分段错误。 – 2009-12-03 13:47:24
你不能做到这一点与C风格的数组(*)。最好是将它作为链表来实现,可以是任何单链或双链。 (*)如果你需要必须使用使用数组,你可以从下一个元素到你想要删除的元素执行一个移动。但是,在这种情况下,您还必须更新NSYMS的值,它看起来像是#define,不可能。
你可以往回穿过阵列。不过,前进或后退,就必须移动的内存量而言,删除列表开头处的元素会导致惩罚的增加。出于这个原因,首先删除阵列末尾的条目可能会略微优化性能。
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
}
}
}
有几个选项:
继续使用一个固定大小的数组,但使用定点值的关键领域,所以你知道哪些项目是未使用(如-1)。 。当您需要添加条目时,请搜索下一个未使用的插槽。这仍然受限于具有固定大小的阵列。
使用memmove
在其他的答案中提到。这不是非常有效。
使用链表,而不是一个固定阵列的,那么你就可以轻松地(和便宜)删除条目,以及添加。
基本上,除非你是对具有严重的内存限制,一些嵌入式系统编写代码,有可能是没有充分的理由把一个任意上限阵列上。其他结构(例如链接列表)可以很容易地添加或删除,并且周围有大量的库提供这样的容器。
而经过了这一切,你肯定不希望一个哈希表(或字典),如果你管理一个符号表?
该最佳解决方案是使用含有结构链表。如上所述,这对数组来说效率非常低,因为如果最后没有删除数据,就必须移动数据。
您确定要将数据放在表格中而不是链接列表中吗?如果你想快速删除,链接列表要快得多(free()+一些指针引用)。用桌子你需要在内存中移动东西。 – Makis 2009-12-03 09:49:31