Có bất kỳ nhược điểm nào trong việc chuyển các cấu trúc theo giá trị trong C, thay vì truyền một con trỏ không?
Nếu cấu trúc lớn, rõ ràng có khía cạnh hiệu suất của việc sao chép nhiều dữ liệu, nhưng đối với một cấu trúc nhỏ hơn, về cơ bản nó sẽ giống như truyền một số giá trị cho hàm.
Nó thậm chí còn thú vị hơn khi được sử dụng làm giá trị trả về. C chỉ có các giá trị trả về duy nhất từ các hàm, nhưng bạn thường cần một vài giá trị. Vì vậy, một giải pháp đơn giản là đặt chúng trong một cấu trúc và trả lại nó.
Có bất kỳ lý do cho hoặc chống lại điều này?
Vì mọi người có thể không rõ ràng về những gì tôi đang nói ở đây, tôi sẽ đưa ra một ví dụ đơn giản.
Nếu bạn đang lập trình bằng C, sớm muộn bạn cũng sẽ bắt đầu viết các hàm giống như thế này:
void examine_data(const char *ptr, size_t len)
{
...
}
char *p = ...;
size_t l = ...;
examine_data(p, l);
Đây không phải là một vấn đề. Vấn đề duy nhất là bạn phải đồng ý với đồng nghiệp của mình, theo đó thứ tự các tham số sẽ là do đó bạn sử dụng cùng một quy ước trong tất cả các chức năng.
Nhưng điều gì xảy ra khi bạn muốn trả lại cùng loại thông tin? Bạn thường nhận được một cái gì đó như thế này:
char *get_data(size_t *len);
{
...
*len = ...datalen...;
return ...data...;
}
size_t len;
char *p = get_data(&len);
Điều này hoạt động tốt, nhưng có nhiều vấn đề hơn. Giá trị trả về là giá trị trả về, ngoại trừ trong triển khai này thì không. Không có cách nào để nói ở trên rằng hàm get_data không được phép xem xét những gì len trỏ tới. Và không có gì làm cho trình biên dịch kiểm tra rằng một giá trị thực sự được trả về thông qua con trỏ đó. Vì vậy, vào tháng tới, khi một người khác sửa đổi mã mà không hiểu đúng về mã (vì anh ta không đọc tài liệu?), Nó sẽ bị hỏng mà không ai nhận ra, hoặc nó bắt đầu bị sập một cách ngẫu nhiên.
Vì vậy, giải pháp tôi đề xuất là cấu trúc đơn giản
struct blob { char *ptr; size_t len; }
Các ví dụ có thể được viết lại như thế này:
void examine_data(const struct blob data)
{
... use data.tr and data.len ...
}
struct blob = { .ptr = ..., .len = ... };
examine_data(blob);
struct blob get_data(void);
{
...
return (struct blob){ .ptr = ...data..., .len = ...len... };
}
struct blob data = get_data();
Vì một số lý do, tôi nghĩ rằng hầu hết mọi người sẽ theo bản năng làm cho tests_data lấy một con trỏ đến một blob struct, nhưng tôi không hiểu tại sao. Nó vẫn nhận được một con trỏ và một số nguyên, rõ ràng hơn là chúng đi cùng nhau. Và trong trường hợp get_data, không thể gây rối theo cách tôi đã mô tả trước đây, vì không có giá trị đầu vào cho độ dài và phải có độ dài được trả về.
gettimeofday
sử dụng con trỏ (như ) thay vào đó và mọi người lấy đó làm ví dụ.
void examine data(const struct blob)
là không chính xác.