Trong một số ví dụ về C ++, tôi thấy việc sử dụng kiểu size_tmà tôi sẽ sử dụng một cách đơn giản int. Sự khác biệt là gì, và tại sao size_tnên tốt hơn?
Trong một số ví dụ về C ++, tôi thấy việc sử dụng kiểu size_tmà tôi sẽ sử dụng một cách đơn giản int. Sự khác biệt là gì, và tại sao size_tnên tốt hơn?
Câu trả lời:
Từ Wikipedia thân thiện :
Các tệp tiêu đề stdlib.h và stddef.h xác định một kiểu dữ liệu được gọi là size_t được sử dụng để thể hiện kích thước của một đối tượng. Các hàm thư viện có kích thước dự kiến chúng có kiểu size_t và toán tử sizeof ước tính thành size_t.
Loại size_t thực tế phụ thuộc vào nền tảng; một lỗi phổ biến là giả sử size_t giống như int unsign, điều này có thể dẫn đến lỗi lập trình, đặc biệt khi kiến trúc 64 bit trở nên phổ biến hơn.
Ngoài ra, hãy kiểm tra Tại sao size_t quan trọng
/usr/include/stdlib.hcó định nghĩa từ /usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.hđó và mặc định nó được mặc định long unsigned inttrừ khi một số tệp tiêu đề khác nói khác.
size_t là loại được sử dụng để thể hiện kích thước (như tên của nó ngụ ý). Nền tảng của nó (và thậm chí có khả năng thực hiện) phụ thuộc và chỉ nên được sử dụng cho mục đích này. Rõ ràng, đại diện cho một kích thước, size_t là không dấu. Nhiều hàm stdlib, bao gồm malloc, sizeof và các hàm hoạt động chuỗi khác nhau sử dụng size_t làm kiểu dữ liệu.
Một int được ký theo mặc định và mặc dù kích thước của nó cũng phụ thuộc vào nền tảng, nó sẽ là 32 bit cố định trên hầu hết các máy hiện đại (và mặc dù size_t là 64 bit trên kiến trúc 64 bit, int vẫn dài 32 bit trên các kiến trúc đó).
Để tóm tắt: sử dụng size_t để thể hiện kích thước của một đối tượng và int (hoặc dài) trong các trường hợp khác.
Các size_tloại được định nghĩa là loại không thể thiếu unsigned của sizeofnhà điều hành. Trong thế giới thực, bạn sẽ thường thấy intđược xác định là 32 bit (để tương thích ngược) nhưng size_tđược xác định là 64 bit (để bạn có thể khai báo các mảng và cấu trúc có kích thước hơn 4 GiB) trên nền tảng 64 bit. Nếu a long intcũng là 64 bit, đây được gọi là quy ước LP64; nếu long intlà 32 bit nhưng long long intvà con trỏ là 64 bit, đó là LLP64. Bạn cũng có thể nhận được điều ngược lại, một chương trình sử dụng các hướng dẫn 64 bit cho tốc độ, nhưng con trỏ 32 bit để tiết kiệm bộ nhớ. Ngoài ra, đã intđược ký vàsize_t không dấu.
Trước đây, có một số nền tảng khác có địa chỉ rộng hơn hoặc ngắn hơn kích thước gốc int . Trên thực tế, trong thập niên 70 và đầu thập niên 80, điều này phổ biến hơn không phải: tất cả các máy vi tính 8 bit phổ biến đều có thanh ghi 8 bit và địa chỉ 16 bit, và quá trình chuyển đổi giữa 16 và 32 bit cũng tạo ra nhiều máy. có địa chỉ rộng hơn đăng ký của họ. Thỉnh thoảng tôi vẫn thấy các câu hỏi ở đây về Borland Turbo C cho MS-DOS, chế độ bộ nhớ khổng lồ có địa chỉ 20 bit được lưu trữ trong 32 bit trên CPU 16 bit (nhưng có thể hỗ trợ tập lệnh 32 bit của 80386); Motorola 68000 có ALU 16 bit với các thanh ghi và địa chỉ 32 bit; có các máy tính lớn của IBM với các địa chỉ 15 bit, 24 bit hoặc 31 bit. Bạn cũng vẫn thấy các kích thước ALU và bus địa chỉ khác nhau trong các hệ thống nhúng.
Bất kỳ thời gian nào intnhỏ hơn size_tvà bạn cố gắng lưu trữ kích thước hoặc phần bù của một tệp hoặc đối tượng rất lớn trong một unsigned int, có khả năng nó có thể tràn và gây ra lỗi. Với một int, cũng có khả năng nhận được một số âm. Nếu một inthoặc unsigned intrộng hơn, chương trình sẽ chạy chính xác nhưng lãng phí bộ nhớ.
Bạn thường nên sử dụng đúng loại cho mục đích nếu bạn muốn tính di động. Rất nhiều người sẽ khuyên bạn nên sử dụng toán đã ký thay vì không dấu (để tránh những lỗi khó chịu, tinh tế như 1U < -3). Vì mục đích đó, các định nghĩa thư viện chuẩn ptrdiff_ttrong <stddef.h>như các loại ký về kết quả trừ đi một con trỏ từ khác.
Điều đó nói rằng, một cách giải quyết có thể là giới hạn - kiểm tra tất cả các địa chỉ và giá trị chống lại INT_MAX và một trong hai 0hoặc INT_MINnếu thích hợp, và bật cảnh báo trình biên dịch về so sánh chữ ký và số lượng unsigned trong trường hợp bạn bỏ lỡ bất kỳ. Bạn nên luôn luôn, luôn luôn, luôn luôn kiểm tra truy cập mảng của bạn xem có bị tràn trong C không.
Đó là bởi vì size_t có thể là bất cứ thứ gì khác ngoài int (có thể là struct). Ý tưởng là nó tách riêng công việc của nó từ loại cơ bản.
size_tđược chỉ định là một kiểu số nguyên không dấu . C11 §6.5.3.4 5 "Giá trị kết quả của cả hai toán tử ( sizeof _Alignof) được xác định theo thực hiện và loại của nó (một kiểu số nguyên không dấu) là size_t,".
Định nghĩa của SIZE_Tđược tìm thấy tại:
https://msdn.microsoft.com/en-us/l Library / cc441980.aspx và https://msdn.microsoft.com/en-us/l Library / cc230394.aspx
Dán ở đây các thông tin cần thiết:
SIZE_Tlà một ULONG_PTRđại diện cho số byte tối đa mà con trỏ có thể trỏ tới.
Loại này được khai báo như sau:
typedef ULONG_PTR SIZE_T;
A ULONG_PTRlà một loại dài không dấu được sử dụng cho độ chính xác của con trỏ. Nó được sử dụng khi truyền một con trỏ thành một loại dài để thực hiện số học con trỏ.
Loại này được khai báo như sau:
typedef unsigned __int3264 ULONG_PTR;
SIZE_TKhông size_t, những gì OP hỏi về.
SIZE_Tlà hoàn toàn khác với size_t. Bạn không thể khai báo một biến loại SIZE_T.