Sự khác biệt giữa size_t và int unsigned?


107

Tôi rất bối rối về size_t. Tôi đã tìm kiếm trên internet và ở khắp mọi nơi đề cập rằng size_tloại không dấu, vì vậy, nó chỉ có thể đại diện cho các giá trị không âm.

Câu hỏi đầu tiên của tôi là: nếu nó chỉ được sử dụng để đại diện cho các giá trị không âm, tại sao chúng ta không sử dụng unsigned intthay vì size_t?

Câu hỏi thứ hai của tôi là: có size_tvà có thể unsigned inthoán đổi cho nhau hay không? Nếu không, thì tại sao?

Và bất cứ ai có thể cho tôi một ví dụ điển hình size_tvà ngắn gọn về hoạt động của nó được không?


5
typedef /*This part is implementation dependent */ size_t;
P0W

5
bản sao có thể có của int unsigned so với size_t

Câu trả lời:


87

nếu nó được sử dụng để biểu thị giá trị không âm, vậy tại sao chúng tôi không sử dụng unsigned intthay vìsize_t

unsigned intkhông phải là kiểu số nguyên không dấu duy nhất. size_tcó thể là bất kỳ unsigned char, unsigned short, unsigned int, unsigned longhoặc unsigned long long, tùy thuộc vào việc thực hiện.

Câu hỏi thứ hai là đó size_tunsigned intcó thể hoán đổi cho nhau hay không và nếu không thì tại sao?

Chúng không thể hoán đổi cho nhau, vì lý do đã giải thích ở trên ^^.

Và bất cứ ai có thể cho tôi một ví dụ điển hình về size_t và cách làm việc ngắn gọn của nó được không?

Tôi không hiểu ý bạn là "nó hoạt động ngắn gọn". Nó hoạt động giống như bất kỳ kiểu không dấu nào khác (đặc biệt, giống như kiểu mà nó được đánh dấu vào). Bạn được khuyến khích sử dụng size_tkhi bạn đang mô tả kích thước của một đối tượng. Đặc biệt, sizeoftoán tử và các chức năng thư viện tiêu chuẩn khác nhau, chẳng hạn như strlen()trả về size_t.

Phần thưởng: đây là một bài báo hay về size_t(và ptrdiff_tloại có liên quan chặt chẽ ). Nó lý do rất tốt tại sao bạn nên sử dụng nó.


1
Làm thế nào chính xác có thể size_tlà một unsigned char? Điều này có nằm trong tiêu chuẩn mà nó được phép không? Ý tôi là với ý tưởng đó, làm thế nào để mọi người có thể sử dụng calloc()(và gia đình), strlen()v.v.? Điều đó đối với tôi dường như vô lý.
Pryftan

Tôi nghĩ size_tđược định nghĩa trong tiêu chuẩn là "kiểu số nguyên không dấu", nhưng không yêu cầu nó phải giống với bất kỳ kiểu nào unsigned {char, short, int, long, long long}.
Paul Hankin

80

Có 5 kiểu số nguyên không dấu tiêu chuẩn trong C:

  • unsigned char
  • unsigned short
  • unsigned int
  • unsigned long
  • unsigned long long

với các yêu cầu khác nhau về kích thước và phạm vi của chúng (ngắn gọn, phạm vi của mỗi loại là một tập hợp con của phạm vi loại tiếp theo, nhưng một số trong số chúng có thể có cùng phạm vi).

size_tlà một typedef(tức là một bí danh) cho một số kiểu không dấu, (có thể là một trong những kiểu trên nhưng có thể là một kiểu số nguyên không dấu mở rộng , mặc dù điều đó khó xảy ra). Đó là kiểu do sizeofnhà điều hành mang lại .

Trên một hệ thống, có thể hợp lý khi sử dụng unsigned intđể biểu thị kích thước; mặt khác, nó có thể có ý nghĩa hơn khi sử dụng unsigned longhoặc unsigned long long. ( size_tkhông chắc là unsigned charhoặc unsigned short, nhưng được phép).

Mục đích của việc size_tlà để giảm các lập trình viên khỏi phải lo lắng về trong những loại được xác định trước được sử dụng để đại diện cho kích cỡ.

Mã giả định sizeofmang lại một unsigned intsẽ không di động được. Mã giả định nó mang lại một mã size_tcó nhiều khả năng di động hơn.


6
Tôi nghĩ rằng đây sẽ là câu trả lời được chấp nhận vì nó giải thích lý do tại sao bạn nên sử dụng size_t
Tư Quy

