c++ - सी++ मानक int int, लंबे प्रकार के आकार का आकार क्या है?




c++-faq (16)

मैं बुनियादी सी ++ प्रकारों के आकार के बारे में विस्तृत जानकारी की तलाश में हूं। मुझे पता है कि यह वास्तुकला (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 (और अन्य प्रकारों के बारे में नहीं सोचा था) के आकार बताते हुए, बिना किसी सफलता के, विश्वसनीय जानकारी के बिना खोजने की कोशिश की।



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

64-बिट सिस्टम के लिए, प्राथमिक यूनिक्स 'डी फैक्टो' मानक एलपी 64 - long और पॉइंटर 64-बिट है (लेकिन int 32-बिट है)। विंडोज 64-बिट मानक एलएलपी 64 है - long long और सूचक 64-बिट (लेकिन long और int दोनों 32-बिट हैं)।

एक समय में, कुछ यूनिक्स सिस्टम आईएलपी 64 संगठन का इस्तेमाल करते थे।

इन मानक तथ्यों में से कोई भी सी मानक (आईएसओ / आईईसी 98 99: 1 999) द्वारा कानूनित नहीं है, लेकिन इसकी सभी अनुमति है।

और, परिभाषा के अनुसार, पर्ल कॉन्फ़िगर स्क्रिप्ट में परीक्षण के बावजूद sizeof(char) 1

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


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

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

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

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

यदि आप चाहते हैं कि आप स्थिर रूप से (संकलन-समय) इन मौलिक प्रकारों के आकार पर जोर दे सकें। यह लोगों को आपके कोड को पोर्ट करने के बारे में सोचने के लिए चेतावनी देगा यदि आकार धारणाएं बदलती हैं।


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

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

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


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

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

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

और एमएसडीएन पर डेटा प्रकार रेंज:

हस्ताक्षरित चार: -127 से 127 (नोट, नहीं -128 से 127; यह 1 के पूरक प्लेटफॉर्म को समायोजित करता है) हस्ताक्षरित चार: 0 से 255 "सादा" चार: -127 से 127 या 0 से 255 (डिफ़ॉल्ट चार हस्ताक्षर पर निर्भर करता है) लघु: -32767 से 32767 हस्ताक्षरित शॉर्ट: 0 से 65535 हस्ताक्षरित int: -32767 से 32767 हस्ताक्षरित int: 0 से 65535 हस्ताक्षरित लंबे समय तक: -2147483647 से 2147483647 हस्ताक्षरित लंबे समय तक: 0 से 42 9 4 9 672 9 5 लंबे समय तक हस्ताक्षरित: -9223372036854775807 से 9223372036854775807 लंबे समय तक हस्ताक्षर किए गए: 0 से 18446744073709551615 ए सी ++ (या सी) कार्यान्वयन किसी प्रकार के आकार को बाइट्स आकार (प्रकार) में किसी भी मान को परिभाषित कर सकता है, जब तक

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

उदाहरण के लिए, इस प्रकार आपको 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 बिट दिनों के बाद से इन मानक आकारों को रखा गया है जब स्मृति कम उपलब्ध थी, और पीछे की संगतता और मानकीकरण के लिए यह वही बना रहा। Even 64 bit systems tend to use these and have extentions/modifications. Please reference this for more information:

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


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

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

#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

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


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

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

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

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

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


मानक है।

सी 9 0 मानक की आवश्यकता है

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

सी 99 मानक की आवश्यकता है

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

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

विंडोज प्लेटफार्मों के लिए इंटेल टाइप आकार (बिट्स) यहां दिए गए हैं:

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_t 8 बिट होने की गारंटी है, और int16_t 16 बिट्स आदि की गारंटी है।


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

पीछे का विचार बहुत आसान है: प्रकार, char, int, short, long, long long (हस्ताक्षरित और हस्ताक्षरित संस्करण) वाले एक सूची बनाएं और सूची स्कैन करें और numeric_limits टेम्पलेट के उपयोग से दिए गए आकार के साथ प्रकार का चयन करें।

इस हेडर को शामिल करने के लिए आपको 8 प्रकार की stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64 मिला है।

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

नीचे दिए गए कोड को वारंटी के बिना दिया गया है, कृपया इसे जांचें।
मैं मेट्रोप्रोग्रामिंग पर नया हूं, इस कोड को संपादित करने और सही करने के लिए स्वतंत्र महसूस करें।
देवसी ++ के साथ परीक्षण किया गया (इसलिए 3.5 के आसपास एक जीसीसी संस्करण)

#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;

}

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

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

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

और MSDN पर डेटा प्रकार रेंज:

  1. signed char : -127 से 127 (नोट, नहीं -128 से 127; यह 1 के पूरक और साइन-और-आयाम प्लेटफॉर्म को समायोजित करता है)
  2. unsigned char : 0 से 255
  3. "सादा" char : signed char या unsigned char , implementation-defined रूप में एक ही सीमा
  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 से 42 9 4 9 672 9 5
  10. signed long long : -9223372036854775807 से 9223372036854775807
  11. unsigned long long : 0 से 18446744073709551615

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

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

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

उदाहरण के लिए, इस प्रकार आपको 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();

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

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

typedef int int32;

int32 i;
int32 j;
...

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

typedef long int int32;

int32 i;
int32 j;
...


I notice that all the other answers here have focused almost exclusively on integral types, while the questioner also asked about floating-points.

I don't think the C++ standard requires it, but compilers for the most common platforms these days generally follow the IEEE754 standard for their floating-point numbers. This standard specifies four types of binary floating-point (as well as some BCD formats, which I've never seen support for in C++ compilers):

  • Half precision (binary16) - 11-bit significand, exponent range -14 to 15
  • Single precision (binary32) - 24-bit significand, exponent range -126 to 127
  • Double precision (binary64) - 53-bit significand, exponent range -1022 to 1023
  • Quadruple precision (binary128) - 113-bit significand, exponent range -16382 to 16383

How does this map onto C++ types, then? Generally the float uses single precision; thus, sizeof(float) = 4 . Then double uses double precision (I believe that's the source of the name double ), and long double may be either double or quadruple precision (it's quadruple on my system, but on 32-bit systems it may be double). I don't know of any compilers that offer half precision floating-points.

In summary, this is the usual:

  • sizeof(float) = 4
  • sizeof(double) = 8
  • sizeof(long double) = 8 or 16

There are four types of integers based on size:

  • short integer: 2 byte
  • long integer: 4 byte
  • long long integer: 8 byte
  • integer: depends upon the compiler (16 bit, 32 bit, or 64 bit)

You can use variables provided by libraries such as OpenGL , Qt , etc.

For example, Qt provides qint8 (guaranteed to be 8-bit on all platforms supported by Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64, etc.





c++-faq