Sự khác biệt giữa những gì lâu dài, một thời gian dài, một thời gian dài, một thời gian dài, và lâu dài


209

Tôi đang chuyển từ Java sang C ++ và có một số câu hỏi về longkiểu dữ liệu. Trong Java, để giữ một số nguyên lớn hơn 2 32 , bạn chỉ cần viết long x;. Tuy nhiên, trong C ++, dường như đó longlà cả kiểu dữ liệu và công cụ sửa đổi.

Dường như có một số cách để sử dụng long:

long x;
long long x;
long int x;
long long int x;

Ngoài ra, có vẻ như có những thứ như:

long double x;

và như thế.

Sự khác biệt giữa tất cả các loại dữ liệu khác nhau này và chúng có cùng mục đích không?



2
@ user2612743 - để an toàn, hãy suy nghĩ về những yêu cầu của bạn và sử dụng loại phù hợp. long longcó thể chậm hơn long, có thể chậm hơn int.
Pete Becker


1
Không, "để an toàn, sử dụng lâu dài" cũng giống như câu nói "để an toàn, chỉ cần cung cấp cho mọi người một căn bệnh AIDS, vì vậy chúng tôi không phải lo lắng về tình dục an toàn, dù sao chúng ta cũng đã có nó!" Ngớ ngẩn, không? Hãy suy nghĩ về dữ liệu và những giá trị có thể có của nó và sử dụng loại phù hợp nhất. Điều này cũng giúp trình biên dịch thực hiện tối ưu hóa bổ sung mà không phá vỡ mục đích mã ban đầu, chẳng hạn như nếu nó phải tải các thư viện bổ sung để xử lý các số lớn hơn độ rộng bit tự nhiên của nền tảng đích.
CM

Sử dụng lâu dài với các hộp danh sách win32 và những thứ tương tự sẽ không chơi tàn phá với bộ nhớ của bạn và các biến khác - ngay cả khi các giới hạn không bị vi phạm. Ngay cả với cảnh báo C4244 vô hại, nó cũng không dễ phát hiện.
Laurie Stearn

Câu trả lời:


182

longlong intgiống hệt nhau. Vậy là long longlong long int. Trong cả hai trường hợp, intlà tùy chọn.

Đối với phần chênh lệch giữa hai bộ, C ++ nhiệm vụ chuẩn dãy tối thiểu cho mỗi, và đó long longlà tại ít nhất rộng như long.

Các phần điều khiển của tiêu chuẩn (C ++ 11, nhưng điều này đã có từ lâu), đối với một 3.9.1 Fundamental types, phần 2 (phần sau đưa ra các quy tắc tương tự cho các loại tích phân không dấu):

Có năm loại số nguyên được ký tiêu chuẩn: ký char, short int, int, long int và long long int. Trong danh sách này, mỗi loại cung cấp ít nhất dung lượng lưu trữ như những loại trước nó trong danh sách.

Ngoài ra còn có một bảng 9 7.1.6.2 Simple type specifiers, trong đó hiển thị "ánh xạ" của các chỉ định đến các loại thực tế (cho thấy rằng đó intlà tùy chọn), một phần trong đó được hiển thị bên dưới:

Specifier(s)         Type
-------------    -------------
long long int    long long int
long long        long long int
long int         long int
long             long int

Lưu ý phân biệt ở đó giữa specifier và loại. Trình xác định là cách bạn nói với trình biên dịch loại đó là gì nhưng bạn có thể sử dụng các trình xác định khác nhau để kết thúc cùng một loại.

Do đó, longbản thân nó không phải là loại cũng không phải là công cụ sửa đổi như câu hỏi của bạn, nó chỉ đơn giản là một công cụ xác định cho long intloại. Ditto long longlà một specifier cho các long long intloại.

Mặc dù bản thân tiêu chuẩn C ++ không chỉ định phạm vi tối thiểu của các loại tích phân, nhưng nó trích dẫn C99 1.2 Normative references, khi áp dụng. Do đó, phạm vi tối thiểu như quy định trong C99 5.2.4.2.1 Sizes of integer types <limits.h>được áp dụng.


Về mặt long double, đó thực sự là một giá trị dấu phẩy động chứ không phải là một số nguyên. Tương tự như các loại tích phân, yêu cầu phải có độ chính xác ít nhất bằng một doublevà để cung cấp siêu giá trị cho loại đó (nghĩa là ít nhất là các giá trị đó, không nhất thiết phải có nhiều giá trị hơn ).


4
điều tương tự với unsignedunsigned int
Kal

2
Tôi khá chắc chắn longlà ít nhất 32 bit (2 ^ 31-1 ở hai bên của số 0) và long longít nhất là 64 (2 ^ 63-1 ở hai bên).
Chris

2
long doubleđược đảm bảo có ít nhất là phạm vi double, nhưng nó có thể giống nhau. Nó phụ thuộc vào máy tính. Một số FPU có độ chính xác mở rộng; các chip x87 có độ chính xác đơn 32 bit, độ chính xác kép 64 bit và độ chính xác mở rộng 80 bit.
Eric Jablow

Đối với các yêu cầu phạm vi, tiêu chuẩn C ++ 11 tham chiếu tiêu chuẩn C11, có phạm vi thực tế.
Chris