@ keith-thompson nên này có ý nghĩa rằng loại hình cụ thể (ví dụ unsigned int, unsigned longvv) mà size_ttương ứng với phụ thuộc vào máy tính mà trên đó các mã được chạy? tức là trên một kiến ​​trúc máy, nó tương ứng với unsigned intnhưng trên một kiến ​​trúc khác, nó sẽ tương ứng với unsigned long, v.v.?
Richie Thomas

1
@RichieThomas: Nó phụ thuộc vào việc triển khai C. Hai trình biên dịch khác nhau trên cùng một kiến ​​trúc có thể chọn các kiểu khác nhau size_t, đặc biệt là nếu, ví dụ, unsigned longunsigned long longcó cùng kích thước.
Keith Thompson

@RichieThomas Đó cũng là một phần của nó. Điều đó có nghĩa là giá trị tối đa của long, long longv.v. phụ thuộc vào hệ thống: Nếu bạn nhìn vào hệ thống, limits.hít nhất bạn sẽ thấy rằng giá trị tối đa cho số nguyên phụ thuộc vào kích thước từ của hệ thống.
Pryftan

1
@Pryftan Hãy nhìn vào dòng Motorola 68000, cũng là dòng Intel x86 cũ hơn (trở lại 8086 và 8088).
Keith Thompson

10

size_t có một hạn chế cụ thể.

Trích dẫn từ http://www.cplusplus.com/reference/cstring/size_t/ :

Bí danh của một trong những kiểu số nguyên không dấu cơ bản.

Đây là một kiểu có thể biểu diễn kích thước của bất kỳ đối tượng nào theo byte : size_t là kiểu được trả về bởi toán tử sizeof và được sử dụng rộng rãi trong thư viện chuẩn để biểu diễn kích thước và số lượng.

Nó không thể hoán đổi cho nhau unsigned intvì kích thước của intđược chỉ định bởi mô hình dữ liệu. Ví dụ LLP64 sử dụng 32-bit intvà ILP64 sử dụng 64-bit int.


5
Đó là trích dẫn từ đâu? (Nó không phải từ các tiêu chuẩn C.)
Keith Thompson

2
Câu hỏi được gắn thẻ c . Tiêu chuẩn C ++ không liên quan đến C.
IInspectable

7

size_t được sử dụng để lưu trữ kích thước của các đối tượng dữ liệu và được đảm bảo có thể giữ kích thước của bất kỳ đối tượng dữ liệu nào mà việc triển khai C cụ thể có thể tạo ra. Kiểu dữ liệu này có thể nhỏ hơn (tính theo số bit), lớn hơn hoặc giống hệt kiểu int không dấu.


4

Ngoài các câu trả lời khác, nó cũng ghi lại mã và cho mọi người biết rằng bạn đang nói về kích thước của các đối tượng trong bộ nhớ


Điểm tốt. An applelà một quả táo , a size_tlà một kích thước ...
dom_beau

2

kiểu size_t là kiểu số nguyên không dấu cơ sở của ngôn ngữ C / C ++. Đây là kiểu kết quả được trả về bởi toán tử sizeof. Kích thước của kiểu được chọn để nó có thể lưu trữ kích thước tối đa của một mảng về mặt lý thuyết thuộc bất kỳ kiểu nào. Trên hệ thống 32 bit, size_t sẽ chiếm 32 bit, trên 64 bit một 64 bit. Nói cách khác, một biến kiểu size_t có thể lưu một con trỏ một cách an toàn. Ngoại lệ là con trỏ đến các hàm lớp nhưng đây là một trường hợp đặc biệt. Mặc dù size_t có thể lưu trữ một con trỏ, nhưng tốt hơn là sử dụng một kiểu số nguyên không dấu khác uintptr_t cho mục đích đó (tên của nó phản ánh khả năng của nó). Các loại size_t và uintptr_t là các từ đồng nghĩa. kiểu size_t thường được sử dụng cho các bộ đếm vòng lặp, lập chỉ mục mảng và số học địa chỉ. Giá trị tối đa có thể có của loại size_t là hằng số SIZE_MAX.


1
size_tcó thể lưu trữ kích thước của bất kỳ đối tượng đơn lẻ nào. Một con trỏ có thể trỏ đến bất kỳ byte nào của bất kỳ đối tượng nào. Ví dụ: bạn có thể có một hệ thống với không gian địa chỉ 64 bit giới hạn kích thước của bất kỳ đối tượng nào là 2 ** 32-1 byte. Không có gì đảm bảo rằng size_tuintptr_tlà cùng một loại.
Keith Thompson

1

Nói một cách đơn giản size_t là nền tảng và cũng như việc triển khai phụ thuộc trong khi int unsigned chỉ phụ thuộc vào nền tảng.

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.