Tôi tìm định nghĩa của size_t ở đâu?


123

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.).



@kjfletch: hhhmmm, thật kỳ lạ khi tìm kiếm cụm từ 'size_t' (như tôi đã làm trước đây) không trả lại câu hỏi đó.
Eliseo Ocampos

1
@Eliseo - Chức năng tìm kiếm của Stackoverflow thật tệ. Thay vào đó, hãy sử dụng Google với tham số 'site: stackoverflow.com'.
Michael Burr

8
OP đã hỏi cụ thể Tôi tìm định nghĩa của size_t ở đâu? Tôi đã hạ cánh ở đây để tìm kiếm điều tương tự. Phần trùng lặp được trích dẫn không thảo luận về việc tìm tuyên bố ở đâu.
jww

9
Câu hỏi này rõ ràng không giống với câu hỏi được liên kết. "Tôi tìm thấy thứ gì đó ở đâu" không giống với "Sự khác biệt giữa là gì" (ngay cả khi câu trả lời cho câu hỏi này cung cấp câu trả lời cho câu hỏi kia). Tìm kiếm trên Google của tôi cho 'định nghĩa c ++ ở đâu là size_t' đã đưa tôi đến thẳng đây và tôi sẽ bỏ lỡ câu hỏi khác, vì nó khác .
Dan Nissenbaum

Câu trả lời:


122

Từ Wikipedia

Tệp tiêu đề stdlib.hstddef.htệp tiêu đề xác định một kiểu dữ liệu được gọi là size_t1 đượ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ại size_tvà toán tử sizeof đánh giá thànhsize_t .

Loại thực tế size_tphụ thuộc vào nền tảng; một sai lầm phổ biến là giả định size_tlà 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.

Từ C99 7.17.1 / 2

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


2
Ví dụ, trên Win64, intunsigned intcác loại là 32 bit, trong khi size_t là 64 bit.
Michael Burr

7
Vui lòng tham khảo tiêu chuẩn ISO C (99) (mà từ đó các tiêu chuẩn C ++ bao gồm) phần 7,17 và 7.18.3
Martin York

3
@LokiAstari tại sao bạn không chỉnh sửa câu trả lời vì bạn biết nó được viết ở đâu trong tiêu chuẩn?
Hi-Angel

Vậy câu trả lời C ++ nằm ở đâu?
Lothar

@Lothar Tôi nghĩ sự khác biệt duy nhất là size_t có thể là một từ khóa, và nếu không thì có cùng ý nghĩa.
Paul Stelian

30

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>

2
Đây chính xác là những gì tôi cần, câu trả lời này sẽ được ủng hộ.
neodelphi

27

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 sizeofnhà đ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.)


Câu trả lời tốt nhất vì nó trích dẫn tiêu chuẩn.
Martin York

1
@Martin - đủ đúng, nhưng tôi nghĩ rằng phần 'tại sao không dấu int được sử dụng' của câu hỏi cũng thú vị (hoặc hơn) như phần 'size_t là gì' và bạn sẽ không tìm thấy điều đó trong tiêu chuẩn .
Michael Burr

Vâng, ngoại trừ không có 'Mục 17.17 ': p. Đó là hiếm, không ai nói một lời nào về Void_t
Eliseo Ocampos

Tôi chấp nhận câu trả lời này vì nó trả lời trực tiếp câu hỏi, nhưng sẽ thật tuyệt nếu nó được khen với câu trả lời của Michael.
Eliseo Ocampos 14/07/09

58
Đáng tiếc, câu trả lời của bạn không cho tôi biết phải bao gồm tệp tiêu đề nào.
Matt

6

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 uintrấ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".


2

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 inthay 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_ttương ứng với kiểu dữ liệu tích phân được trả về bởi toán tử ngôn ngữ sizeofvà đượ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ố numtrong chức năng memchr, memcmp, memcpy, memmove, memset, strncat, strncmp, strncpystrxfrm, 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, strspnstrxfrmkích thước trở lại và độ dài.


2

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.


1

Tôi không quen với void_tngoại trừ như là kết quả của một tìm kiếm Google (nó được sử dụng trong một vmallocthư 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ụ:

  • size_t tóm tắt kiểu được sử dụng để chứa kích thước của các đối tượng vì trên một số hệ thống, đây sẽ là giá trị 32 bit, trên những hệ thống khác, nó có thể là 16 bit hoặc 64 bit.
  • Void_ttóm tắt loại con trỏ được trả về bởi các vmallocquy 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 đó voidtừ 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_tloạ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.


Đây là những gì tôi đang tìm kiếm, một phần. Như tôi đã nói trong một chú thích trong câu trả lời của fpmurphy, nó sẽ là tuyệt vời mà nó có thể được bổ sung với câu trả lời này (Nếu bạn không nhớ có thể bạn có thể chỉnh sửa nó) :)
Eliseo Ocampos

1

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.)


1

Đố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ụ, typedefd như một intvà sau đó được nâng cấp lên longsau 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_tphù hợp và được sử dụng để chứa kích thước của mọi thứ, giống như time_tthí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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.