Phần "int" chỉ phân biệt giữa kiểu số nguyên và dấu phẩy động, ký tự hoặc loại không nguyên khác. Trong nhiều trường hợp, điều này có thể được suy ra bởi trình biên dịch, vì vậy nó có thể bị loại bỏ - Đây là lý do tại sao "unsign" giống như "unsign int", chẳng hạn. Phần "int" được giả định đơn giản trừ khi lập trình viên chỉ định một cái gì đó khác, chẳng hạn như "char" hoặc "double". Đối với kích thước thực tế được sử dụng .. tùy thuộc vào tiêu chuẩn bạn đọc, mỗi kích thước có thể có số bit tối thiểu, nhưng tất cả chúng đều được xác định sao cho mỗi kích thước ít nhất bằng loại trước đó.
CM


17

longlà tương đương với long int, shorttương tự như short int. A long intlà loại tích phân đã ký có ít nhất 32 bit, trong khi a long longhoặc long long intlà loại tích phân đã ký ít nhất là 64 bit.

Điều này không nhất thiết có nghĩa là a long longrộng hơn a long. Nhiều nền tảng / ABI sử dụng LP64mô hình - trong đó long(và con trỏ) rộng 64 bit. Win64 sử dụng LLP64, nơi longvẫn còn 32 bit và long long(và con trỏ) rộng 64 bit.

Có một bản tóm tắt tốt về các mô hình dữ liệu 64 bit ở đây .

long doublekhông đảm bảo nhiều hơn nó sẽ ít nhất là rộng bằng a double.


7

Điều này có vẻ khó hiểu bởi vì bạn đang dùng longnhư một kiểu dữ liệu.

longkhông là gì ngoài việc viết tắt long intkhi bạn đang sử dụng nó một mình.

longlà một modifier, bạn có thể sử dụng nó với doublecũng như long double.

long== long int.

Cả hai đều mất 4 byte.



1
Vâng, rõ ràng ... không chỉ dài ... int mất 4 byte và 2 byte phụ thuộc vào nền tảng, không còn nghi ngờ gì nữa.
Siraj Alam

3

Trong lịch sử, vào thời kỳ đầu C, khi các bộ xử lý có wordlength 8 hoặc 16 bit, intgiống hệt với ngày nay short(16 bit). Theo một nghĩa nào đó, int là một kiểu dữ liệu trừu tượng hơn char, short, longhoặc long long, như bạn không thể chắc chắn về bitwidth.

Khi xác định, int n;bạn có thể dịch phần này với "cung cấp cho tôi sự thỏa hiệp tốt nhất về băng thông và tốc độ trên máy này cho n". Có thể trong tương lai bạn nên mong đợi trình biên dịch dịch intthành 64 bit. Vì vậy, khi bạn muốn biến của mình có 32 bit và không nhiều hơn, tốt hơn nên sử dụng một longloại dữ liệu rõ ràng .

[Chỉnh sửa: #include <stdint.h>dường như là cách thích hợp để đảm bảo băng thông bit sử dụng các loại int ## _ t, mặc dù nó chưa phải là một phần của tiêu chuẩn.]


2
Phần cuối cùng đó, sử dụng "dài" để nhận 32 bit khi int là 64 bit, không chính xác. Nếu int là 64 bit, thì dài cũng sẽ có ít nhất 64 bit. Long được đảm bảo ít nhất là lớn như int, mặc dù nó có thể lớn hơn, nhưng không bao giờ nhỏ hơn. Hầu hết các trình biên dịch có các phương thức khác nhau cho phép lập trình viên cụ thể hơn, chẳng hạn như loại __int32 (không di động) chính xác là 32 bit, v.v.
CM

1
Như được định nghĩa trong tiêu chuẩn C, a longđược đảm bảo tối thiểu 32 bit. (Các tiêu chuẩn có thể thay đổi khó khăn.) Bản nháp C ++ 14 hiện tại chỉ nói: @CM "Các số nguyên có kích thước tự nhiên được đề xuất bởi kiến ​​trúc của môi trường thực thi, các loại số nguyên đã ký khác được cung cấp để đáp ứng các nhu cầu đặc biệt" (phần 3.9.1 ). Tôi không tìm thấy từ nào về mối quan hệ chiều dài của các số nguyên khác nhau trong đó. __int32 không thực sự là một phần của tiêu chuẩn, nhưng vì C ++ 11 có sẵn các typedefs như int_fast32_t hoặc int_least32_t để có được chính xác những gì bạn muốn.
thomiel

Tôi muốn nói rằng trong các triển khai của thế kỷ XX cho các máy vi tính có thể lập trình lại cho mục đích chung, charhầu như chỉ có 8 bit, shortlà 16 và longlà 32; intcó thể là 16 hoặc 32. Lưu ý đối với một số nền tảng (đặc biệt là 68000) cả 16 bit và 32 bit intđều khá phổ biến và thực sự một số trình biên dịch có các tùy chọn để hỗ trợ. Do đó, mã cần phải di động được dự kiến ​​sẽ sử dụng shorthoặc longưu tiên int.
supercat

0

Mặc dù trong Java a longluôn là 64 bit, nhưng trong C ++, điều này phụ thuộc vào kiến ​​trúc máy tính và hệ điều hành . Ví dụ: a longlà 64 bit trên Linux và 32 bit trên Windows (điều này được thực hiện để giữ khả năng tương thích ngược, cho phép các chương trình 32 bit biên dịch trên Windows 64 bit mà không có bất kỳ thay đổi nào).

Nó được coi là phong cách C ++ tốt để tránh short int long ... và thay vào đó sử dụng:

std::int8_t   # exactly  8 bits
std::int16_t  # exactly 16 bits
std::int32_t  # exactly 32 bits
std::int64_t  # exactly 64 bits

std::size_t   # can hold all possible object sizes, used for indexing

Những ( int*_t) có thể được sử dụng sau khi bao gồm <cstdint>tiêu đề. size_tlà trong <stdlib.h>.

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.