【问题标题】:Alternate Solution to Passing Parameter by Reference in C在 C 中通过引用传递参数的替代解决方案
【发布时间】:2014-05-08 17:10:33
【问题描述】:

我正在尝试实现链表的头插入功能,并希望通过引用传递将 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 不会更改其先前的值。任何建议或帮助表示赞赏,谢谢!

【问题讨论】:

  • 您需要将元素作为 void 传入**
  • 我无法更改函数的参数。
  • 好吧,那我觉得你倒霉了。
  • 可能有助于向人们展示调用该函数的代码。
  • list->next = list_new 基本上分配给“list”输入参数。调用者可以利用这个作为调用函数提供的“列表”内存。这对您的程序有意义吗?

标签: c pointers linked-list pass-by-reference


【解决方案1】:

好吧,我知道您不能更改参数,但如果您可以更改此函数的实现和调用者,您可以做到这一点!

关于 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;
}

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

【讨论】:

    【解决方案2】:

    如前所述,如果您无法修改函数原型,您仍然可以使用 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-20
      • 2021-07-29
      • 2014-02-09
      • 2017-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多