Tôi thấy các biến được định nghĩa với kiểu này nhưng tôi không biết nó đến từ đâu, cũng như mục đích của nó là gì. Tại sao không sử dụng int hoặc int unsigned? (Còn các kiểu "tương tự" khác thì sao? Void_t, v.v.).
Tôi thấy các biến được định nghĩa với kiểu này nhưng tôi không biết nó đến từ đâu, cũng như mục đích của nó là gì. Tại sao không sử dụng int hoặc int unsigned? (Còn các kiểu "tương tự" khác thì sao? Void_t, v.v.).
Câu trả lời:
Từ Wikipedia
Tệp tiêu đề
stdlib.h
vàstddef.h
tệp tiêu đề xác định một kiểu dữ liệu được gọi làsize_t
1 được sử dụng để biểu thị kích thước của một đối tượng. Các hàm thư viện có kích thước mong muốn chúng thuộc loạisize_t
và toán tử sizeof đánh giá thànhsize_t
.Loại thực tế
size_t
phụ thuộc vào nền tảng; một sai lầm phổ biến là giả địnhsize_t
là giống như int unsigned, có thể dẫn đến sai sót lập trình, 2 đặc biệt là kiến trúc 64-bit trở nên phổ biến hơn.
Các loại và macro sau được xác định trong tiêu đề chuẩn
stddef.h
<snip>
size_t
là kiểu số nguyên không dấu của kết quả của toán tử sizeof
int
và unsigned int
các loại là 32 bit, trong khi size_t là 64 bit.
Theo mô tả size_t trên en.cppreference.com size_t
được định nghĩa trong các tiêu đề sau:
std::size_t
...
Defined in header <cstddef>
Defined in header <cstdio>
Defined in header <cstring>
Defined in header <ctime>
Defined in header <cwchar>
size_t
là kiểu số nguyên không dấu của kết quả của toán tử sizeof (ISO C99 Mục 7.17.)
Các sizeof
nhà điều hành mang lại kích thước (tính theo byte) của toán hạng của nó, có thể là một biểu thức hoặc tên trong ngoặc của một loại. Kích thước được xác định từ loại toán hạng. Kết quả là một số nguyên. Giá trị của kết quả là implement-de fi ned và kiểu của nó (kiểu số nguyên không dấu) là size_t
(ISO C99 Mục 6.5.3.4.)
Thực tế mà nói size_t
đại diện cho số byte bạn có thể giải quyết. Trên hầu hết các kiến trúc hiện đại trong 10-15 năm qua, 32 bit cũng là kích thước của một int không dấu. Tuy nhiên, chúng tôi đang chuyển sang định địa chỉ 64bit trong khi uint
rất có thể sẽ ở mức 32bit (kích thước của nó không được đảm bảo trong tiêu chuẩn c ++). Để làm cho mã của bạn phụ thuộc vào kích thước bộ nhớ di động qua các kiến trúc, bạn nên sử dụng a size_t
. Ví dụ, những thứ như kích thước mảng nên luôn sử dụng size_t
's. Nếu bạn nhìn vào các vùng chứa tiêu chuẩn, ::size()
luôn trả về a size_t
.
Cũng xin lưu ý, visual studio có một tùy chọn biên dịch có thể kiểm tra các loại lỗi này được gọi là "Phát hiện các vấn đề về khả năng di động 64-bit".
Bằng cách này, bạn luôn biết kích thước là gì, vì một loại cụ thể dành riêng cho kích thước. Chính câu hỏi cho thấy nó có thể là một vấn đề: nó là một int
hay một unsigned int
? Ngoài ra, độ lớn là gì ( short
, int
,long
, vv)?
Bởi vì có một loại cụ thể được chỉ định, bạn không phải lo lắng về độ dài hoặc ký tự.
Định nghĩa thực tế có thể được tìm thấy trong Thư viện tham chiếu C ++ , cho biết:
Kiểu:
size_t
(Loại tích phân không dấu)Tiêu đề:
<cstring>
size_t
tương ứng với kiểu dữ liệu tích phân được trả về bởi toán tử ngôn ngữsizeof
và được định nghĩa trong<cstring>
tệp tiêu đề (trong số những người khác) là kiểu tích phân không dấu.Trong
<cstring>
, nó được sử dụng như kiểu của tham sốnum
trong chức năngmemchr
,memcmp
,memcpy
,memmove
,memset
,strncat
,strncmp
,strncpy
vàstrxfrm
, mà trong mọi trường hợp nó được sử dụng để xác định số lượng tối đa byte hoặc các ký tự chức năng có ảnh hưởng đến.Nó cũng được sử dụng như là kiểu trả về cho
strcspn
,strlen
,strspn
vàstrxfrm
kích thước trở lại và độ dài.
size_t phải được xác định trong tiêu đề thư viện chuẩn của bạn. Theo kinh nghiệm của tôi, nó thường chỉ đơn giản là một typedef thành unsigned int. Tuy nhiên, vấn đề là nó không nhất thiết phải như vậy. Các loại như size_t cho phép nhà cung cấp thư viện tiêu chuẩn tự do thay đổi các kiểu dữ liệu cơ bản của nó nếu phù hợp với nền tảng. Nếu bạn giả sử size_t luôn là int không dấu (thông qua truyền, v.v.), bạn có thể gặp sự cố trong tương lai nếu nhà cung cấp của bạn thay đổi size_t thành loại 64-bit. Thật nguy hiểm nếu giả định bất kỳ điều gì về điều này hoặc bất kỳ loại thư viện nào khác vì lý do này.
Tôi không quen với void_t
ngoại trừ như là kết quả của một tìm kiếm Google (nó được sử dụng trong một vmalloc
thư viện bằng cách Kiếm-Phong Võ tại AT & T Nghiên cứu - Tôi chắc chắn nó được sử dụng trong các thư viện khác cũng).
Các typedef xxx_t khác nhau được sử dụng để tóm tắt một kiểu từ một triển khai xác định cụ thể, vì các kiểu cụ thể được sử dụng cho một số thứ nhất định có thể khác nhau từ nền tảng này sang nền tảng khác. Ví dụ:
Void_t
tóm tắt loại con trỏ được trả về bởi các vmalloc
quy trình thư viện vì nó được viết để hoạt động trên các hệ thống đã định ngày trước ANSI / ISO C trong đó void
từ khóa có thể không tồn tại. Ít nhất đó là những gì tôi đoán.wchar_t
tóm tắt kiểu được sử dụng cho các ký tự rộng vì trên một số hệ thống, nó sẽ là kiểu 16 bit, trên những hệ thống khác, nó sẽ là kiểu 32 bit.Vì vậy, nếu bạn viết mã xử lý ký tự rộng của mình để sử dụng wchar_t
loại thay vì, chẳng hạn unsigned short
, mã đó có lẽ sẽ dễ di động hơn với các nền tảng khác nhau.
Trong các chương trình tối giản, trong đó một size_t
định nghĩa không được tải "tình cờ" trong một số bao gồm nhưng tôi vẫn cần nó trong một số ngữ cảnh (ví dụ: để truy cập std::vector<double>
), thì tôi sử dụng ngữ cảnh đó để trích xuất loại chính xác. Ví dụtypedef std::vector<double>::size_type size_t
.
(Bao quanh namespace {...}
nếu cần thiết để giới hạn phạm vi.)
Đối với "Tại sao không sử dụng int hoặc unsigned int?", Đơn giản vì nó có ý nghĩa hơn về mặt ngữ nghĩa. Có một lý do thực tế mà nó có thể là, ví dụ, typedef
d như một int
và sau đó được nâng cấp lên long
sau này, tất nhiên mà không cần ai phải thay đổi mã của họ, nhưng về cơ bản hơn là một loại được cho là có ý nghĩa. Để đơn giản hóa rất nhiều, một biến kiểu size_t
phù hợp và được sử dụng để chứa kích thước của mọi thứ, giống như time_t
thích hợp để chứa các giá trị thời gian. Làm thế nào những điều này được thực hiện thực sự phải là công việc của người thực hiện. So với việc chỉ gọi tất cả mọi thứ int
, việc sử dụng các tên kiểu có ý nghĩa như thế này giúp làm rõ ý nghĩa và mục đích của chương trình của bạn, giống như bất kỳ nhóm kiểu phong phú nào.