C ++ मानक का आकार, लंबे प्रकार का होना बताता है?


696

मैं मूल C ++ प्रकार के आकार के संबंध में विस्तृत जानकारी की तलाश कर रहा हूं। मुझे पता है कि यह आर्किटेक्चर (16 बिट्स, 32 बिट्स, 64 बिट्स) और कंपाइलर पर निर्भर करता है।

लेकिन क्या सी ++ के लिए कोई मानक हैं?

मैं 32-बिट आर्किटेक्चर पर विजुअल स्टूडियो 2008 का उपयोग कर रहा हूं। यहाँ मुझे क्या मिलेगा:

char  : 1 byte
short : 2 bytes
int   : 4 bytes
long  : 4 bytes
float : 4 bytes
double: 8 bytes

मुझे लगता है की कोशिश की, ज्यादा सफलता नहीं मिली, विश्वसनीय के आकार बताते हुए जानकारी char, short, int, long, double, floatविभिन्न आर्किटेक्चर और compilers के तहत (और अन्य प्रकार मैं के बारे में सोच नहीं था)।


18
@ अपनी पसंद से नहीं इसे हटाएं ... समर्थन करने के लिए बहुत सारे आर्किटेक्चर हैं जो इसे लचीला होना चाहिए।
क्रैकोस


4
वे सभी अस्पष्ट प्रकारों को क्यों नहीं निकालते हैं, और सभी को निश्चित लंबाई के प्रकारों जैसे कि int32_t, uint32_t, int64_t आदि के लिए मानकीकृत करते हैं
डेवलपर 10

5
@thyrgle यह वास्तव में इस तरह से कुछ मानकीकृत करने के लिए बहुत मुश्किल है। जावा के विपरीत, जहां ये चीजें जेवीएम के काम करने के तरीके के कारण स्थिर रहती हैं, C / C ++ को अनिवार्य रूप से उस सिस्टम से चिपके रहना पड़ता है, जिस पर वे बिना किसी फैंसी-पैंसी एब्स्ट्रैक्शन लेयर्स के भाग जाते हैं (कम से कम जावा के साथ उतने नहीं)। के बीच। यदि इंट का आकार वह है जो महत्वपूर्ण उपयोग कर सकता है int16_t, int32_tऔर int64_t( iostreamयदि मुझे सही याद है तो इसके लिए उसे शामिल करने की आवश्यकता है)। इस बारे में क्या अच्छा है कि int64_t को 32 बिट सिस्टम पर समस्या नहीं होनी चाहिए (हालांकि यह प्रदर्शन को प्रभावित करेगा)।
rbaleksandar

5
@rbaleksandar वे वास्तव में परिभाषित हैं <cstdint>, नहीं <iostream>
जस्टिन टाइम -

जवाबों:


685

C ++ मानक बाइट्स में अभिन्न प्रकार के आकार को निर्दिष्ट नहीं करता है, लेकिन यह न्यूनतम सीमाएं निर्दिष्ट करता है जो उन्हें धारण करने में सक्षम होना चाहिए। आप आवश्यक सीमा से बिट्स में न्यूनतम आकार का अनुमान लगा सकते हैं। आप उस से बाइट्स में न्यूनतम आकार और एक बाइट में बिट्स की संख्या को परिभाषित करने वाले CHAR_BITमैक्रो के मूल्य का अनुमान लगा सकते हैं । सभी में लेकिन सबसे अस्पष्ट प्लेटफ़ॉर्म यह 8 है, और यह 8 से कम नहीं हो सकता है। ऐसा इसलिए है क्योंकि यह "यूनिकोड यूटीएफ -8 एन्कोडिंग फॉर्म की आठ-बिट कोड इकाइयों" को धारण करने के लिए पर्याप्त होना चाहिए।

इसके लिए एक अतिरिक्त बाधा charयह है कि इसका आकार हमेशा 1 बाइट, या CHAR_BITबिट्स (इसलिए नाम) होता है। यह मानक में स्पष्ट रूप से कहा गया है।

C मानक C ++ मानक के लिए एक मानक संदर्भ है , इसलिए भले ही यह इन आवश्यकताओं को स्पष्ट रूप से नहीं बताता है, C ++ को C मानक (पृष्ठ 22) द्वारा आवश्यक न्यूनतम रेंज की आवश्यकता होती है , जो कि डेटा टाइप रेंज पर से समान हैं। MSDN :

  1. signed char: -127 से 127 (नोट, -128 नहीं, 127; इसमें 1-पूरक और साइन-एंड-मैग्नेट प्लेटफॉर्म शामिल हैं)
  2. unsigned char: 0 से 255
  3. "सादा" char: के रूप में एक ही सीमा signed charया unsigned char, कार्यान्वयन-परिभाषित
  4. signed short: -32767 से 32767
  5. unsigned short: 0 से 65535 तक
  6. signed int: -32767 से 32767
  7. unsigned int: 0 से 65535 तक
  8. signed long: -2147483647 से 2147483647
  9. unsigned long: 0 से 4294967295
  10. signed long long: -922337203685474780807 से 9223372036854775807
  11. unsigned long long: 0 से 18446744073709551615

C ++ (या C) कार्यान्वयन sizeof(type)किसी भी मूल्य के बाइट्स में किसी भी प्रकार के आकार को तब तक परिभाषित कर सकता है , जब तक

  1. अभिव्यक्ति sizeof(type) * CHAR_BITआवश्यक बिट्स को समाहित करने के लिए पर्याप्त बिट्स की संख्या का मूल्यांकन करती है, और
  2. प्रकार का क्रम अभी भी मान्य है (उदाहरण के लिए sizeof(int) <= sizeof(long))।

यह सब एक साथ रखते हुए, हम गारंटी देते हैं कि:

  • char, signed charऔर unsigned charकम से कम 8 बिट हैं
  • signed short, unsigned short, signed int, और unsigned intकम से कम 16 बिट कर रहे हैं
  • signed longऔर unsigned longकम से कम 32 बिट्स हैं
  • signed long longऔर unsigned long longकम से कम 64 बिट्स हैं

