一级指针和二级指以及(void**)在双链表中的应用
因為函數參數是按值傳遞的,所以要想改變變量,必須傳遞地址。
二級指針實際上就是指針變量的地址,如果傳遞二級指針,函數聲明必須寫**。
(void**)&必須是本質上就是指針變量的地址才可以做這樣的轉換,并不是說把一個一級指針也可以轉換,void**的本質是標識一個二級指針。
&data就是(默認數據類型 **)&data,(void **)&data和&data還是同一塊內存,只不過數據類型發生變化了。
如果默認數據類型是int,&data就是(int **)&data
一級指針:
- void
- swap ( int *a, int *b ){
- int temp = 0;
- temp = *a;
- *a = *b;
- *b = temp;
- }
- int
- main ( int argc, char **argv ){
- int a,b;
- a = 16;
- b = 32;
- swap(&a, &b);
- return ( a - b );
- }
二級指針:
- void swap(int **a, int **b)
- {
- int t;
- t =**a;
- **a =**b;
- **b=t;
- }
- int main()
- {
- int i = 3;
- int j = 5;
- int *p = &i;
- int *q = &j;
- swap(&p, &q);
- }
高級一點使用void**只是為了通用,可以交換各種類型。
- void swap(void **a, void **b)
- {
- void *t;
- t =*a;
- *a =*b;
- *b=t;
- }
- int main()
- {
- int i = 3;
- int j = 5;
- int *p = &i;
- int *q = &j;
- char *s1="abc";
- char *s2="def";
- swap((void**)&p, (void**)&q);
- swap((void**)&s1, (void**)&s2);
- }
注意char*是字符串指針,需要改變其對應的變量必須用地址,s1就是"abc"的起始地址,是不能被改變,要想改變s1必須用他的地址也就是&s1,所以需要void**:
- void swap(void *a, void *b)
- {
- void *t;
- t =a;
- a =b;
- b=t;
- }
- int main()
- {
- char *s1="abc";
- char *s2="def";
- swap((void*)s1, (void*)s2);
- }
(void**)& 本質
在看《算法精解? C語言描述》的雙鏈表dlist.c的代碼看到這樣一段
算法精解:C語言描述\examples_unix\examples\chtbl\ex-1.c
- int??????????????? *data;
- *data = 11;
- if (dlist_remove(&list, element, (void **)&data) != 0)
- return 1;
算法精解:C語言描述\examples_unix\source\dlist.c
- int dlist_remove(DList *list, DListElmt *element, void **data) {
- /*****************************************************************************
- * *
- * Do not allow a NULL element or removal from an empty list. *
- * *
- *****************************************************************************/
- if (element == NULL || dlist_size(list) == 0)
- return -1;
- /*****************************************************************************
- * *
- * Remove the element from the list. *
- * *
- *****************************************************************************/
- *data = element->data;
- if (element == list->head) {
- /**************************************************************************
- * *
- * Handle removal from the head of the list. *
- * *
- **************************************************************************/
- list->head = element->next;
- if (list->head == NULL)
- list->tail = NULL;
- else
- element->next->prev = NULL;
- }
- else {
- /**************************************************************************
- * *
- * Handle removal from other than the head of the list. *
- * *
- **************************************************************************/
- element->prev->next = element->next;
- if (element->next == NULL)
- list->tail = element->prev;
- else
- element->next->prev = element->prev;
- }
- /*****************************************************************************
- * *
- * Free the storage allocated by the abstract data type. *
- * *
- *****************************************************************************/
- free(element);
- /*****************************************************************************
- * *
- * Adjust the size of the list to account for the removed element. *
- * *
- *****************************************************************************/
- list->size--;
- return 0;
- }
其實很簡單:
data是指針變量;
&data是data指針變量的地址所以傳遞他就是void**
看下面這幅調試圖就明白了,起始&data就是(int **)&data,(void **)&data和&data還是同一塊內存,只不過數據類型發生變化了。
總結
以上是生活随笔為你收集整理的一级指针和二级指以及(void**)在双链表中的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++指向指针的指针
- 下一篇: CUDA学习3-GridBlock