1. 程式人生 > >關於(void**)&的理解

關於(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;