इसके आकार के बारे में कोई गारंटी नहीं दी गई है floatया doubleइसके अलावा doubleकम से कम उतना सटीक प्रदान करता है float

वास्तविक कार्यान्वयन-विशिष्ट पर्वतमाला <limits.h>सी में हेडर में देखी जा सकती हैं , या <climits>सी ++ में (या इससे भी बेहतर, हेडर std::numeric_limitsमें टेम्पलेटेड <limits>)।

उदाहरण के लिए, यह है कि आप किस प्रकार अधिकतम सीमा पाएंगे int:

सी:

#include <limits.h>
const int min_int = INT_MIN;
const int max_int = INT_MAX;

C ++ :

#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();

49
बल्कि, C ++ मानक शब्द बाइट का उपयोग "1 char" करने के लिए करता है , और सामान्य अर्थ नहीं।
बेन वोइगट

4
@Programmer उत्तर पढ़ें (कोष्ठक में बिंदु 1 नोट), या वास्तविक मानक शब्द (उत्तर में जुड़ा हुआ)। C मानक 1 के पूरक आर्किटेक्चर को समायोजित करता है, जिसका सबसे व्यापक 2 के पूरक से अलग प्रतिनिधित्व है। न्यूनतम गारंटीकृत रेंज लगभग हमेशा उन वास्तविक श्रेणियों से अलग होगी जो एक कार्यान्वयन प्रदान करता है।
एलेक्स बी

9
@ एलेक्स बी आपने अपने उत्तर में डबल के बारे में कुछ भी उल्लेख नहीं किया है। क्या आप फ़्लोटिंग पॉइंट चर के लिए अपने उत्तर को अपडेट कर सकते हैं?
कूल_कोडर

3
@ कूल_कोडर: फ्लोटिंग पॉइंट मछली की एक पूरी अतिरिक्त केतली है, जो आसानी से पदों के आकार को दोगुना कर देती है।
Deduplicator

3
@Mooing Duck: "C ++ के सभी संस्करण में 256 अलग-अलग मूल्यों [हस्ताक्षरित चार प्रकारों के लिए] की आवश्यकता थी" नहीं, यह तब तक सही नहीं था जब तक कि यह हाल ही के C ++ स्पेक्स में तय नहीं हो गया। पुराने चश्मे ने हस्ताक्षरित चार प्रकारों को बिट पैटर्न के लिए अनुमति दी है जो एक नंबर पर मैप नहीं करते हैं, इसलिए वे इस आवश्यकता को याद कर रहे थे कि 256 अलग-अलग मूल्य हैं। "अहस्ताक्षरित वर्ण प्रकारों के लिए, मूल्य प्रतिनिधित्व के सभी संभावित बिट पैटर्न संख्याओं का प्रतिनिधित्व करते हैं। ये आवश्यकताएं अन्य प्रकारों के लिए नहीं होती हैं।"
एड्रियन मैकार्थी

241

32-बिट सिस्टम के लिए, 'डी वास्तविक' मानक ILP32 है - और int, longऔर पॉइंटर सभी 32-बिट मात्रा हैं।

64-बिट सिस्टम के लिए, प्राथमिक यूनिक्स 'डी वास्तविक' मानक LP64 है - longऔर सूचक 64-बिट (लेकिन int32-बिट) है। Windows 64-bit मानक LLP64 है - long longऔर सूचक 64-बिट (लेकिन longऔर int32-बिट कर रहे हैं)।

एक समय में, कुछ यूनिक्स प्रणालियों ने ILP64 संगठन का उपयोग किया था।

इन सभी वास्तविक मानकों में से कोई भी C मानक (ISO / IEC 9899: 1999) द्वारा निर्धारित नहीं है, लेकिन सभी को इसकी अनुमति है।

और, परिभाषा के द्वारा, sizeof(char)है 1पर्ल कॉन्फ़िगर लिपि में परीक्षण के होते हुए भी,।

ध्यान दें कि वहाँ मशीनें (Crays) थीं, जहां CHAR_BIT8. से बहुत बड़ा था। इसका मतलब, IIRC, वह sizeof(int)भी 1 था, क्योंकि दोनों charऔर int32-बिट थे।


73
+1 यह बताने के लिए कि चीजें वास्तव में किस मामले में हैं जो कि सबसे ज्यादा मायने रखती हैं, बजाय इसके कि चीजें सिद्धांत में कैसे हैं। यदि आप 32 बिट का उपयोग करना चाहते हैं, तो आप 64 बिट का लंबे समय तक उपयोग करना चाहते हैं। यदि आप देशी उपयोग size_t चाहते हैं। "सादे" से बचें क्योंकि यह भिन्न होता है। कि ज्यादातर अनुप्रयोगों के लिए काम करना चाहिए।
एल्फ

37
जवाब के लिए +1। @Eloff: इसके विपरीत ... यदि आप 32 बिट उपयोग [u]int32_tया समान चाहते हैं, यदि आप 64 बिट उपयोग चाहते हैं [u]int64_t... यदि आपके पास उनके लिए कोई हेडर नहीं है, तो डाउनलोड करें या एक बनाएं, अधिमानतः या तो संकलन समय चयन के साथ आकार को सत्यापित करने के लिए इस तरह के या स्थिर दावे। pubs.opengroup.org/onlinepubs/009695299/basedefs/stdint.h.html यदि सटीक आकार इतने महत्वपूर्ण नहीं हैं और आपको केवल इतना ही ख्याल है कि वे कम से कम इतने बड़े हैं, तो आपकी सलाह आम आधुनिक पीसी / सर्वर प्लेटफार्मों के लिए है।
टोनी डेलारॉय

8
ध्यान दें कि यह सिर्फ पुराने क्रे मशीनों है कि CHAR_BIT> 8. जैसे DSPs अक्सर 16 या 32 की CHAR_BIT (देखें उदाहरण के लिए की जरूरत नहीं है इन )
ओपन स्कूल

