C语言中通过引用传递参数的替代解决方案



我试图实现一个链表的插入头部功能,并希望通过引用传递返回一个void*指针到新插入的节点。不幸的是,我不能改变参数。这是我的相关代码:

typedef struct List_t_def{
 spinlock_t * lock_counter;
 unsigned int key;
 struct List_t_def *next;
}list_t;
typedef volatile unsigned int spinlock_t;//basic lock
void List_Insert(list_t *list, void *element, unsigned int key) {  
  list_t * list_new = (list_t *)malloc(sizeof(list_t));
  spinlock_t * lock_temp = (spinlock_t*)malloc(sizeof(spinlock_t));
  list_new->lock_counter = lock_temp;
  spinlock_acquire(list->lock_counter);
  list_new->key = key;    //inserting the new created node as the first one (head of the linked list)
  list_new->next = list->next;
  list_new->lock_counter = list->lock_counter;    
  list->next = list_new;
  element = (void*)list_new; 
  spinlock_release(list->lock_counter);
  return;
}

我试图将element设置为新插入节点的开始,但是当它返回时,element不会改变其先前的值。任何建议或帮助是感激的,谢谢!

嗯,我知道你不能改变参数,但是如果你可以改变这个函数的实现和调用者,你可以做到这一点!

关于C的可怕(也不错)的事情是你可以将任何东西强制转换为你想要的任何东西。因此,即使你不能改变函数签名来接受void**,你仍然可以传递一个。例子:

char *element = (char *)malloc(0xDEADBEEF);
List_Insert(list, (void*)&element, key);

在函数内部,可以将其强制转换为void**:

void List_Insert(list_t *list, void *element, unsigned int key) {
    void **e = (void **)element;
    /* do stuff */
    *e = (void *)list_new;
}

瞧!顺便说一句,这太可怕了,对调用者来说不直观。我希望这不是生产代码:)

正如已经建议的,如果你不能修改函数原型,你仍然可以使用你的void*参数传递任何类型的指针到函数,包括指针对指针返回你的新元素。

让我对代码进行细化,以显示这种用法的不那么抽象的示例:

void List_Insert_Caller() {
    // ...
    list_t *new_element;
    List_Insert(list, &new_element, key);
    // new_element now points to newly created list_t element
}
void List_Insert(list_t *list, void *new_element_ptr_ptr, unsigned int key) {
    // ...
    list_t **new_element = (list_t **)new_element_ptr_ptr;
    // ...
    *new_element = list_new;
}

相关内容

  • 没有找到相关文章

最新更新