2009-07-11 25 views
15

Tôi đã thấy mọi người sử dụng size_t bất cứ khi nào họ ngụ ý một số nguyên không dấu. Ví dụ:Có thực hành tốt để sử dụng size_t trong C++ không?

class Company { 
    size_t num_employees_; 
    // ... 
}; 

Thực tiễn đó có tốt không? Có một điều là bạn phải bao gồm <cstddef>. Nếu nó là unsigned int thay thế? Hoặc thậm chí chỉ cần int?

Chỉ cần sử dụng int âm thanh hấp dẫn đối với tôi vì nó tránh được lỗi ngớ ngẩn như thế này (vì người ta thường sử dụng int):

for(int i = num_employees_ - 1; i >= 0; --i) { 
    // do something with employee_[i] 
} 
+0

Tôi không biết bất kỳ ai đếm mọi thứ từ kích thước xuống tới 0.: | – GManNickG

+0

Tôi tò mò về câu trả lời cho điều này liên quan đến việc truyền. Nếu bạn đi với int unsigned hoặc int và đó không phải là những gì size_t thực sự là trên hệ thống của bạn thì có lẽ nó đã chuyển đổi nó để có thể có một hit hiệu suất? – Troubadour

+0

Nó có thể hữu ích, nhưng làm theo cách mà ví dụ hiển thị chỉ là thực hành không tốt. Chọn loại dữ liệu của bạn để đáp ứng một kết quả thực hành xấu trong 2 thực tiễn không tốt. – Gerald

Trả lời

15

size_t có thể có kích thước khác nhau để int.

Đối với những thứ như số lượng nhân viên, v.v., sự khác biệt này thường không quan trọng; bao lâu một người có hơn 2^32 nhân viên? Tuy nhiên, nếu bạn là một trường đại diện cho kích thước tệp, bạn sẽ muốn sử dụng size_t thay vì int, nếu hệ thống tệp của bạn hỗ trợ các tệp 64 bit.

Nhận ra rằng kích thước đối tượng (như thu được bởi sizeof) thuộc loại size_t, không phải int hoặc unsigned int; cũng tương ứng, có một số ptrdiff_t cho sự khác biệt giữa hai con trỏ (ví dụ: &a[5] - &a[0] == ptrdiff_t(5)).

+14

Bạn nên sử dụng off_t cho filesizes chứ không phải size_t. Trên hệ thống 32 bit, size_t sẽ là 32 bit, trong khi off_t sẽ là 64 bit (giả sử hỗ trợ tệp lớn). –

+0

@ Søren: +1 Điểm rất tốt. Tôi sẽ cố gắng nghĩ về một ví dụ khác, trong đó có 'size_t' 64 bit xuất hiện, sau đó cập nhật bài đăng của tôi. Bất kỳ đề nghị bạn có được chào đón. :-) –

0

Tôi sẽ sử dụng unsigned int hoặc int trong trường hợp này. size_t là, có vẻ như, chủ yếu để đại diện cho kích thước của cấu trúc dữ liệu. Khái niệm, trong khi số lượng nhân viên có thể trong một số trường hợp kích thước của một cấu trúc dữ liệu, nó không nhất thiết phải; nó có thể chỉ là đếm. Vì vậy, tôi muốn sử dụng int, nhưng tôi có lẽ sẽ không đẩy điểm quá khó.

0

Tôi không chuyên nghiệp, nhưng tôi chỉ sử dụng size_t cho kích thước bộ nhớ để tăng khả năng đọc của mã. Trong mọi trường hợp khác, tôi sử dụng unsigned int (hoặc bất kỳ thứ gì khác).

7

Sử dụng size_t trong nhiều trường hợp giúp tính di động. size_t không phải lúc nào cũng là "unsigned int", nhưng nó luôn luôn là kích thước có thể đại diện cho đối tượng lớn nhất có thể trên nền tảng đã cho. Ví dụ, một số nền tảng có kích thước nguyên 16 bit, nhưng sử dụng con trỏ 32 bit. Trong trường hợp đó nếu bạn sử dụng int unsigned cho kích thước của một cái gì đó bạn sẽ được giới hạn nó đến 65.536 byte (hoặc các yếu tố khác) mặc dù nền tảng có thể xử lý một cái gì đó lớn hơn nhiều.

Trong ví dụ của bạn, tôi có thể sử dụng typedef cho số nguyên không dấu 32 bit hoặc 64 bit thay vì sử dụng int hoặc unsigned int hoặc size_t.

-1

Bạn không muốn sử dụng đồng bằng int trong trường hợp này vì số lượng nhân viên không bao giờ là tiêu cực và bạn muốn trình biên dịch của bạn giúp bạn thực thi quy tắc này, đúng không?

+4

Vâng, tôi sẽ rất vui nếu tôi nhận được một trình biên dịch hoặc cảnh báo thời gian chạy cho việc này: num_employees_ = 0; --num_employees_; Nhưng nó không xảy ra. – Frank

+0

@dehmann Nhưng bạn có thể viết các hàm/phương thức lấy int không dấu như một tham số và khi người dùng chuyển int đơn giản, chúng sẽ được cảnh báo. –

+2

@Piotr: không họ sẽ không. "void foo (unsigned int a) {} int main() {int a = -1; foo (a);}" không cảnh báo trên bất kỳ trình biên dịch nào mà tôi biết. Vượt qua một chữ tiêu cực. –

2

Bạn luôn có thể sử dụng những thứ như

employeeList.size(); 

hoặc

EmployeeList::size_type i = 0; 

hoặc

EmployeeNumber number = employee.getNumber(); 

Ý tôi là làm ints incapsulate và các loại khác như thế này trừ khi nó chỉ là một số tính toán nội bộ hoặc thuật toán.

7

Trong trường hợp của bạn không sử dụng bất kỳ thẻ nào trong số đó. Sử dụng vùng chứa và trình lặp hoặc tạo loại dữ liệu mới (ví dụ: cơ sở dữ liệu của nhân viên), cung cấp quyền truy cập vòng lặp/dải ô.

Đối với unsigned, Bjarne Stroustrup đã viết trong TCPL:

Các loại unsigned integer là lý tưởng cho sử dụng trong trị liệu lưu trữ như một mảng bit. Sử dụng một unsigned thay vì một int để đạt được một chút nữa để đại diện cho các số nguyên dương là gần như không bao giờ là một ý tưởng tốt . Nỗ lực để đảm bảo rằng một số giá trị dương tính bằng cách tuyên bố biến không được ký sẽ thường bị đánh bại bởi quy tắc chuyển đổi ngụ ý ẩn.

1

size_t được thiết kế đặc biệt để xác định kích thước bộ nhớ (tính theo byte) của một giá trị. Đây là loại biểu thức sizeof.

Bạn chỉ nên sử dụng size_t cho mục đích này, cho những thứ khác bạn nên sử dụng int hoặc xác định loại của riêng bạn.

Xem thêm Wikipedia.

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