2
@nos: लिंक के लिए धन्यवाद। ऑडबॉल के मामलों के लिए आधुनिक, वर्तमान प्रणालियों की पहचान करना बहुत सहायक है। जिज्ञासा से बाहर, उन मशीनों पर सेट कोड क्या है? यदि कोड सेट UTF-16 है, तो 0xFFFF एक मान्य वर्ण नहीं है, और यदि कोड सेट ISO 8859-x कोड सेट है, तो फिर से 0xFFFF एक मान्य वर्ण नहीं है (0x00 से 0xFF के वर्ण कोड मान्य हैं)। मैं अभी तक आश्वस्त नहीं हूं कि ईओएफ का पता लगाने में कोई समस्या है, लेकिन निश्चित रूप से सावधानी बरतने की गुंजाइश है, और शायद int get_char(FILE *fp, char *c)ईओएफ या 0 और सेट लौटाने वाले फ़ंक्शन को लिखने और उपयोग करने के लिए *c
जोनाथन लेफ्लर

2
@joelw: C11 के लिए आवश्यक है कि, प्लेटफ़ॉर्म पर "29 "का uint32_t x=1,y=2;मान x-y4294967295 हो, जहाँ" int "32 बिट्स या उससे छोटा हो, और प्लेटफॉर्म पर -1 जहाँ" int "33 बिट्स या बड़ा हो। इसके अलावा, यह आवश्यक है कि x*yx और y के सभी मानों के लिए मॉड्यूलर अंकगणितीय का उपयोग करके मूल्यांकन किया जाना चाहिए यदि "int" 32 बिट्स या छोटा है, और 65 अंक या बड़ा होने पर पारंपरिक अंकगणित है, लेकिन बड़े मूल्यों के साथ क्या हो सकता है पर कोई आवश्यकता नहीं है। x और y यदि "int" 33 से 64 बिट्स का है।
सुपरकैट

88

व्यवहार में ऐसी कोई बात नहीं है। अक्सर आप std::size_tमौजूदा वास्तुकला पर अहस्ताक्षरित देशी पूर्णांक आकार का प्रतिनिधित्व करने की उम्मीद कर सकते हैं । यानी 16-बिट, 32-बिट या 64-बिट लेकिन यह हमेशा ऐसा नहीं होता है जैसा कि इस उत्तर में टिप्पणियों में बताया गया है।

जहां तक ​​अन्य सभी अंतर्निहित प्रकार चलते हैं, यह वास्तव में संकलक पर निर्भर करता है। यहां नवीनतम C ++ मानक के वर्तमान कार्य मसौदे से दो अंश लिए गए हैं:

पांच मानक हस्ताक्षरित पूर्णांक प्रकार हैं: हस्ताक्षरित चार, लघु इंट, इंट, लंबे इंट, और लंबे लंबे इंट। इस सूची में, प्रत्येक प्रकार कम से कम उतना भंडारण प्रदान करता है जितना कि सूची में आने से पहले।

मानक हस्ताक्षरित पूर्णांक प्रकारों में से प्रत्येक के लिए, एक संगत (लेकिन अलग) मानक अहस्ताक्षरित पूर्णांक प्रकार मौजूद है: अहस्ताक्षरित चार, अहस्ताक्षरित लघु int, अहस्ताक्षरित int, अहस्ताक्षरित लंबे int, और अहस्ताक्षरित लंबे लंबे int, जिनमें से प्रत्येक एक ही राशि में व्याप्त है। भंडारण और एक ही संरेखण आवश्यकताओं है।

यदि आप चाहते हैं तो आप इन मूलभूत प्रकारों के आकार के अनुसार संकलित (संकलन-समय) कर सकते हैं। यह आकार कोड मान्यताओं को बदलने पर लोगों को आपके कोड को पोर्ट करने के बारे में सोचने के लिए सचेत करेगा।


7
अच्छी पोस्ट। एक और चीज़ जो आवश्यक है, वह है कम से कम बिट-साइज़ (c89 / c99 में डॉक्यूमेंट्स के साथ लिमिट.एच और c ++ द्वारा लिया गया): char> = 8, short और int> = 16, long> = 32।
जोहान्स स्काउब -

1
इसके अलावा, 8 बिट AVR प्लेटफॉर्म size_t पर 8 बिट्स नहीं, बल्कि 16 होने जा रहे हैं, क्योंकि पॉइंटर और इंट का आकार 16 बिट्स है। तो प्रोसेसर देशी डेटा का आकार size_t से संबंधित नहीं है।
रोबोटबग्स

80

मानक है।

C90 मानक की आवश्यकता है कि

sizeof(short) <= sizeof(int) <= sizeof(long)

C99 मानक की आवश्यकता है कि

sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

यहाँ C99 विनिर्देशों है । विभिन्न अभिन्न प्रकारों के पृष्ठ 22 विवरण आकार।

यहाँ Windows प्लेटफ़ॉर्म के लिए int प्रकार के आकार (बिट्स) हैं:

Type           C99 Minimum     Windows 32bit
char           8               8
short          16              16
int            16              32
long           32              32
long long      64              64

यदि आप पोर्टेबिलिटी से चिंतित हैं, या आप चाहते हैं कि टाइप का नाम आकार को दर्शाता है, तो आप हेडर को देख सकते हैं <inttypes.h>, जहां निम्नलिखित मैक्रो उपलब्ध हैं:

int8_t
int16_t
int32_t
int64_t

int8_t8 बिट्स होने की गारंटी है, और int16_t16 बिट्स होने की गारंटी है, आदि।


8
माइनर नाइटपिक: sizeof(long) < sizeof(long long)सममिति के विपरीत मानक कहाँ कहता है sizeof(long) <= sizeof(long long)?
जोनाथन लेफलर

2
@JonathonLeffler - C99 5.2.4.2.1 देखें - पूर्णांक प्रकारों का आकार। minsizeof (int) == 16-बिट्स, minsizeof (लॉन्ग) == 32-बिट्स, minsizeof (लॉन्ग लॉन्ग) == 64-बिट्स। तो मुझे लगता है कि आप सही हैं <= जैसा कि कोई अधिकतम आकार (प्रकार) निर्दिष्ट नहीं है।
जेसी चिशोल्म

