ความแตกต่างระหว่าง "ยาว", "ยาวนาน", "long int" และ "long long int" ใน C ++ คืออะไร


209

ฉันกำลังเปลี่ยนจาก Java เป็น C ++ และมีคำถามบางอย่างเกี่ยวกับlongชนิดข้อมูล ใน Java จะถือมากขึ้นกว่า 2 จำนวนเต็ม32long x;คุณก็จะเขียน อย่างไรก็ตามใน C ++ ดูเหมือนว่าlongทั้งชนิดข้อมูลและตัวดัดแปลง

ดูเหมือนจะมีหลายวิธีที่จะใช้long:

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

นอกจากนี้ดูเหมือนว่ามีสิ่งต่าง ๆ เช่น:

long double x;

และอื่น ๆ

อะไรคือความแตกต่างระหว่างชนิดข้อมูลต่าง ๆ เหล่านี้และพวกมันมีจุดประสงค์เดียวกันหรือไม่?



2
@ user2612743 - ปลอดภัยคิดเกี่ยวกับความต้องการของคุณและใช้งานประเภทที่เหมาะสม long longอาจจะช้ากว่าซึ่งอาจจะช้ากว่าlong int
Pete Becker


1
ไม่ "เพื่อความปลอดภัยใช้เวลานาน" ก็เหมือนกับการพูดว่า "ปลอดภัยแค่ให้เอดส์โลกเดียวกับทุกคนดังนั้นเราไม่ต้องกังวลเรื่องเพศที่ปลอดภัยเราทุกคนต่างเข้าใจแล้ว!" ไร้สาระ? คิดเกี่ยวกับข้อมูลและค่าที่เป็นไปได้ที่จะมีและใช้ประเภทที่เหมาะสมที่สุด สิ่งนี้ยังช่วยให้คอมไพเลอร์ทำการปรับแต่งเพิ่มเติมโดยไม่ทำลายเจตนาของโค้ดดั้งเดิมเช่นถ้าต้องโหลดไลบรารี่เพิ่มเติมเพื่อจัดการกับตัวเลขที่ใหญ่กว่าความกว้างบิตตามธรรมชาติของแพลตฟอร์มเป้าหมาย
CM

ใช้เวลานานด้วยกล่องรายการ win32 และสิ่งที่ชอบคือไม่เล่นความเสียหายกับหน่วยความจำของคุณและตัวแปรอื่น ๆ - แม้ว่าจะไม่ถูก จำกัด ก็ตาม ถึงแม้จะมีคำเตือน C4244 ที่ดูไม่น่ากลัวก็ยังไม่สามารถตรวจจับได้ง่าย
Laurie Stearn

คำตอบ:


182

longและlong intเหมือนกัน เพื่อให้มีและlong long long long intในทั้งสองกรณีintนี้เป็นตัวเลือก

ในฐานะที่เป็นความแตกต่างระหว่างทั้งสองชุด, c ++ เอกสารมาตรฐานช่วงขั้นต่ำสำหรับแต่ละและที่long longอยู่ที่อย่างน้อยlongกว้างเท่า

ส่วนการควบคุมของมาตรฐาน (C ++ 11 แต่มีมานานแล้ว) สำหรับหนึ่ง3.9.1 Fundamental typesส่วน 2 (ส่วนต่อมาให้กฎที่คล้ายกันสำหรับประเภทอินทิกรัลที่ไม่ได้ลงนาม):

จำนวนเต็มมาตรฐานที่ลงนามแล้วมีห้าประเภท ได้แก่ ถ่านที่ลงนามไว้, int สั้น, int, long int และ long long int ในรายการนี้แต่ละประเภทมีพื้นที่เก็บข้อมูลอย่างน้อยเท่ากับพื้นที่นำหน้าในรายการ

นอกจากนี้ยังมีตารางที่ 9 ใน7.1.6.2 Simple type specifiersซึ่งแสดง "การแมป" ของตัวระบุเป็นประเภทจริง (แสดงว่าintเป็นตัวเลือก) ส่วนที่แสดงอยู่ด้านล่าง:

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

สังเกตความแตกต่างระหว่างตัวระบุและชนิด ตัวระบุเป็นวิธีที่คุณบอกคอมไพเลอร์ว่าเป็นประเภทใด แต่คุณสามารถใช้ตัวระบุที่แตกต่างกันเพื่อจบที่ประเภทเดียวกัน

ดังนั้นlongด้วยตัวของมันเองไม่ใช่ประเภทหรือตัวดัดแปลงตามคำถามของคุณมันเป็นเพียงตัวระบุสำหรับlong intประเภท เหมือนกันสำหรับlong longการเป็นตัวระบุสำหรับlong long intประเภท

