你如何传递C中的结构指针?
我有点困惑于如何通过引用传递函数指针?你如何传递C中的结构指针?
举例来说,这里的一些代码,我已经写了 (我没有复制整个功能,只是它的一部分是相关的)
metadata * removeBlock(metadata *first)
{
metadata *temp = first;
if(first == NULL || first -> prev == NULL)
{
first -> in_use = 1;
first = NULL;
return temp;
}
}
我要的是,当函数返回,传入的原始值应该设置为NULL。 这里是我如何调用函数,(这行代码将从堆中的区域中拉出元数据结构,它工作正常,我已经调试并确保在此之后,结构实际上指向有效的元数据结构)
metadata *strct = ((metadata *)ptr - sizeof(metadata));
removeBlock(strct);
但是,在此方法返回后,strct仍然是我在函数中传递它之前的值。我尝试传递& strct,但这只是抛出了一个无效的转换异常。传递结构作为参数的最佳方式是什么?
谢谢。
我不认为你想要的是一个好的设计 - 如果你的函数的用户希望指针设置为空(为什么?),使用函数的返回值重置该值是有意义的。
无论如何,你会想要一个指针到一个指针,像这样:
metadata* removeBlock(metadata** first) {
metadata* temp = *first;
if(temp == NULL) return temp;
if(temp->prev == NULL) {
temp->in_use = true;
*first = NULL;
}
return temp;
}
metadata* strct = ((metadata*)ptr - sizeof(metadata));
removeBlock(&strct);
这是怎么回事?不是'first = NULL',其中'first'是与'* first = NULL'相同的指针,其中'first'是指向指针的指针? – 2013-04-26 01:32:46
我尝试使用像你说的双指针,它完全按照它应该做的。谢谢。 – iamseiko 2013-04-26 01:33:11
@SheerFish不,它更深一层。 '* first = NULL'其中'first'是一个指向指针的指针,它保持原来的状态。它是指向*的东西(这也是一个指针)。 – 2013-04-26 01:41:18
正如@SheerFish说,所有我们在C是通过按值。但是,可以使用指针模拟传递引用。
void func(struct foo **fooptr) { *fooptr = 0; }
int main(int argc, char **argv) { struct foo *fooptr; func(&fooptr); }
这是一个指针传递ptr
为变量的值(从不介意那个数值的指针),使功能与*ptr
原值玩。这种技术有时被称为传递地址,并且是最靠近的C必须通过引用。
谢谢,我做到了,它工作。 – iamseiko 2013-04-26 01:35:08
如果您通过'C中的引用',则需要记住通过 - >/**和*引用和引用。这是我写的代码位可以帮助你有点
int delete_node(struct node** head, int target)
{
if(*head == NULL)
return 0;
if((*head)->data == target)
{
temp = *head;
*head = (*head)->next;
free(temp);
return 1;
}
}
函数调用:
delete_node(&head, data)
你与直接内存指针操作工作。你在内存中抛出结构的位置,引用它,然后改变该内存位置的值。
这个'delete_node'从哪里来? (不是我的投票) – Shoe 2013-04-26 01:30:22
我更新它来纠正这一点。忘了说明这是底层的函数调用。这只是我为C链接列表编写的示例代码片段。 – TheCodingArt 2013-04-26 01:33:02
我的数据不是一个整数,这是一个双向链表的一部分,没有任何数据。它只是位于堆中的位置引用,位于数据块旁边,因此不会删除任何要删除的数据。但是,正如你所建议的那样,使用双指针起作用。谢谢。 – iamseiko 2013-04-26 01:34:49
我没看过所有的细节,但是这部分跳出来是不正确的:
(metadata *)ptr - sizeof(metadata)
指针运算的类型的单位进行,而sizeof
为您提供测量以字节为单位。
所以我怀疑你想要说的是:
(metadata *)(((char*)ptr) - sizeof(metadata))
这也使得有关你的机器上运行,即一些假设可能需要填充metadata
以确保字段正确对齐以供此用途。如果sizeof(metadata)
不是字大小的倍数,则在很多体系结构上都会失败。 (但是x86会让它滑动,尽管性能成本和原子操作在某些领域不起作用)。
指针按值传递。 任何东西在c是通过值。所以为了改变传递给函数的指针,它应该得到metadata **first
。
此外,你应该使用
metadata *strct = ((metadata *)ptr - 1);
为指针运算用的sizeof(* P)的整数倍进行。所以这相当于
metadata *strct = ((metadata *)((char*)ptr - sizeof(metadata)));
C根本没有'传递引用',它只有'传值'。即使在传递指针时,它本质上也是'传递值'。 – 2013-04-26 01:22:52
您的功能有问题。例如,如果'first == NULL',那么继续并尝试设置'first-> in_use'来解引用NULL指针。 – Blastfurnace 2013-04-26 01:25:55
我没有任何情况下,当用户传入一个NULL,虽然这是一个好主意,以消除检查,以便它永远不会发生。谢谢。 – iamseiko 2013-04-26 01:38:45