इसी तरह आकार (फ्लोट) <= आकार (डबल) <= आकार (लंबा डबल)। C99 7.12 पैरा 2 के अनुसार
जेसी चिशोल्म

38

यदि आपको निश्चित आकार के प्रकारों की आवश्यकता है, तो stdint.h में परिभाषित uint32_t (अहस्ताक्षरित पूर्णांक 32 बिट्स) जैसे प्रकारों का उपयोग करें । वे C99 में निर्दिष्ट हैं ।


10
वे निर्दिष्ट हैं, लेकिन आवश्यक नहीं हैं।
सपनालाल

2
@dreamlax क्या प्लेटफार्मों में शामिल नहीं है?
लेवी मॉरिसन

3
@ लेवीमोरिसन: कोई भी प्लेटफ़ॉर्म जो उनके पास आवश्यक रूप में नहीं है। एक मंच CHAR_BIT == 16, उदाहरण के लिए, नहीं होगा int8_t। दो के पूरक का उपयोग नहीं करने वाले किसी भी प्लेटफ़ॉर्म में उनमें से कोई भी नहीं होगा (जैसा कि दो के पूरक मानक द्वारा आवश्यक है)।
DevSolar

36

अपडेट किया गया: C ++ 11 आधिकारिक तौर पर TR1 के प्रकारों को मानक में लाया गया:

  • लंबे लंबे int
  • अहस्ताक्षरित लंबे लंबे int

और "आकार" प्रकार से <cstdint>

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (और अहस्ताक्षरित समकक्षों)।

साथ ही आपको मिलता है:

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • इसके अलावा अहस्ताक्षरित समकक्षों।

ये प्रकार कम से कम निर्दिष्ट बिट्स के साथ सबसे छोटे पूर्णांक प्रकारों का प्रतिनिधित्व करते हैं। इसी तरह कम से कम बिट्स की संख्या के साथ "सबसे तेज़" पूर्णांक प्रकार हैं:

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • इसके अलावा अहस्ताक्षरित संस्करण।

"तेज" का अर्थ है, अगर कुछ भी, कार्यान्वयन तक है। यह सभी उद्देश्यों के लिए सबसे तेज़ होने की आवश्यकता नहीं है।


यह अब C ++ 11 मानक का हिस्सा है।
जान

2
"फास्ट" बस हार्डवेयर आर्किटेक्चर के अनुरूप है। यदि रजिस्टर 16-बिट हैं, तो int_fast8_t 16-बिट मान है। यदि रजिस्टर 32-बिट हैं, तो int_fast8_t और int_fast16_t दोनों 32-बिट मान हैं। आदि देखें C99 खंड 7.18.1.3 पैरा 2.
जेसी चिशोल्म

19

सी ++ स्टैंडर्ड इसे इस तरह कहते हैं:

3.9.1, .12:

पाँच हस्ताक्षरित पूर्णांक प्रकार हैं: "हस्ताक्षरित चार", "लघु int", "int", "long int", और "long long"। इस सूची में, प्रत्येक प्रकार कम से कम उतना भंडारण प्रदान करता है जितना कि सूची में आने से पहले। प्लेन इन्ट्स का निष्पादन आकार (44) की वास्तुकला द्वारा सुझाए गए प्राकृतिक आकार है; अन्य हस्ताक्षरित पूर्णांक प्रकार विशेष आवश्यकताओं को पूरा करने के लिए प्रदान किए जाते हैं।

(४४) जो कि, INT_MIN और INT_MAX की सीमा में किसी भी मान को सम्‍मिलित करने के लिए काफी बड़ा है, जैसा कि हेडर में परिभाषित किया गया है <climits>

निष्कर्ष: यह इस बात पर निर्भर करता है कि आप किस आर्किटेक्चर पर काम कर रहे हैं। कोई अन्य धारणा झूठी है।


12

नहीं, आकार के लिए कोई मानक नहीं है। मानक को केवल इसकी आवश्यकता होती है:

sizeof(short int) <= sizeof(int) <= sizeof(long int)

यदि आप एक निश्चित आकार के चर चाहते हैं तो सबसे अच्छी बात यह है कि इस तरह मैक्रोज़ का उपयोग किया जा सकता है:

#ifdef SYSTEM_X
  #define WORD int
#else
  #define WORD long int
#endif

तब आप अपने चर को परिभाषित करने के लिए WORD का उपयोग कर सकते हैं। ऐसा नहीं है कि मुझे यह पसंद है लेकिन यह सबसे पोर्टेबल तरीका है।


4
समस्या यह है कि WORD कार्यक्रम के चारों ओर ऐसे क्षेत्रों में फैल जाता है जो वास्तव में एक निश्चित आकार (कुछ विंडोज़ कोड को देखें) पर निर्भर नहीं होते हैं। जैसा कि मुझे पता चला कि 16 बिट से 32 बिट सिस्टम में जाने पर आप उसी समस्या से समाप्त होते हैं जो WORD को हल करने के लिए थी।
लिलबर्न

@liburne निश्चित रूप से आपको WORD का उपयोग तभी करना चाहिए जब आपको एक निश्चित आकार के चर की आवश्यकता हो, जैसे कि जब आप / से फ़ाइल में पढ़ / लिख रहे हों। यदि कोड का एक टुकड़ा वास्तव में एक निश्चित आकार से निर्भर नहीं है, तो आपको सामान्य "int" चर का उपयोग करना चाहिए।
एमिलियानो

3
पोर्टेबल आकार प्राप्त करने के लिए सबसे अच्छी बात यह हो सकती है#include <boost/cstdint.hpp>
kizzx2

11

हमें उस प्रकार के एक पर्याय को परिभाषित करने की अनुमति है ताकि हम अपना "मानक" बना सकें।

एक मशीन पर जिसमें आकार (int) == 4, हम परिभाषित कर सकते हैं:

typedef int int32;

int32 i;
int32 j;
...

इसलिए जब हम कोड को एक अलग मशीन में स्थानांतरित करते हैं, जहां वास्तव में लंबे int का आकार 4 होता है, तो हम केवल int की एकल घटना को फिर से परिभाषित कर सकते हैं।

typedef long int int32;