แม้ว่ามาตรฐาน C ++ เองจะไม่ระบุช่วงต่ำสุดของประเภทอินทิกรัล แต่ก็อ้างถึง C99 1.2 Normative referencesซึ่งเป็นการนำไปใช้ ดังนั้นช่วงที่น้อยที่สุดตามที่กำหนดไว้C99 5.2.4.2.1 Sizes of integer types <limits.h>จึงมีผลบังคับใช้


ในแง่ของlong doubleที่จริงแล้วเป็นค่าจุดลอยตัวมากกว่าจำนวนเต็ม ในทำนองเดียวกันกับประเภทอินทิกรัลมันต้องมีความแม่นยำอย่างน้อยที่สุดเท่าที่ a doubleและเพื่อให้ค่า superset มากกว่าประเภทนั้น (หมายถึงค่าเหล่านั้นอย่างน้อยไม่จำเป็นต้องมีค่ามากกว่า )


4
สิ่งเดียวกันกับunsignedและunsigned int
Kal

2
ฉันค่อนข้างแน่ใจว่าlongอย่างน้อย 32 บิต (2 ^ 31-1 ที่ด้านใดด้านหนึ่งของศูนย์) และlong longอย่างน้อย 64 (2 ^ 63-1 บนทั้งสองด้าน)
chris

2
และlong doubleรับประกันว่าจะมีช่วงอย่างน้อยที่สุดdoubleแต่ก็อาจจะเหมือนกัน มันขึ้นอยู่กับคอมพิวเตอร์ FPU บางตัวมีการขยายความแม่นยำ ชิป x87 มีความแม่นยำเดี่ยว 32 บิต, ความแม่นยำสองเท่า 64 บิตและเพิ่มความแม่นยำ 80 บิต
Eric Jablow

สำหรับข้อกำหนดของช่วงมาตรฐาน C ++ 11 อ้างอิงถึงมาตรฐาน C11 ซึ่งมีช่วงจริง
Chris

ส่วน "int" เพียงแค่แยกความแตกต่างระหว่างประเภทจำนวนเต็มและจุดลอยตัวอักขระหรือประเภทที่ไม่ใช่จำนวนเต็มอื่น ๆ ในหลายกรณีนี้สามารถสรุปได้โดยคอมไพเลอร์ดังนั้นจึงสามารถลดลง - นี่คือเหตุผลที่ "unsigned" เป็นเช่นเดียวกับ "unsigned int" ตัวอย่างเช่น ส่วน "int" จะถูกสันนิษฐานง่ายๆเว้นแต่ว่าโปรแกรมเมอร์จะระบุสิ่งอื่นเช่น "char" หรือ "double" สำหรับขนาดที่แท้จริงที่ใช้ .. ขึ้นอยู่กับมาตรฐานที่คุณอ่านแต่ละขนาดอาจมีจำนวนบิตขั้นต่ำ แต่ทั้งหมดกำหนดไว้ว่าอย่างน้อยที่สุดก็ใหญ่พอ ๆ กับประเภทก่อนหน้า
CM


17

longเทียบเท่ากับการlong intเช่นเดียวกับที่เทียบเท่ากับshort short intA long intเป็นประเภทอินทิกรัลที่มีการเซ็นชื่อที่อย่างน้อย 32 บิตในขณะที่ a long longหรือlong long intเป็นอินทิกรัลประเภทที่เซ็นชื่ออย่างน้อย 64 บิต

นี้ไม่ได้หมายความว่าจะกว้างกว่าlong long longแพลตฟอร์ม / ABIs จำนวนมากใช้LP64โมเดล - โดยที่long(และตัวชี้) กว้าง 64 บิต Win64 ใช้ส่วนLLP64ที่longยังคงเป็น 32 บิตและlong long(และตัวชี้) กว้าง 64 บิต

มีบทสรุปที่ดีของข้อมูลแบบ 64 บิตเป็นที่นี่

long doubleไม่ได้รับประกันมาก ๆ กว่ามันจะเป็นอย่างน้อยdoubleที่กว้างเป็น


7

สิ่งนี้ดูสับสนเพราะคุณใช้longเป็นประเภทข้อมูลเอง

longไม่มีอะไรนอกจากเป็นชวเลขlong intเพียงอย่างเดียวเมื่อคุณใช้มันเพียงอย่างเดียว

longเป็นตัวดัดแปลงคุณสามารถใช้กับdoubleได้เช่นlong doubleกัน

longlong int==

ทั้งคู่ใช้เวลา 4 ไบต์


การใช้เวลานานถึง 4 ไบต์จะใช้งานได้ใน Win64 ขึ้นอยู่กับแพลตฟอร์ม
Prodigle

1
เห็นได้ชัดว่า ... ไม่นาน ... int ใช้เวลา 4 ไบต์และ 2 ไบต์ขึ้นอยู่กับแพลตฟอร์มไม่ต้องสงสัยเลย
Siraj Alam

3

