GLib库这样做是为了比较两个单独链接的列表节点:
typedef struct _GSList {
_GSList *link;
void *data;
} GSList;
int g_sListPosition(GSList *list, GSList *llink) {
int cnt = 0;
while(list) {
if(list == llink) // Note here
return cnt;
cnt++;
list = list->link;
}
return -1;
}
但是当我这样比较节点时。返回false:
int main(void) {
GSList *list = NULL, *list2 = NULL;
list2 = g_sListAppend(list2, "def");
list = g_sListAppend(list, "abc");
list = g_sListAppend(list, "def");
list = g_sListAppend(list, "ghi");
printf("%d", g_sListPosition(list, list2)); // Return -1 ?
}
那么,这里的比较是什么(在DOC中,它被写为获取给定元素在GSList中的位置)、节点或列表中包含的数据?
编辑:感谢所有的付出,我的错误实际上是我做错了。我必须比较列表中的相同实例。
因为list
和llink
是节点地址,我们不能有两个不同的节点具有相同的地址,所以找到llink
在list
中的起始位置是非常简单的技术(首先)。
假设list
传递给函数如下:
// 0 1 2 3 4
list---->[]-->[]-->[]-->[]-->[]---null
23 42 18 102 324
addresses are assumption
若llink
的值为18
,则函数返回2
,因为llink
是list
中的第三个节点。
并且如果未找到CCD_ 11,则返回CCD_。
(类似于数组索引从0
列表中的0
函数计数节点开始)
正如你所评论的,我正在评论代码:
int cnt = 0; // initial value of node_count is 0
while(list) { // search while list not NULL (till end)
if(list == llink) // if `llink` is a node in `list`
return cnt; // return node number
cnt++; // else it may be next node
list = list->link;
}
// control comes here if list == NULL, means llink not found
return -1; // not found so return -1
// negative number can't be a position
评论:
我的意思是,如何测试它如果它真的给出了正值
调用您的函数如下:
g_sListPosition(list, list->link->link->link);
// 0 1 2
它将返回CCD_ 15。
但请注意,您列出的应该由3
节点组成。
头为list2
的列表
+--------+
| def |--->X
+--------+
arr1
当函数分配节点时,它将分配一个具有节点大小的可用内存位置,然后在节点的数据部分中分配字符串(它必须在其中分配字符串)。
头为list
的列表
+--------+ +--------+ +--------+
| abc |--->| def |--->| ghi |--->X
+--------+ +--------+ +--------+
addr2 addr3 addr4
在这里,每次将字符串附加到链表时,都会分配一个新节点,并将字符串复制到数据部分。请注意,每次分配新节点时,该节点的地址都是不同的。
在上述情况下,具有数据"def"的第一个列表具有地址addr1
,而具有数据"def"的第二个列表具有节点,其地址为addr3
。因此,如果您尝试用==
运算符比较这两个节点,那么比较结果自然会为false,因为等式会比较不同节点的地址,从而返回false。
如果要特别匹配节点中的数据,则需要对其进行特别比较。也就是说,访问list
中的每个节点,并将数据部分与另一个节点(list1
)进行比较。
另一方面,如果你已经在一个特定的链表中提取了节点地址,那么你可以使用该地址进行比较。例如,如果您遍历列表直到末尾,并获得最后一个节点的地址,其中"ghi"的地址为addr4
,那么您可以稍后使用该地址来比较列表中的特定节点,前提是该节点没有被释放并使用相同的数据重新创建。在这种情况下,您可以清楚地看到,即使该节点内的数据发生了更改,地址也将保持不变。
我发现,我们实际上必须给出列表的相同实例。下面是一个例子:
int main(void) {
RSList *list = NULL;
list = r_sListAppend(list, "abc");
list = r_sListAppend(list, "def");
list = r_sListAppend(list, "ghi");
RSList *list2 = list;
int i = 2;
while(i--) {
list2 = list2->link;
}
printf("%d", r_sListIndexOf(list, list2)); // Print 2
}