int32 i;
int32 j;
...

1
यह आवश्यक नहीं है कि मानक हेडर <stdint.h>(C99 और बाद में, और C ++ मानक को C लाइब्रेरी के C99 संस्करण को अपनाया जाए)।
कीथ थॉम्पसन

8

फ़्लोटिंग पॉइंट नंबरों के लिए एक मानक (IEEE754) है : फ़्लोट्स 32 बिट हैं और डबल्स 64 हैं। यह एक हार्डवेयर मानक है, C ++ मानक नहीं है, इसलिए कंपाइलर सैद्धांतिक रूप से फ्लोट को परिभाषित कर सकते हैं और कुछ अन्य आकार में डबल हो सकते हैं, लेकिन व्यवहार में मैं ' ve ने कभी ऐसा आर्किटेक्चर नहीं देखा, जो कुछ भी अलग करता हो।


2
हालांकि, IEEE 754 (उर्फ IEC 559) का अनुपालन C ++ के भीतर वैकल्पिक है (शायद C भी, लेकिन मुझे यकीन नहीं है)। स्टड देखें :: न्यूमेरिक_लिमिट्स :: is_iec559
ड्रू हॉल

1
तब आपने TMS320C28xx DSP के लिए TI का कंपाइलर नहीं देखा है, जहाँ doubleइसका आकार एक जैसा है float(और intजैसा है char, दोनों 16 बिट हैं)। लेकिन उनके पास 64 बिट है long double
starblue

7

एक मानक है और यह विभिन्न मानकों के दस्तावेजों (आईएसओ, एएनएसआई और व्हाट्सएप) में निर्दिष्ट है।

विकिपीडिया में विभिन्न प्रकारों और उनके द्वारा संग्रहित अधिकतम की व्याख्या करने वाला एक शानदार पृष्ठ है: कंप्यूटर विज्ञान में पूर्णांक।

हालाँकि मानक C ++ कंपाइलर के साथ भी आप निम्न कोड स्निपेट का उपयोग करके आसानी से पता लगा सकते हैं:

#include <iostream>
#include <limits>


int main() {
    // Change the template parameter to the various different types.
    std::cout << std::numeric_limits<int>::max() << std::endl;
}

एसटीडी के लिए दस्तावेज़ीकरण :: num_limits Roguewave में पाया जा सकता है । इसमें अन्य आदेशों की अधिकता शामिल है जिन्हें आप विभिन्न सीमाओं का पता लगाने के लिए कॉल कर सकते हैं। इसका उपयोग किसी भी मनमाने प्रकार के साथ किया जा सकता है जो आकार को बताता है, उदाहरण के लिए std :: streamsize।

जॉन के उत्तर में सबसे अच्छा विवरण शामिल है, क्योंकि उन्हें रखने की गारंटी दी जाती है। कोई फर्क नहीं पड़ता कि आप किस प्लेटफॉर्म पर हैं, एक और अच्छा पेज है जो अधिक विवरण में जाता है कि प्रत्येक प्रकार के कितने बिट्स होने चाहिए: इंट प्रकार , जो मानक में परिभाषित हैं।

आशा है कि ये आपकी मदद करेगा!



7

आप उपयोग कर सकते हैं:

cout << "size of datatype = " << sizeof(datatype) << endl;

datatype = int, long intआदि आप जिस भी प्रकार का डेटा टाइप करते हैं, उसके लिए आकार देख पाएंगे।


7

जब यह विभिन्न आर्किटेक्चर और विभिन्न कंपाइलरों के प्रकारों में निर्मित होता है, तो यह देखने के लिए कि यह आउटपुट क्या है, अपने कंपाइलर के साथ अपने आर्किटेक्चर पर निम्न कोड चलाएं। नीचे मेरा Ubuntu 13.04 दिखाता है (रेयरिंग रिंगटोन) दिखाता है 64 बिट g ++ 4.7.3 आउटपुट। कृपया ध्यान दें कि नीचे क्या उत्तर दिया गया था जिसके कारण आउटपुट का आदेश दिया गया है:

"पांच मानक हस्ताक्षरित पूर्णांक प्रकार हैं: हस्ताक्षरित चार, लघु इंट, इंट, लंबे इंट, और लंबे लंबे इंट। इस सूची में, प्रत्येक प्रकार कम से कम उतना भंडारण प्रदान करता है जितना कि सूची में पूर्ववर्ती है।"

#include <iostream>

int main ( int argc, char * argv[] )
{
  std::cout<< "size of char: " << sizeof (char) << std::endl;
  std::cout<< "size of short: " << sizeof (short) << std::endl;
  std::cout<< "size of int: " << sizeof (int) << std::endl;
  std::cout<< "size of long: " << sizeof (long) << std::endl;
  std::cout<< "size of long long: " << sizeof (long long) << std::endl;

  std::cout<< "size of float: " << sizeof (float) << std::endl;
  std::cout<< "size of double: " << sizeof (double) << std::endl;

  std::cout<< "size of pointer: " << sizeof (int *) << std::endl;
}


size of char: 1
size of short: 2
size of int: 4
size of long: 8
size of long long: 8
size of float: 4
size of double: 8
size of pointer: 8

sizeof(char)शामिल नहीं होना चाहिए।
शुक्र

3

जैसा कि उल्लेख किया गया है कि आकार को वर्तमान वास्तुकला को प्रतिबिंबित करना चाहिए। limits.hयदि आप यह देखना चाहते हैं कि आपका वर्तमान संकलक चीजों को कैसे संभाल रहा है, तो आप चारों ओर एक शिखर ले सकते हैं।


धन्यवाद, लेकिन मैं achitectures के लिए आकार जानना चाहूंगा जो मेरे पास नहीं है (जैसे 64 बिट्स)। यह ट्यूटोरियल केवल 32 बिट्स अचीवमेंट्स के बारे में बात करता है ...
Jérôme

2