ในอดีตในช่วงต้นของซีเมื่อโปรเซสเซอร์มีความยาวของ word 8 หรือ 16 บิตintก็เหมือนกับวันนี้short(16 บิต) ในความรู้สึกบางอย่าง int เป็นชนิดข้อมูลนามธรรมมากกว่าchar, short, longหรือlong longตามที่คุณไม่สามารถตรวจสอบเกี่ยวกับ bitwidth

เมื่อกำหนดint n;คุณสามารถแปลสิ่งนี้ด้วย "ให้ฉันประนีประนอมที่ดีที่สุดของแบนด์วิดท์และความเร็วบนเครื่องนี้สำหรับ n" บางทีในอนาคตคุณควรคาดหวังให้คอมไพเลอร์แปลintเป็น 64 บิต ดังนั้นเมื่อคุณต้องการให้ตัวแปรของคุณมี 32 บิตและไม่มากกว่านั้นให้ใช้longชนิดข้อมูลที่ชัดเจน

[แก้ไข: #include <stdint.h>ดูเหมือนจะเป็นวิธีที่เหมาะสมในการตรวจสอบให้แน่ใจว่าแบนด์วิดท์ที่ใช้ประเภท int ## _t แม้ว่าจะยังไม่ได้เป็นส่วนหนึ่งของมาตรฐาน]


2
ส่วนสุดท้ายนั้นใช้ "ยาว" เพื่อรับ 32- บิตเมื่อ int เป็น 64- บิตไม่ถูกต้อง ถ้า int เป็น 64- บิตความยาวจะเป็นอย่างน้อย 64- บิตเช่นกัน ยาวรับประกันได้ว่าจะอย่างน้อยมีขนาดใหญ่เป็น int แม้ว่ามันอาจจะมีขนาดใหญ่ แต่ไม่เคยมีขนาดเล็กลง คอมไพเลอร์ส่วนใหญ่มีวิธีการต่าง ๆ ที่ทำให้โปรแกรมเมอร์มีความเฉพาะเจาะจงมากขึ้นเช่นชนิด (ไม่ใช่พกพา) __int32 ที่มีขนาด 32 บิตและอื่น ๆ
CM

1
ตามที่กำหนดไว้ในมาตรฐาน C longรับประกันว่าจะมีอย่างน้อย 32 บิต (มาตรฐานอาจเปลี่ยนแปลงยาก) ปัจจุบัน C ++ 14 ฉบับร่างเพิ่งพูดว่า: @CM "ธรรมดา int มีขนาดตามธรรมชาติที่แนะนำโดยสถาปัตยกรรมของสภาพแวดล้อมการดำเนินการชนิดจำนวนเต็มอื่น ๆ ที่ได้รับการลงลายมือชื่อมีไว้เพื่อตอบสนองความต้องการพิเศษ" (ส่วน 3.9.1 ) ฉันไม่พบคำพูดใด ๆ เกี่ยวกับความสัมพันธ์แบบยาวของ ints ต่างๆในนั้น __int32 ไม่ได้เป็นส่วนหนึ่งของมาตรฐานจริง ๆ แต่เนื่องจาก C ++ 11 มี typedefs ที่พร้อมใช้งานเช่น int_fast32_t หรือ int_least32_t พร้อมที่จะให้คุณได้สิ่งที่คุณต้องการ
thomiel

ฉันจะบอกว่าในการใช้งานในศตวรรษที่ยี่สิบสำหรับเครื่องไมโครคอมพิวเตอร์ที่สามารถโปรแกรมซ้ำได้โดยทั่วไปนั้นมีขนาดcharเกือบเป็นเอกฉันท์ 8 บิตshortคือ 16 และlongเป็น 32 intอาจเป็น 16 หรือ 32 ก็ได้หมายเหตุสำหรับบางแพลตฟอร์ม (โดยเฉพาะ 68000) ทั้ง 16- บิตและ 32- บิตintเป็นเรื่องธรรมดามากและแน่นอนว่าคอมไพเลอร์บางตัวก็มีตัวเลือกให้รองรับเช่นกัน รหัสซึ่งจำเป็นที่จะพกพาจึงคาดว่าจะใช้งานshortหรือในการตั้งค่าlong int
supercat

0

ในขณะที่ในจาวาlongอยู่เสมอ 64 บิตใน C ++ นี้ขึ้นอยู่กับสถาปัตยกรรมคอมพิวเตอร์และระบบปฏิบัติการ ตัวอย่างเช่น a longคือ 64 บิตบน Linux และ 32 บิตบน Windows (ทำเพื่อรักษาความเข้ากันได้ย้อนหลังทำให้โปรแกรม 32 บิตสามารถคอมไพล์บน Windows 64 บิตโดยไม่มีการเปลี่ยนแปลงใด ๆ )

ถือว่าเป็นสไตล์ C ++ ที่ดีในการหลีกเลี่ยง short int long ...และใช้แทน:

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

เหล่านี้ ( int*_t) สามารถใช้งานได้หลังจากรวม<cstdint>ส่วนหัว อยู่ในsize_t<stdlib.h>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.