का आकार

From alpha
Jump to navigation Jump to search

sizeof प्रोग्रामिंग भाषाओं C (प्रोग्रामिंग भाषा) और C++ में एक यूनरी ऑपरेटर है। यह किसी अभिव्यक्ति या डेटा प्रकार का भंडारण आकार उत्पन्न करता है, जिसे चार आकार की इकाइयों की संख्या में मापा जाता है। नतीजतन, निर्माण sizeof (char) 1 होने की गारंटी है। चार प्रकार के अंश ्स की वास्तविक संख्या प्रीप्रोसेसर मैक्रो द्वारा निर्दिष्ट की जाती है CHAR_BIT, मानक में परिभाषित फ़ाइल सीमाएँ शामिल हैं। अधिकांश आधुनिक कंप्यूटिंग प्लेटफ़ॉर्म पर यह आठ बिट है। साइज़ऑफ़ के परिणाम में एक अहस्ताक्षरित पूर्णांक प्रकार होता है जिसे आमतौर पर size_t द्वारा दर्शाया जाता है।

ऑपरेटर के पास एक एकल ऑपरेंड होता है, जो या तो एक अभिव्यक्ति है या डेटा प्रकार का कास्ट है, जो कोष्ठक में संलग्न एक डेटा प्रकार है। डेटा प्रकार न केवल आदिम प्रकार हो सकते हैं, जैसे इंटीजर (कंप्यूटर विज्ञान) और आईईईई फ़्लोटिंग-पॉइंट मानक | फ़्लोटिंग-पॉइंट प्रकार, बल्कि डेटा पॉइंटर प्रकार, और मिश्रित डेटाटाइप (यूनियन (कंप्यूटर विज्ञान), स्ट्रक्चर (सी प्रोग्रामिंग भाषा) भी हो सकते हैं। s, और C++ क्लास (कंप्यूटर विज्ञान))।

उद्देश्य

कई प्रोग्रामों को किसी विशेष डेटा प्रकार के भंडारण आकार का पता होना चाहिए। हालाँकि C या C++ के किसी भी प्रोग्रामिंग भाषा कार्यान्वयन के लिए एक विशेष डेटाटाइप का आकार स्थिर है, कार्यान्वयन के विभिन्न प्लेटफार्मों के लिए C और C++ में भी आदिम प्रकारों के आकार को अलग-अलग परिभाषित किया जा सकता है। उदाहरण के लिए, सरणी स्थान का रनटाइम आवंटन निम्नलिखित कोड का उपयोग कर सकता है, जिसमें sizeof ऑपरेटर को int प्रकार के कास्ट पर लागू किया जाता है:

int *pointer =  malloc(10 * sizeof (int));

इस उदाहरण में, फ़ंक्शन मॉलोक मेमोरी आवंटित करता है और मेमोरी ब्लॉक में एक पॉइंटर लौटाता है। आवंटित ब्लॉक का आकार int प्रकार की एक वस्तु के लिए बाइट्स की संख्या को 10 से गुणा करने के बराबर है, जो दस पूर्णांकों के लिए स्थान प्रदान करता है।