जैसा कि अन्य ने उत्तर दिया है, "मानक" सभी विवरणों को "कार्यान्वयन परिभाषित" के रूप में छोड़ देते हैं और केवल यह बताते हैं कि "char" प्रकार "char_bis" चौड़ा है, और यह कि "char <= short <= int <= long < = लंबे लंबे "(फ्लोट और डबल IEEE फ्लोटिंग पॉइंट मानकों के साथ बहुत अधिक संगत हैं, और लंबी डबल आमतौर पर डबल के समान है - लेकिन अधिक वर्तमान कार्यान्वयन पर बड़ा हो सकता है)।

बहुत विशिष्ट और सटीक मान न होने के कारणों का एक हिस्सा यह है क्योंकि C / C ++ जैसी भाषाओं को बड़ी संख्या में हार्डवेयर प्लेटफ़ॉर्म पर पोर्टेबल होने के लिए डिज़ाइन किया गया था - जिसमें कंप्यूटर सिस्टम शामिल हैं जिसमें "चार" शब्द-आकार 4-बिट हो सकते हैं या 7-बिट्स, या यहां तक ​​कि "8- / 16- / 32- / 64-बिट" कंप्यूटर के अलावा कुछ मूल्य जो औसत घरेलू कंप्यूटर उपयोगकर्ता के संपर्क में है। (यहां शब्द-आकार का अर्थ है कि सिस्टम सामान्य रूप से कितने बिट्स को चौड़ा करता है - फिर से, यह हमेशा 8-बिट्स नहीं होता है जैसा कि होम कंप्यूटर उपयोगकर्ता अपेक्षा कर सकते हैं।)

यदि आपको वास्तव में किसी विशिष्ट संख्या के बिट्स की एक वस्तु (एक अभिन्न मूल्य का प्रतिनिधित्व करने वाली बिट्स की एक श्रृंखला के अर्थ में) की आवश्यकता होती है, तो अधिकांश कंपाइलरों को निर्दिष्ट करने की कुछ विधि होती है; लेकिन यह आम तौर पर पोर्टेबल नहीं है, यहां तक ​​कि अमी कंपनी द्वारा तैयार किए गए कंपाइलरों के बीच भी। कुछ मानक और प्रथाएं (विशेष रूप से लिमिट.एच और लाइक) आम हैं कि अधिकांश कंपाइलरों में विशिष्ट श्रेणी के मानों के लिए सर्वोत्तम-फिट प्रकार का निर्धारण करने के लिए समर्थन होगा, लेकिन उपयोग किए गए बिट्स की संख्या नहीं। (अर्थात, यदि आप जानते हैं कि आपको 0 और 127 के बीच मान रखने की आवश्यकता है, तो आप यह निर्धारित कर सकते हैं कि आपका कंपाइलर 8-बिट्स के "int8" प्रकार का समर्थन करता है, जो कि पूरी रेंज को वांछित रखने के लिए काफी बड़ा होगा, लेकिन ऐसा कुछ नहीं "int7" प्रकार जो 7-बिट्स के लिए एक सटीक मिलान होगा।]

नोट: कई Un * x स्रोत पैकेजों का उपयोग किया जाता है "./configure" स्क्रिप्ट जो कंपाइलर / सिस्टम की क्षमताओं की जांच करेगा और एक उपयुक्त मेकफाइल और config.h आउटपुट करेगा। आप इनमें से कुछ लिपियों की जांच कर सकते हैं कि वे कैसे काम करते हैं और वे कैसे कामरेड / सिस्टम क्षमताओं की जांच करते हैं, और उनके नेतृत्व का पालन करते हैं।


1

यदि आप शुद्ध सी ++ समाधान में रुचि रखते हैं, तो मैंने उनके बिट आकार के आधार पर संकलन समय पर प्रकारों को परिभाषित करने के लिए टेम्पलेट्स और केवल सी ++ मानक कोड का उपयोग किया। यह घोल को कंपाइलरों में पोर्टेबल बनाता है।

पीछे का विचार बहुत सरल है: एक सूची बनाएं जिसमें प्रकार चार, इंट, लघु, लंबी, लंबी (हस्ताक्षरित और अहस्ताक्षरित संस्करण) हैं और सूची को स्कैन करें और संख्यात्मक_लिमिट्स टेम्पलेट के उपयोग से दिए गए आकार के साथ प्रकार का चयन करें।

इस शीर्ष लेख में आपको 8 प्रकार के stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64 मिला।

यदि कुछ प्रकार का प्रतिनिधित्व नहीं किया जा सकता है तो इसका मूल्यांकन stdtype :: null_type द्वारा उस शीर्ष लेख में भी किया जाएगा।

CODE BELOW WARRANTY के बिना है, कृपया इसे देखें।
मैं मेट्रोपोलिमिंग टू में नया हूं, इस कोड को संपादित करने और सुधारने के लिए स्वतंत्र हूं।
DevC ++ के साथ परीक्षण किया गया (ताकि 3.5 के आसपास एक gcc संस्करण)

#include <limits>

namespace stdtype
{
    using namespace std;


    /*
     * THIS IS THE CLASS USED TO SEMANTICALLY SPECIFY A NULL TYPE.
     * YOU CAN USE WHATEVER YOU WANT AND EVEN DRIVE A COMPILE ERROR IF IT IS 
     * DECLARED/USED.
     *
     * PLEASE NOTE that C++ std define sizeof of an empty class to be 1.
     */
    class null_type{};

    /*
     *  Template for creating lists of types
     *
     *  T is type to hold
     *  S is the next type_list<T,S> type
     *
     *  Example:
     *   Creating a list with type int and char: 
     *      typedef type_list<int, type_list<char> > test;
     *      test::value         //int
     *      test::next::value   //char
     */
    template <typename T, typename S> struct type_list
    {
        typedef T value;
        typedef S next;         

    };




    /*
     * Declaration of template struct for selecting a type from the list
     */
    template <typename list, int b, int ctl> struct select_type;


    /*
     * Find a type with specified "b" bit in list "list"
     *
     * 
     */
    template <typename list, int b> struct find_type
    {   
        private:
            //Handy name for the type at the head of the list
            typedef typename list::value cur_type;

            //Number of bits of the type at the head
            //CHANGE THIS (compile time) exp TO USE ANOTHER TYPE LEN COMPUTING
            enum {cur_type_bits = numeric_limits<cur_type>::digits};

        public:
            //Select the type at the head if b == cur_type_bits else
            //select_type call find_type with list::next
            typedef  typename select_type<list, b, cur_type_bits>::type type;
    };

