2013-07-18 35 views
6

Tôi đã triển khai cấu trúc hàng đợi cơ bản trong C bằng cách sử dụng con trỏ void. Thủ tục như sau:Thực hiện hàng đợi C bằng cách sử dụng void * - thực hành tốt hay xấu?

  • khởi tạo cấu trúc - Tôi thiết lập kích thước của các loại biến được lưu trữ trong hàng đợi
  • push - tôi vượt qua con trỏ đến các biến phải được lưu trữ, hàng đợi sau đó lấy bản sao cho chính nó
  • trước - cấu trúc trả về khoảng trống * cho phần tử ở phía trước. Tôi có thể chỉ cần lấy con trỏ, hoặc memcpy() nó để có một bản sao cục bộ.

Các struct bản thân trông như thế này:

struct queue 
{ 
    void* start; //pointer to the beginning of queue 
    void* end;  //-||- to the end 
    size_t memsize; //size of allocated memory, in bytes 
    size_t varsize; //size of a single variable, in bytes 
    void* initial_pointer;  //position of the start pointer before pop() operations 
}; 

bắt đầu và kết thúc chỉ là con trỏ void trỏ đến một số vị trí trong khối bộ nhớ hiện đang được phân bổ. Nếu tôi đẩy các phần tử vào hàng đợi, tôi sẽ tăng con trỏ kết thúc lên varsize. Nếu tôi bật(), tôi chỉ cần giảm con trỏ cuối cũng bằng varsize.

Tôi không nghĩ mình nên đăng mã chức năng ở đây, nó có trên 100 dòng.

Câu hỏi: được coi là thực tiễn tốt hay xấu? Tại sao không)?

Lưu ý: Tôi biết rằng có nhiều tùy chọn khác cho hàng đợi trong C. Tôi chỉ hỏi về chất lượng của hàng này.

EDIT: Việc thực hiện có sẵn ở đây: http: // 89.70.149.19 /stuff/queue.txt (loại bỏ các khoảng trắng)

+2

Sử dụng size_t cho kích thước bộ nhớ –

+0

Tôi nghĩ tốt để viết mã chung bằng cách sử dụng 'void *' –

+0

@RanEldan Cảm ơn bạn, tôi sẽ. Đã sửa nó ở đây. – szczurcio

Trả lời

8

Đó là OK để sử dụng void * nếu bạn không biết loại và kích thước các đối tượng được lưu trữ trong hàng đợi (trên thực tế, thư viện chuẩn C theo cùng cách tiếp cận, xem các hàm memcpy()qsort() đối với một số ví dụ). Tuy nhiên, sẽ tốt hơn nếu sử dụng size_t (hoặc ssize_t nếu bạn cần loại dữ liệu đã ký) để chỉ định kích thước của các phần tử được lưu trữ trong hàng đợi.

+1

Ran Eldan đã đề cập đến điều đó, tôi đã sửa chữa nó. OK, cảm ơn vì ý kiến ​​của bạn. Tôi thực sự nghĩ rằng nó trực quan để làm điều đó, chỉ có tôi đã nhìn thấy một số người tuyên bố điều này là "xấu xí". – szczurcio

+2

@szczurcio Điều này là bạn không thể thực sự làm bất cứ điều gì khác nếu bạn không biết loại trước. Nếu bạn làm như vậy, sau đó không sử dụng 'void *' bằng bất kỳ phương tiện nào cho an toàn loại tốt hơn. –

2

Bạn thực sự không cho chúng tôi biết đủ để chắc chắn về triển khai của bạn. void* cho các mục dữ liệu người dùng là tốt, bạn không thể làm nhiều cách khác trong C.

Nhưng tôi rất nghi ngờ rằng bạn có một loại nguyên tố danh sách nội bộ mà bạn sử dụng để quản lý các mục riêng biệt, một cái gì đó giống như

struct list_item { 
    struct list_item* next; 
    void* data; 
}; 

Nếu đó là trường hợp và startend bạn con trỏ đang trỏ đến các yếu tố như vậy, bạn dứt khoát nên sử dụng loại nguyên tố của bạn trong việc kê khai struct queue:

struct queue 
{ 
    struct list_item* start; //pointer to the beginning of queue 
    struct list_item* end;  //-||- to the end 
    size_t memsize; //size of allocated memory, in bytes 
    size_t varsize; //size of a single variable, in bytes 
    struct list_item* initial_pointer;  //position of the start pointer before pop() operations 
}; 

Để làm việc này, bạn thậm chí không cần phải phơi bày định nghĩa của struct list_item cho người dùng của struct queue.

+0

Tôi không chắc chắn ý của bạn là gì. bắt đầu và kết thúc chỉ là con trỏ void trỏ đến một số vị trí trong khối bộ nhớ hiện được cấp phát. Nếu tôi đẩy các phần tử vào hàng đợi, tôi sẽ tăng con trỏ kết thúc bằng varsize. Nếu tôi bật(), tôi chỉ cần giảm con trỏ cuối cũng bằng varsize. – szczurcio

+0

EDIT: Tôi đã thêm một liên kết đến mã trong câu hỏi của tôi. – szczurcio

+0

@szczurcio, là một triển khai rất độc đáo của một hàng đợi, thông thường sẽ là một cái gì đó với các yếu tố năng động như tôi mô tả nó ở đây. Bạn nên thêm mô tả mà bạn có trong nhận xét của mình cho câu hỏi, để tham khảo. Sau đó tôi sẽ xóa câu trả lời này, câu trả lời này không phục vụ bạn nhiều. –

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