2012-07-12 71 views
5

Tôi bắt đầu học C và đọc mã sau:Tuyên bố void ** có nghĩa là gì trong ngôn ngữ C?

public void** list_to_array(List* thiz){ 
    int size = list_size(thiz); 
    void **array = malloc2(sizeof(void *) * size); 
    int i=0; 
    list_rewind(thiz); 
    for(i=0; i<size; i++){ 
     array[i] = list_next(thiz); 
    } 
    list_rewind(thiz); 
    return array; 
} 

Tôi không hiểu ý nghĩa của void**. Ai đó có thể giải thích nó với một số ví dụ?

+3

'khoảng trống ** '= con trỏ đến một' khoảng trống *' – Mysticial

+1

Trong trường hợp này, nó có nghĩa là "con trỏ đến một mảng các con trỏ * khoảng trống" –

+2

@VariableLengthCoder, không đó sẽ là ' void * (* mảng) [] '.Bạn có thể có nghĩa là "con trỏ đến phần tử đầu tiên của một mảng con trỏ' void' ". –

Trả lời

1

void** là con trỏ đến void* hoặc pointer thành void pointer nếu bạn thích! Ký hiệu này được sử dụng theo kiểu truyền thống trong ví dụ C để triển khai ma trận. Vì vậy, trong trường hợp ma trận, đó sẽ là pointer đến một số array of pointers.

+1

Đó là một con trỏ trỏ đến con trỏ 'void', nhưng con trỏ' void' là con trỏ 'void' là gì? –

+0

@CarlNorum Tôi xin lỗi vì đã nhập sai. – cybertextron

0

Thông thường void * con trỏ được sử dụng để biểu thị con trỏ đến một loại dữ liệu không xác định. Trong trường hợp này hàm của bạn trả về một mảng các con trỏ như vậy sao cho sao đôi.

Trong C, con trỏ thường được sử dụng để tham chiếu một mảng. Ví dụ: nhiệm vụ sau đây hoàn toàn hợp pháp:

char str1[10]; 
char *str2 = str1; 

Bây giờ khi sử dụng khoảng trống, nghĩa là thay vì char bạn có một loại biến không xác định.

Con trỏ đến loại dữ liệu không xác định rất hữu ích để viết các thuật toán chung. Ví dụ. chức năng qsort trong thư viện C chuẩn được định nghĩa là:

void qsort (void * base, 
      size_t num, 
      size_t size, 
      int (* comparator) 
      (const void *, const void *)); 

Thuật toán sắp xếp là chung, nhưng không biết nội dung của dữ liệu. Vì vậy, người dùng phải cung cấp một thực hiện của một so sánh có thể đối phó với nó. Thuật toán sẽ gọi bộ so sánh với hai con trỏ tới các phần tử cần so sánh. Các con trỏ này thuộc loại void *, bởi vì hiện tại có thông tin về loại dữ liệu đang được sắp xếp.

Hãy nhìn vào chủ đề này để biết thêm ví dụ http://forums.fedoraforum.org/showthread.php?t=138213

+3

-1 để nói rằng 'char ** strarray2 = strarray1;' là "hoàn toàn hợp pháp". –

+0

Jens là đúng, 'char [] []' tương đương với 'char []' (nó chỉ là cú pháp thuận tiện cho phép trình biên dịch làm số học con trỏ mảng 2D cho bạn), trong khi 'char **' là một mảng con trỏ vào mảng char. – Adam

+0

Thanx để chỉ ra rằng, tôi đã không có một trình biên dịch C ở bàn tay khi tôi trả lời nó để sửa tôi: ( – anttix

4

trống ** là một con trỏ đến một con trỏ để làm mất hiệu lực (loại không xác định). Nó có nghĩa là biến (vị trí bộ nhớ) chứa một địa chỉ đến một vị trí bộ nhớ, có chứa một địa chỉ đến một vị trí bộ nhớ khác, và những gì được lưu trữ ở đó không được chỉ định. Trong trường hợp của câu hỏi này, nó là một con trỏ tới một mảng các con trỏ void *.

Sidenote: Một con trỏ void không thể bị bỏ qua, nhưng một khoảng trống ** có thể.

void *a[100]; 
void **aa = a; 

Bằng cách thực hiện việc này sẽ có thể thực hiện, ví dụ: aa [17] để lấy phần tử thứ 18 của mảng a.

Để hiểu các khai báo như vậy, bạn có thể sử dụng công cụ this và cũng có thể kiểm tra một số liên quan question hoặc two.

+0

Trả lời không đứng trên riêng của mình - nếu và khi các liên kết phá vỡ, điều này sẽ có giá trị bằng không – dwanderson

+0

@ Tôi đã được cập nhật câu trả lời.Tôi phải có được chút lười biếng trở lại vào năm 2012 khi tôi đã viết câu trả lời này.Được rồi. :) –

+0

Theo dõi ấn tượng! luôn luôn đánh giá cao khi mọi người trả lời các câu hỏi cũ. Cảm ơn! – dwanderson

0

con trỏ void được sử dụng để giữ địa chỉ của bất kỳ loại dữ liệu nào. void** có nghĩa là con trỏ để làm mất con trỏ. Các con trỏ rỗng được sử dụng ở một nơi mà chúng ta muốn một hàm sẽ nhận các kiểu dữ liệu khác nhau như là đối số hàm. Vui lòng kiểm tra ví dụ dưới đây

void func_for_int(void *int_arg) 
{ 
    int *ptr = (int *)int_arg; 
    //some code 
} 

void func_for_char(void *char_arg) 
{ 
    char *ptr = (char *)char_arg; 
    //some code 
} 

int common_func(void * arg, void (*func)(void *arg)) 
{ 
    func(arg); 
} 

int main() 
{ 
    int a = 10; 
    char b = 5; 

    common_func((void *)&a, func_for_int); 
    common_func((void *)&b, func_for_char); 

    return 0; 
} 
Các vấn đề liên quan