    /*
     * This is the specialization for empty list, return the null_type
     * OVVERRIDE this struct to ADD CUSTOM BEHAVIOR for the TYPE NOT FOUND case
     * (ie search for type with 17 bits on common archs)
     */
    template <int b> struct find_type<null_type, b>
    {   
        typedef null_type type;

    };


    /*
     * Primary template for selecting the type at the head of the list if
     * it matches the requested bits (b == ctl)
     *
     * If b == ctl the partial specified templated is evaluated so here we have
     * b != ctl. We call find_type on the next element of the list
     */
    template <typename list, int b, int ctl> struct select_type
    {   
            typedef  typename find_type<typename list::next, b>::type type; 
    };

    /*
     * This partial specified templated is used to select top type of a list
     * it is called by find_type with the list of value (consumed at each call)
     * the bits requested (b) and the current type (top type) length in bits
     *
     * We specialice the b == ctl case
     */
    template <typename list, int b> struct select_type<list, b, b>
    {
            typedef typename list::value type;
    };


    /*
     * These are the types list, to avoid possible ambiguity (some weird archs)
     * we kept signed and unsigned separated
     */

    #define UNSIGNED_TYPES type_list<unsigned char,         \
        type_list<unsigned short,                           \
        type_list<unsigned int,                             \
        type_list<unsigned long,                            \
        type_list<unsigned long long, null_type> > > > >

    #define SIGNED_TYPES type_list<signed char,         \
        type_list<signed short,                         \
        type_list<signed int,                           \
        type_list<signed long,                          \
        type_list<signed long long, null_type> > > > >



    /*
     * These are acutally typedef used in programs.
     * 
     * Nomenclature is [u]intN where u if present means unsigned, N is the 
     * number of bits in the integer
     *
     * find_type is used simply by giving first a type_list then the number of 
     * bits to search for.
     *
     * NB. Each type in the type list must had specified the template 
     * numeric_limits as it is used to compute the type len in (binary) digit.
     */
    typedef find_type<UNSIGNED_TYPES, 8>::type  uint8;
    typedef find_type<UNSIGNED_TYPES, 16>::type uint16;
    typedef find_type<UNSIGNED_TYPES, 32>::type uint32;
    typedef find_type<UNSIGNED_TYPES, 64>::type uint64;

    typedef find_type<SIGNED_TYPES, 7>::type    int8;
    typedef find_type<SIGNED_TYPES, 15>::type   int16;
    typedef find_type<SIGNED_TYPES, 31>::type   int32;
    typedef find_type<SIGNED_TYPES, 63>::type   int64;

}

0
unsigned char bits = sizeof(X) << 3;

जहां Xएक है char, int, longआदि .. आप का आकार दे देंगे Xबिट्स में।


1
एक चर हमेशा 8 बिट नहीं होता है, इसलिए आपकी अभिव्यक्ति गैर-8-बिट चार के साथ आर्किटेक्चर पर काम नहीं करेगी । केवल sizeof(type)*CHAR_BITधारण करता है
phuclv

यहां तक ​​कि अगर CHAR_BIT8 बिट होने की गारंटी दी गई है, << 3तो यह लिखने के लिए एक शानदार तरीका है * 8या * CHAR_BIT
कीथ थॉम्पसन

0

एलेक्स बी से सी ++ मानक बाइट्स में अभिन्न प्रकार के आकार को निर्दिष्ट नहीं करता है, लेकिन यह न्यूनतम सीमाओं को निर्दिष्ट करता है जो उन्हें धारण करने में सक्षम होना चाहिए। आप आवश्यक सीमा से बिट्स में न्यूनतम आकार का अनुमान लगा सकते हैं। आप उस से बाइट्स में न्यूनतम आकार और CHAR_BIT मैक्रो के मूल्य का अनुमान लगा सकते हैं जो एक बाइट में बिट्स की संख्या को परिभाषित करता है (सभी में लेकिन सबसे अस्पष्ट प्लेटफार्मों यह 8 है, और यह 8 से कम नहीं हो सकता है)।

चार के लिए एक अतिरिक्त बाधा यह है कि इसका आकार हमेशा 1 बाइट या CHAR_BIT बिट्स (इसलिए नाम) होता है।

मानक द्वारा आवश्यक न्यूनतम श्रेणियां (पृष्ठ 22) हैं:

और MSDN पर डेटा टाइप रेंज:

हस्ताक्षरित चार: -127 से 127 (ध्यान दें, -128 से 127 तक; यह 1-पूरक प्लेटफॉर्म को समायोजित करता है) अहस्ताक्षरित चार: 0 से 255 "सादे" चार: -127 से 127 या 0 से 255 (डिफ़ॉल्ट चार हस्ताक्षर पर निर्भर करता है) पर हस्ताक्षर किए short: -32767 से 32767 अहस्ताक्षरित लघु: 0 से 65535 हस्ताक्षरित int: -32767 से 32767 अहस्ताक्षरित int: 0 से 65535 हस्ताक्षर किए लंबे: -2147483647 से 2147483647 असाइन किए गए लंबे समय: 0 से 4294967295 लंबे हस्ताक्षर किए: -922337203685477 से 922227 0 से 18446744073709551615 A ​​C ++ (या C) कार्यान्वयन किसी भी मान के लिए बाइट्स आकार (प्रकार) में एक प्रकार के आकार को परिभाषित कर सकता है, जब तक कि

अभिव्यक्ति का आकार (प्रकार) * CHAR_BIT आवश्यक सीमाओं को शामिल करने के लिए पर्याप्त बिट्स की संख्या का मूल्यांकन करता है, और प्रकार का आदेश अभी भी मान्य है (उदाहरण के लिए आकार (int) <= sizeof (लंबा))। वास्तविक कार्यान्वयन-विशिष्ट सीमाएँ C में हेडर में, या C ++ में (या इससे भी बेहतर, टेम्प्लेटेड एसटी :: हेडर में संख्यात्मक_लिमिट्स) पाई जा सकती हैं।

