Sự khác biệt giữa int32, int, int32_t, int8 và int8_t


103

Tôi đã xem qua kiểu dữ liệu int32_ttrong một chương trình C gần đây. Tôi biết rằng nó lưu trữ 32 bit, nhưng không intint32làm như vậy?

Ngoài ra, tôi muốn sử dụng chartrong một chương trình. Tôi có thể sử dụng int8_tthay thế không? Sự khác biệt là gì?

Tóm lại: sự khác biệt giữa int32, int, int32_t, int8 và int8_t trong C là gì?

Câu trả lời:


122

Giữa int32int32_t, (và tương tự như vậy giữa int8int8_t) sự khác biệt khá đơn giản: tiêu chuẩn C xác định int8_tint32_t, nhưng không xác định bất kỳ thứ gì có tên int8hoặc int32- cái sau (nếu chúng tồn tại) có thể là từ một số tiêu đề hoặc thư viện khác (rất có thể trước việc bổ sung int8_tint32_ttrong C99).

Plain inthơi khác một chút so với những cái khác. Trong đó int8_tint32_tmỗi có một kích thước xác định, intcó thể là bất kỳ kích thước> = 16 bit. Tại các thời điểm khác nhau, cả 16 bit và 32 bit đều khá phổ biến (và đối với việc triển khai 64 bit, nó có lẽ phải là 64 bit).

Mặt khác, intđược đảm bảo có mặt trong mọi quá trình triển khai C, ở đâu int8_tint32_tkhông. Mặc dù vậy, có lẽ câu hỏi này có quan trọng với bạn hay không. Nếu bạn sử dụng C trên các hệ thống nhúng nhỏ và / hoặc trình biên dịch cũ hơn, nó có thể là một vấn đề. Nếu bạn chủ yếu sử dụng nó với một trình biên dịch hiện đại trên máy tính để bàn / máy chủ, nó có thể sẽ không.

Rất tiếc - đã bỏ lỡ phần về char. Bạn sẽ sử dụng int8_tthay vì char nếu (và chỉ khi) bạn muốn một kiểu số nguyên được đảm bảo có kích thước chính xác 8 bit. Nếu bạn muốn lưu trữ các ký tự, bạn có thể muốn sử dụng charthay thế. Kích thước của nó có thể khác nhau (về số lượng bit) nhưng nó được đảm bảo là chính xác một byte. Mặc dù vậy, có một điều hơi kỳ lạ: không có gì đảm bảo về việc liệu một đơn nguyên charđược ký hay không có dấu (và nhiều trình biên dịch có thể tạo thành một trong hai, tùy thuộc vào cờ thời gian biên dịch). Nếu bạn cần đảm bảo rằng nó được ký hoặc chưa được ký, bạn cần chỉ định điều đó một cách rõ ràng.


1
@linuxfreak: Không chắc lắm bool_t- chưa bao giờ nghe nói về cái đó trước đây. Tiêu chuẩn C định nghĩa _Boollà một kiểu cài sẵn. boolđược xác định chỉ khi bạn #include <stdbool.h>(dưới dạng macro mở rộng thành _Bool).
Jerry Coffin

5
Bạn đã nói "để triển khai 64 bit, (int) có lẽ phải là 64 bit". Trên thực tế, int là 32-bit trên tất cả các nền tảng 64-bit phổ biến bao gồm Windows, Mac OS X, Linux và các phiên bản UNIX khác nhau. Một ngoại lệ là Cray / UNICOS nhưng chúng đã lỗi mốt trong những ngày này.
Sam Watkins

6
@SamWatkins: Vâng, đó là lý do tại sao tôi cẩn thận nói "nên là", không phải "là". Tiêu chuẩn nói rằng đó là "kích thước tự nhiên được đề xuất bởi kiến ​​trúc", (IMO) có nghĩa là trên bộ xử lý 64 bit, nó thực sự phải là 64 bit (mặc dù, tốt hơn hoặc tệ hơn, bạn hoàn toàn đúng khi nó thường không phải là ' t). Từ quan điểm thực tế hơn, sẽ rất tiện lợi nếu có kiểu 32-bit trong số các kiểu trong C89, và nếu int là 64 bit, long cũng phải có ít nhất 64 bit, vì vậy thường sẽ không có 32 bit kiểu.
Jerry Coffin

2
@barlop: Có. (Cả C và C ++ đều yêu cầu phạm vi tối thiểu là 255 giá trị cho char, vì vậy nó yêu cầu ít nhất 8 bit, nhưng có thể nhiều hơn).
Jerry Coffin

2
Tôi đã luôn luôn theo ấn tượng rằng một byte là chính xác 8 bit, không phải bất cứ nơi nào từ 8 bit trên lên
ErlVolton

18

Kiểu dữ liệu _t là kiểu typedef trong tiêu đề stdint.h, trong khi int là kiểu dữ liệu cơ bản được tạo sẵn. Điều này làm cho _t chỉ khả dụng nếu stdint.h tồn tại. mặt khác int được đảm bảo tồn tại.


1
Tại sao người ta sử dụng _t?
Deven

@Deven Để tránh trường hợp mã của bạn hoạt động ở một nơi nào đó mà không phải ở một nơi khác.
Franklin Yu

2

Hãy luôn nhớ rằng 'kích thước' có thể thay đổi nếu không được chỉ định rõ ràng, vì vậy nếu bạn khai báo

 int i = 10;

Trên một số hệ thống, nó có thể dẫn đến số nguyên 16 bit bằng trình biên dịch và trên một số hệ thống khác, nó có thể dẫn đến số nguyên 32 bit (hoặc số nguyên 64 bit trên các hệ thống mới hơn).

Trong môi trường nhúng, điều này có thể dẫn đến kết quả kỳ lạ (đặc biệt là trong khi xử lý I / O được ánh xạ bộ nhớ hoặc có thể được coi là một tình huống mảng đơn giản), do đó, chúng tôi khuyên bạn nên chỉ định các biến kích thước cố định. Trong các hệ thống cũ, bạn có thể bắt gặp

 typedef short INT16;
 typedef int INT32;
 typedef long INT64; 

Bắt đầu từ C99, các nhà thiết kế đã thêm tệp tiêu đề stdint.h về cơ bản tận dụng các typedef tương tự.

Trên hệ thống dựa trên windows, bạn có thể thấy các mục nhập trong tệp tiêu đề stdin.h như

 typedef signed char       int8_t;
 typedef signed short      int16_t;
 typedef signed int        int32_t;
 typedef unsigned char     uint8_t;

Có khá nhiều thứ khác như số nguyên chiều rộng tối thiểu hoặc các loại số nguyên chiều rộng chính xác, tôi nghĩ không phải là một điều tồi tệ để khám phá stdint.h để hiểu rõ hơn.


1
Mã của bạn có lỗi đánh máy:, typedef short INT16;không phải typedefs short INT16.
Galaxy
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.