一级指针和二级指以及(void**)&在双链表中的应用

因为函数参数是按值传递的,所以要想改变变量,必须传递地址

二级指针实际上就是指针变量的地址,如果传递二级指针,函数声明必须写**

(void**)&必须是本质上就是指针变量的地址才可以做这样的转换并不是说把一个一级指针也可以转换void**的本质是标识一个二级指针。

&data就是(默认数据类型 **)&data,(void **)&data和&data还是同一块内存,只不过数据类型发生变化了。

如果默认数据类型是int,&data就是(int **)&data



一级指针:

  1. void
  2. swap ( int *a, int *b ){
  3. int temp = 0;
  4. temp = *a;
  5. *a = *b;
  6. *b = temp;
  7. }
  8. int
  9. main ( int argc, char **argv ){
  10. int a,b;
  11. a = 16;
  12. b = 32;
  13. swap(&a, &b);
  14. return ( a - b );
  15. }

二级指针:

  1. void swap(int **a, int **b)
  2. {
  3. int t;
  4. t =**a;
  5. **a =**b;
  6. **b=t;
  7. }
  8. int main()
  9. {
  10. int i = 3;
  11. int j = 5;
  12. int *p = &i;
  13. int *q = &j;
  14. swap(&p, &q);
  15. }


高级一点使用void**只是为了通用,可以交换各种类型。

  1. void swap(void **a, void **b)
  2. {
  3. void *t;
  4. t =*a;
  5. *a =*b;
  6. *b=t;
  7. }
  8. int main()
  9. {
  10. int i = 3;
  11. int j = 5;
  12. int *p = &i;
  13. int *q = &j;
  14. char *s1= "abc";
  15. char *s2= "def";
  16. swap(( void**)&p, ( void**)&q);
  17. swap(( void**)&s1, ( void**)&s2);
  18. }


注意char*是字符串指针,需要改变其对应的变量必须用地址,s1就是"abc"的起始地址,是不能被改变,要想改变s1必须用他的地址也就是&s1,所以需要void**:

  1. void swap(void *a, void *b)
  2. {
  3. void *t;
  4. t =a;
  5. a =b;
  6. b=t;
  7. }
  8. int main()
  9. {
  10. char *s1= "abc";
  11. char *s2= "def";
  12. swap(( void*)s1, ( void*)s2);
  13. }




(void**)& 本质

在看《算法精解  C语言描述》的双链表dlist.c的代码看到这样一段


算法精解:C语言描述\examples_unix\examples\chtbl\ex-1.c

  1. int                *data;
  2. *data = 11;
  3. if (dlist_remove(& list, element, ( void **)&data) != 0)
  4. return 1;


算法精解:C语言描述\examples_unix\source\dlist.c

  1. int dlist_remove(DList *list, DListElmt *element, void **data) {
  2. /*****************************************************************************
  3. * *
  4. * Do not allow a NULL element or removal from an empty list. *
  5. * *
  6. *****************************************************************************/
  7. if (element == NULL || dlist_size( list) == 0)
  8. return -1;
  9. /*****************************************************************************
  10. * *
  11. * Remove the element from the list. *
  12. * *
  13. *****************************************************************************/
  14. *data = element->data;
  15. if (element == list->head) {
  16. /**************************************************************************
  17. * *
  18. * Handle removal from the head of the list. *
  19. * *
  20. **************************************************************************/
  21. list->head = element->next;
  22. if ( list->head == NULL)
  23. list->tail = NULL;
  24. else
  25. element->next->prev = NULL;
  26. }
  27. else {
  28. /**************************************************************************
  29. * *
  30. * Handle removal from other than the head of the list. *
  31. * *
  32. **************************************************************************/
  33. element->prev->next = element->next;
  34. if (element->next == NULL)
  35. list->tail = element->prev;
  36. else
  37. element->next->prev = element->prev;
  38. }
  39. /*****************************************************************************
  40. * *
  41. * Free the storage allocated by the abstract data type. *
  42. * *
  43. *****************************************************************************/
  44. free(element);
  45. /*****************************************************************************
  46. * *
  47. * Adjust the size of the list to account for the removed element. *
  48. * *
  49. *****************************************************************************/
  50. list->size--;
  51. return 0;
  52. }

其实很简单:

data是指针变量;

&data是data指针变量的地址所以传递他就是void**

看下面这幅调试图就明白了,起始&data就是(int **)&data,(void **)&data和&data还是同一块内存,只不过数据类型发生变化了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值