उदाहरण के लिए, यह है कि आप int के लिए अधिकतम रेंज कैसे पाएंगे:

सी:

#include <limits.h>
const int min_int = INT_MIN;
const int max_int = INT_MAX;

सी ++:

#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();

यह सही है, हालांकि, आप यह कहने में भी सही थे कि: char: 1 बाइट शॉर्ट: 2 बाइट्स int: 4 बाइट्स लंबी: 4 बाइट्स फ्लोट: 4 बाइट्स डबल: 8 बाइट्स

क्योंकि 32 बिट आर्किटेक्चर अभी भी डिफ़ॉल्ट और सबसे अधिक उपयोग किए जाते हैं, और उन्होंने इन मानक आकारों को प्री -32 बिट दिनों के बाद से रखा है जब मेमोरी कम उपलब्ध थी, और पीछे की संगतता और मानकीकरण के लिए यह समान रहा। यहां तक ​​कि 64 बिट सिस्टम इनका उपयोग करते हैं और सीमा / संशोधन होते हैं। अधिक जानकारी के लिए कृपया इसे देखें:

http://en.cppreference.com/w/cpp/language/types


0

मैंने देखा कि यहाँ अन्य सभी उत्तरों ने लगभग विशेष रूप से अभिन्न प्रकारों पर ध्यान केंद्रित किया है, जबकि प्रश्नकर्ता ने फ्लोटिंग-पॉइंट्स के बारे में भी पूछा।

मुझे नहीं लगता कि C ++ मानक को इसकी आवश्यकता है, लेकिन इन दिनों सबसे आम प्लेटफार्मों के लिए कंपाइलर आम तौर पर अपने फ्लोटिंग-पॉइंट नंबरों के लिए IEEE754 मानक का पालन करते हैं। यह मानक चार प्रकार के बाइनरी फ़्लोटिंग-पॉइंट (साथ ही कुछ बीसीडी फॉर्मेट को निर्दिष्ट करता है, जिसे मैंने C ++ बॉयलर में कभी समर्थन के लिए नहीं देखा है:

  • आधा परिशुद्धता (बाइनरी 16) - 11-बिट महत्व, प्रतिपादक सीमा -14 से 15
  • एकल परिशुद्धता (बाइनरी 32) - 24-बिट महत्व, प्रतिपादक सीमा -126 से 127
  • डबल सटीक (बाइनरी 64) - 53-बिट महत्व, प्रतिपादक सीमा -1022 से 1023
  • चौगुनी सटीकता (बाइनरी128) - 113-बिट महत्व, प्रतिपादक सीमा -16382 से 16383

यह मानचित्र C ++ प्रकारों पर कैसे बनता है, फिर? आमतौर पर floatएकल परिशुद्धता का उपयोग करता है; इस प्रकार, sizeof(float) = 4। फिर doubleदोहरी सटीकता का उपयोग करता है (मेरा मानना ​​है कि यह नाम का स्रोत है double), और long doubleडबल या चौगुनी परिशुद्धता हो सकती है (यह मेरे सिस्टम पर चौगुनी है, लेकिन 32-बिट सिस्टम पर यह डबल हो सकता है)। मुझे ऐसे किसी भी कंपाइलर का पता नहीं है जो आधे सटीक फ्लोटिंग-पॉइंट्स की पेशकश करते हैं।

सारांश में, यह सामान्य है:

  • sizeof(float) = 4
  • sizeof(double) = 8
  • sizeof(long double) = 8 या 16

अजीब बात है कि मैं इस सवाल पर सोच के एक हिस्से के रूप में आया कि जेफ को ज़रूरत से ज़्यादा बाइट्स का उपयोग क्यों करना है।
अनिरुद्ध वर्मा

-1

जैसा कि आपने उल्लेख किया है - यह काफी हद तक कंपाइलर और प्लेटफॉर्म पर निर्भर करता है। इसके लिए, एएनएसआई मानक की जांच करें, http://home.att.net/~jackklein/c/inttypes.html देखें

यहाँ Microsoft कंपाइलर के लिए एक है: डेटा टाइप रेंज


-2

आप पुस्तकालयों द्वारा प्रदान किए गए चर का उपयोग कर सकते हैं जैसे ओपनजीएल , क्यूटी , आदि।

उदाहरण के लिए, क्यूटी प्रदान करता है qint8, qint16, qint32, qint64, quint8, quint16, quint32, quint64, आदि (होने की गारंटी क्यूटी द्वारा समर्थित सभी प्लेटफार्मों पर 8 बिट)


1
इस सवाल का जवाब नहीं देता
EvilTeach

-8

64-बिट मशीन पर:

int: 4
long: 8
long long: 8
void*: 8
size_t: 8

2
कुछ 64 बिट मशीनों intपर 8 बाइट्स हैं, लेकिन अन्य की गारंटी नहीं है। ऐसा कुछ भी नहीं है जो कहता है कि charकेवल 8 बिट्स होना चाहिए। यह sizeof(void*)==464 बिट्स होने पर भी अनुमति है ।
आसमान छू रहा

-10

आकार के आधार पर पूर्णांक के चार प्रकार होते हैं:

  • लघु पूर्णांक: 2 बाइट
  • लंबे पूर्णांक: 4 बाइट
  • लंबे लंबे पूर्णांक: 8 बाइट
  • पूर्णांक: संकलक पर निर्भर करता है (16 बिट, 32 बिट या 64 बिट)

11
गलत, वे सभी वास्तुकला से निर्भर करते हैं, अन्य उत्तरों में से एक में वर्णित न्यूनतम सीमाओं के साथ। कुछ भी नहीं करने के लिए एक कार्यान्वयन बंद हो जाता है short, intऔर longसभी 32 बिट पूर्णांक।
मट्टियो इतालिया

आपने प्रकारों के लिए सही नामों का भी उपयोग नहीं किया है। intशब्द कीवर्ड का उपयोग करते हैं , शब्द "पूर्णांक" नहीं।
कीथ थॉम्पसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.