2016-05-20 16 views
6

Tôi đang quan sát xung quanh với con trỏ trong C và tôi vẫn không chắc chắn về một số vấn đề cơ bản. Tôi đã đưa ra với mã gương mẫu sau:C: Truy cập (int) qua (void *) trỏ tới (void *) trỏ tới (int) bằng typecasting và dereferencing

#include <stdio.h> 

int main(void) 
{ 
    int num = 42;    // we want to access this integer 
    void *vptrB = &num;  // pointer B points to the integer 
    void *vptrA = &vptrB;  // pointer A points to pointer B 
    printf("%d\n", * (int *) * (void **) vptrA); 
    return 0; 
} 

Ký ức nên tìm một cái gì đó như thế này:

scheme

Có giải pháp thay thế để truy cập số nguyên? Bất cứ điều gì xấu/không an toàn với ví dụ? Là * (int *) * (void **) vptrA cách duy nhất để truy cập num qua vptrAvptrB?

+3

Tại sao bạn giữ con trỏ của mình là 'void *' thay vì sử dụng đúng loại? Bạn nên cố gắng làm việc * với * hệ thống kiểu, không chống lại nó. –

+1

Ouch; nhắc tôi không cần phải đọc mã của bạn trong tương lai, xin vui lòng? Điều đó thật khó hiểu. Nếu bạn có thể tham khảo 'vptrB', thì bạn có thể làm cho nó đơn giản hơn, nhưng nếu bạn chỉ có thể truy cập' vptrA', thì những gì bạn đã viết có vẻ đúng - nhưng tôi đã không chạy nó qua trình biên dịch để kiểm tra lại rằng tôi ' đã giải thích nó giống như trình biên dịch. –

+0

Tôi có thể nói rằng phong cách xấu sử dụng 'void *' nói chung (đặc biệt là ở những nơi mà bạn có thể dễ dàng sử dụng con trỏ đã nhập) và phong cách rất xấu để che giấu mức độ liên quan đến indirection (tức là lưu trữ địa chỉ của 'void * 'thay vì' void ** '). Và tôi thường tránh việc truyền vào giữa dereferencing, vì vậy tôi sẽ có '** ((int **) vptrA)'. – Zastai

Trả lời

2

Có lựa chọn thay thế nào để truy cập vào số nguyên không?

int num = 42; 
int *vptrB = &num; 
int **vptrA = &vptrB; 
// All print 42 
printf("%d\n", num); 
printf("%d\n", *vptrB); 
printf("%d\n", **vptrA); 

Bất cứ điều gì xấu/không an toàn với ví dụ?

Sử dụng void* để đại diện cho địa chỉ để dữ liệu bị mất loại, sắp xếp, constvolatile thông tin. void* bắt buộc phải sử dụng phép đúc để sau đó giải thích dữ liệu được tham chiếu - điều này dễ bị lỗi. Mặc dù mã là chính xác trong quá trình truyền của nó, nó có thể bị lỗi bảo trì và mã xem xét hiểu sai.

+1

bằng cách sử dụng 'void *' không có phôi sẽ bảo toàn thông tin 'const' và' volatile'. Tất nhiên bạn có thể bỏ những thứ đó đi nhưng điều đó cũng đúng với 'int *' –

Các vấn đề liên quan