आमतौर पर किसी भी डेटाटाइप का आकार मान लेना सुरक्षित नहीं है। उदाहरण के लिए, भले ही 32-बिट सिस्टम पर C और C++ के अधिकांश कार्यान्वयन प्रकार int को चार ऑक्टेट के रूप में परिभाषित करते हैं, जब कोड को किसी भिन्न सिस्टम में में porting किया जाता है, तो यह आकार बदल सकता है, जिससे कोड टूट जाता है। इसका अपवाद डेटा प्रकार char है, जिसका आकार किसी भी मानक-अनुरूप सी कार्यान्वयन में हमेशा 1 होता है। इसके अलावा, पैडिंग के कारण, संरचना या संघ जैसे यौगिक डेटाटाइप के आकार की भविष्यवाणी करना अक्सर मुश्किल होता है। साइज़ऑफ़ का उपयोग पठनीयता को बढ़ाता है, क्योंकि यह अनाम संख्यात्मक स्थिरांक (मैजिक नंबर (प्रोग्रामिंग)#अनाम संख्यात्मक स्थिरांक) से बचता है।

समान सरणी स्थान को आवंटित करने के लिए एक समतुल्य सिंटैक्स, स्टोरेज पते पर पॉइंटर के डीरेफ़रेंस्ड फॉर्म का उपयोग करने से उत्पन्न होता है, इस बार ऑपरेटर को पॉइंटर वेरिएबल पर लागू करने से:

int *pointer =  malloc(10 * sizeof *pointer);

उपयोग

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

उदाहरण के लिए, चूँकि sizeof (char) को 1 के रूप में परिभाषित किया गया है[1] और यह मानते हुए कि पूर्णांक प्रकार चार बाइट लंबा है, निम्नलिखित कोड खंड प्रिंट होता है 1,4:

char c;
printf ("%zu,%zu\n", sizeof c, sizeof (int));

कुछ मानक हेडर फ़ाइलें, जैसे stddef.h, आकार अभिव्यक्ति के परिणाम के सिग्नेचर इंटीग्रल प्रकार को दर्शाने के लिए size_t को परिभाषित करती हैं। प्रिंटफ चौड़ाई विनिर्देशक z का उद्देश्य उस प्रकार को प्रारूपित करना है।

sizeof का उपयोग सी प्रीप्रोसेसर एक्सप्रेशन में नहीं किया जा सकता, जैसे कि #if, क्योंकि यह प्रोग्रामिंग भाषा का एक तत्व है, प्रीप्रोसेसर सिंटैक्स का नहीं, जिसमें कोई डेटा प्रकार नहीं है।

C++ में निम्नलिखित उदाहरण विविध टेम्पलेट्स के साथ ऑपरेटर sizeof का उपयोग करता है।

template <typename... Args>
std::size_t GetSize (Args&&... args)
{
    /* Get size of parameter pack.*/
    std::size_t Count= sizeof... (Args);
    return Count;           
}

आकार का उपयोग तर्कों की संख्या निर्धारित करने के लिए पैरामीटर पैक पर C++11 और इसके बाद के संस्करण में विविध टेम्पलेट्स के साथ किया जा सकता है।

सरणियों पर अनुप्रयोग

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

<सिंटैक्सहाइलाइट लैंग= सी लाइन हाइलाइट= 9 >

  1. शामिल <stdio.h>

int मुख्य(int argc, char **argv) {

 चार बफ़र[10]; /*10 वर्णों की सारणी*/
 /* argv[1] से अधिकतम 9 अक्षर बफर में कॉपी करें,
  * बफ़र को शून्य-समाप्त करें। */
 एसएनप्रिंटएफ (बफर, साइजऑफ बफर, %s, argv[1]);
 वापसी 0;

} </सिंटैक्सहाइलाइट>

यहाँ, sizeof buffer के बराबर है 10 * sizeof buffer [0], जो 10 का मूल्यांकन करता है, क्योंकि प्रकार char का आकार 1 के रूप में परिभाषित किया गया है।

C99 संरचनाओं में लचीले सरणी सदस्यों के लिए समर्थन जोड़ता है। सरणी घोषणा के इस रूप को केवल संरचनाओं में अंतिम तत्व के रूप में अनुमति दी जाती है, और यह सामान्य सरणी से भिन्न होता है जिसमें कंपाइलर को कोई लंबाई निर्दिष्ट नहीं की जाती है। एस नामक संरचना के लिए जिसमें ए नामक लचीला सरणी सदस्य है, sizeof s इसलिए बराबर है offsetof (s, a):

<सिंटैक्सहाइलाइट लैंग= सी लाइन हाइलाइट= 10 >

  1. शामिल <stdio.h>

संरचना फ्लेक्सरे {

   चार वैल;
   पूर्णांक सरणी[]; /* लचीला सरणी सदस्य; संरचना का अंतिम तत्व होना चाहिए */

};

int मुख्य(int argc, char **argv) {

   प्रिंटफ (साइजऑफ़ (स्ट्रक्चर फ्लेक्सरे) == %zu\n, साइजऑफ़ (स्ट्रक्चर फ्लेक्सरे));
   वापसी 0;

} </सिंटैक्सहाइलाइट>

इस मामले में साइज़ोफ़ ऑपरेटर किसी भी पैडिंग सहित संरचना का आकार लौटाता है, लेकिन सरणी के लिए किसी भी भंडारण की अनुमति के बिना। अधिकांश प्लेटफ़ॉर्म निम्नलिखित आउटपुट उत्पन्न करते हैं:

sizeof (struct flexarray) == 4

C99 वेरिएबल लंबाई सरणियों की भी अनुमति देता है जिनकी लंबाई रनटाइम पर निर्दिष्ट होती है,[2] हालाँकि इस सुविधा को C मानक के बाद के संस्करणों में एक वैकल्पिक कार्यान्वयन माना जाता है। ऐसे मामलों में, सरणी द्वारा कब्जा किए गए भंडारण को निर्धारित करने के लिए रनटाइम पर आकार ऑपरेटर का मूल्यांकन किया जाता है।

#include <stddef.h>

size_t flexsize(int n)
{
   char b[n + 3];   /* Variable length array */
   return sizeof b;  /* Execution time sizeof */
}

int main(void)
{
  size_t size = flexsize(10); /* flexsize returns 13 */
  return 0;
}

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

int main (void)
{
   int tab [10];
   printf ("Number of elements in the array: %zu\n", sizeof tab / sizeof tab [0]); /* yields 10 */
   return 0;
}

अपूर्ण प्रकार

sizeof को केवल पूर्णतः परिभाषित प्रकारों पर ही लागू किया जा सकता है। सरणियों के साथ, इसका मतलब है कि सरणी के आयाम उसकी घोषणा (कंप्यूटर विज्ञान) में मौजूद होने चाहिए, और तत्वों के प्रकार को पूरी तरह से परिभाषित किया जाना चाहिए। संरचनाओं और यूनियनों के लिए, इसका मतलब है कि पूरी तरह से परिभाषित प्रकारों की एक सदस्य सूची होनी चाहिए। उदाहरण के लिए, निम्नलिखित दो स्रोत फ़ाइलों पर विचार करें:

/* file1.c */
int arr [10];
struct x {int one; int two;};
/* more code */

/* file2.c */
extern int arr [];
struct x;
/* more code */

दोनों फ़ाइलें पूरी तरह से कानूनी सी और कोड इन हैं file1.c arr और पर sizeof लागू कर सकते हैं struct x. हालाँकि, यह कोड इन के लिए अवैध है file2.c ऐसा करने के लिए, क्योंकि परिभाषाएँ file2.c पूर्ण नहीं हैं. एआरआर के मामले में, कोड सरणी के आयाम को निर्दिष्ट नहीं करता है; इस जानकारी के बिना, कंपाइलर के पास यह जानने का कोई तरीका नहीं है कि सरणी में कितने तत्व हैं, और सरणी के समग्र आकार की गणना नहीं कर सकता है। इसी तरह, कंपाइलर के आकार की गणना नहीं कर सकता struct x क्योंकि यह नहीं जानता कि यह किन सदस्यों से बना है, और इसलिए संरचना के सदस्यों (और पैडिंग) के आकार के योग की गणना नहीं कर सकता है। यदि प्रोग्रामर ने अपनी घोषणा में सरणी का आकार प्रदान किया है file2.c, या की परिभाषा पूरी की struct x एक सदस्य सूची की आपूर्ति करके, यह आकार के आवेदन को गिरफ्तार करने की अनुमति देगा struct x उस स्रोत फ़ाइल में।

वस्तु सदस्य

C++11 ने इसे प्राप्त करने के लिए ऑब्जेक्ट को तुरंत चालू करने की आवश्यकता के बिना किसी वर्ग के विशिष्ट सदस्यों के लिए sizeof पैरामीटर लागू करने की संभावना पेश की।[3] उदाहरण के लिए निम्नलिखित उदाहरण उपज देता है 4 और 8अधिकांश प्लेटफार्मों पर।

#include <iostream>

struct foo {
  int a;
  int b;
};

int main ()
{
  std::cout << sizeof foo::a << "\n" << sizeof (foo) << "\n";
}

विविध टेम्पलेट पैक

C++11 ने विविध टेम्पलेट पेश किए; अंडाकार के बाद कीवर्ड sizeof एक पैरामीटर पैक में तत्वों की संख्या लौटाता है।

template <typename... Args>
void print_size (Args... args)
{
  std::cout << sizeof... (args) << "\n";
}

int main ()
{
  print_size (); // outputs 0
  print_size ("Is the answer", 42, true); // outputs 3
}

कार्यान्वयन

जब एक निश्चित-लंबाई डेटाटाइप या चर पर लागू किया जाता है, तो प्रोग्राम संकलन के दौरान ऑपरेटर आकार के साथ अभिव्यक्तियों का मूल्यांकन किया जाता है; उन्हें निरंतर परिणाम-मूल्यों द्वारा प्रतिस्थापित किया जाता है। C99 मानक ने चर-लंबाई सरणी (वीएलए) की शुरुआत की, जिसके लिए प्रोग्राम निष्पादन के दौरान ऐसे अभिव्यक्तियों के मूल्यांकन की आवश्यकता होती है। कई मामलों में, कार्यान्वयन विशिष्टताओं को प्लेटफ़ॉर्म के लिए एप्लिकेशन बाइनरी इंटरफ़ेस (एबीआई) दस्तावेज़ में दर्ज किया जा सकता है, जिसमें डेटा प्रकारों के लिए प्रारूप, पैडिंग और संरेखण निर्दिष्ट किया जाता है, जिसके लिए कंपाइलर को अनुरूप होना चाहिए।

संरचना पैडिंग

किसी भी ऑब्जेक्ट प्रकार के आकार की गणना करते समय, कंपाइलर को दक्षता या वास्तुशिल्प बाधाओं को पूरा करने के लिए किसी भी आवश्यक डेटा संरचना संरेखण को ध्यान में रखना चाहिए। कई कंप्यूटर आर्किटेक्चर किसी भी बाइट पते से शुरू होने वाले मल्टीपल-बाइट एक्सेस का समर्थन नहीं करते हैं जो कि शब्द आकार का गुणक नहीं है, और यहां तक ​​कि जब आर्किटेक्चर इसकी अनुमति देता है, तो आमतौर पर सेंट्रल प्रोसेसिंग यूनिट एक डेटा संरचना संरेखण | शब्द-संरेखित ऑब्जेक्ट को तेजी से ला सकती है। इससे वह एक ऐसी वस्तु ला सकता है जो स्मृति में कई शब्दों को समेटे हुए है।[4] इसलिए, कंपाइलर आमतौर पर डेटा संरचनाओं को कम से कम एक वर्ड (डेटा प्रकार) सीमा में संरेखित करते हैं, और व्यक्तिगत सदस्यों को उनकी संबंधित सीमाओं में भी संरेखित करते हैं। निम्नलिखित उदाहरण में, संरचना छात्र को एक शब्द सीमा पर संरेखित किए जाने की संभावना है, जहां सदस्य ग्रेड भी शुरू होता है, और सदस्य की आयु अगले शब्द पते पर शुरू होने की संभावना है। कंपाइलर संरेखण आवश्यकताओं को पूरा करने के लिए आवश्यकतानुसार सदस्यों के बीच पैडिंग बाइट्स डालकर बाद को पूरा करता है। यदि संरचना का उपयोग किसी सरणी के तत्व के रूप में किया जाता है तो उचित संरेखण सुनिश्चित करने के लिए संरचना के अंत में पैडिंग भी हो सकती है।

इस प्रकार, C में किसी संरचना का कुल आकार उसके व्यक्तिगत सदस्यों के आकार के योग से अधिक हो सकता है। उदाहरण के लिए, कई प्रणालियों पर निम्नलिखित कोड प्रिंट होता है 8:

struct student {
  char grade; /* char is 1 byte long */
  int age; /* int is 4 bytes long */
};

printf ("%zu", sizeof (struct student));

यह भी देखें

संदर्भ

  1. "C99 standard (ISO/IEC9899)" (PDF). ISO/IEC. 7 September 2007. 6.5.3.4.3, p. 80. Retrieved 31 October 2010.
  2. "WG14/N1124 Committee Draft ISO/IEC 9899" (PDF). 6 May 2005. 6 May 2005. 6.5.3.4 The sizeof operator.
  3. "N2253 Extending sizeof to apply to non-static data members without an object (Revision 1)".
  4. Rentzsch, Jonathan (8 February 2005). "Data alignment: Straighten up and fly right". IBM. Retrieved 29 September 2014.