कई सी ++ उदाहरणों में मुझे उस प्रकार का उपयोग दिखाई देता है size_t
जहां मैंने एक साधारण का उपयोग किया होगा int
। क्या अंतर है, और क्यों size_t
बेहतर होना चाहिए?
कई सी ++ उदाहरणों में मुझे उस प्रकार का उपयोग दिखाई देता है size_t
जहां मैंने एक साधारण का उपयोग किया होगा int
। क्या अंतर है, और क्यों size_t
बेहतर होना चाहिए?
जवाबों:
से अनुकूल विकिपीडिया :
Stdlib.h और stddef.h हेडर फाइलें एक datatype को size_t परिभाषित करती हैं जिसका उपयोग किसी ऑब्जेक्ट के आकार को दर्शाने के लिए किया जाता है। लाइब्रेरी फ़ंक्शंस जो आकार लेते हैं, उनसे अपेक्षा करते हैं कि वे type size_t के हों, और sizeof ऑपरेटर size_t का मूल्यांकन करता है।
वास्तविक प्रकार का size_t प्लेटफ़ॉर्म-निर्भर है; आम गलती यह है कि size_t अहस्ताक्षरित int के समान है, जिससे प्रोग्रामिंग त्रुटियां हो सकती हैं, विशेष रूप से 64-बिट आर्किटेक्चर अधिक प्रचलित हो जाते हैं।
इसके अलावा, क्यों size_t मामलों की जाँच करें
/usr/include/stdlib.h
से परिभाषा मिलती है /usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.h
और उसमें डिफॉल्ट होता है long unsigned int
जब तक कि कोई अन्य हेडर फ़ाइल अन्यथा न कहे।
size_t आकार का प्रतिनिधित्व करने के लिए उपयोग किया जाने वाला प्रकार है (जैसा कि इसके नाम का तात्पर्य है)। इसका मंच (और यहां तक कि संभावित कार्यान्वयन) निर्भर है, और केवल इस उद्देश्य के लिए उपयोग किया जाना चाहिए। जाहिर है, एक आकार का प्रतिनिधित्व, size_t अहस्ताक्षरित है। Malloc, sizeof और विभिन्न स्ट्रिंग ऑपरेशन फ़ंक्शन सहित कई stdlib फ़ंक्शन, datatype के रूप में size_t का उपयोग करते हैं।
एक int पर डिफ़ॉल्ट रूप से हस्ताक्षर किया जाता है, और भले ही इसका आकार प्लेटफ़ॉर्म पर निर्भर है, यह अधिकांश आधुनिक मशीन पर एक निश्चित 32 बिट्स होगा (और 64-बिट आर्किटेक्चर पर size_t 64 बिट्स होने पर भी, उन आर्किटेक्चर पर 32 बिट्स लंबे समय तक बने रहेंगे)।
संक्षेप में: किसी वस्तु के आकार और अन्य मामलों में int (या लंबे) का प्रतिनिधित्व करने के लिए size_t का उपयोग करें।
size_t
प्रकार के अहस्ताक्षरित अभिन्न प्रकार के रूप में परिभाषित किया गया है sizeof
ऑपरेटर। वास्तविक दुनिया में, आप अक्सर int
32 बिट्स (पिछड़ी अनुकूलता के लिए) के size_t
रूप में परिभाषित होते हैं, लेकिन 64 बिट प्लेटफॉर्म पर 64 बिट्स के रूप में परिभाषित किया जाता है (इसलिए आप एरो और संरचनाओं को 4 GiB से अधिक आकार में घोषित कर सकते हैं)। यदि a long int
भी 64-बिट्स है, तो इसे LP64 कन्वेंशन कहा जाता है; अगर long int
32 बिट्स है लेकिन long long int
पॉइंटर्स 64 बिट्स हैं, तो वह एलएलपी 64 है। आपको रिवर्स भी मिल सकता है, एक प्रोग्राम जो गति के लिए 64-बिट निर्देशों का उपयोग करता है, लेकिन 32-बिट पॉइंटर्स मेमोरी को बचाने के लिए। इसके अलावा, int
हस्ताक्षरित है और size_t
अहस्ताक्षरित है।
ऐतिहासिक रूप से कई अन्य प्लेटफ़ॉर्म थे जहां पते व्यापक थे या देशी आकार से कम थे int
। वास्तव में, s० के दशक और 80० के दशक के दशक में, यह नहीं की तुलना में अधिक सामान्य था: सभी लोकप्रिय bit-बिट माइक्रो कंप्यूटर में computers-बिट रजिस्टर और १६-बिट पते थे, और १६ से ३२ बिट के बीच संक्रमण ने भी कई मशीनों का उत्पादन किया जो कि उनके रजिस्टरों की तुलना में व्यापक थे। मैं कभी-कभार यहां भी एमएस-डॉस के लिए बोरलैंड टर्बो सी के बारे में प्रश्न देखता हूं, जिसकी विशाल मेमोरी मोड में 16-बिट सीपीयू पर 32 बिट्स में संग्रहीत 20-बिट पते थे (लेकिन जो 80386 के 32-बिट अनुदेश सेट का समर्थन कर सकता था); मोटोरोला 68000 में 32-बिट रजिस्टर और पते के साथ 16-बिट ALU था; 15-बिट, 24-बिट या 31-बिट पते के साथ आईबीएम मेनफ्रेम थे। आप अभी भी एम्बेडेड सिस्टम में विभिन्न ALU और पता-बस आकार देखते हैं।
किसी भी समय int
की तुलना में छोटा है size_t
, और आप एक बहुत बड़ी फ़ाइल या ऑब्जेक्ट के आकार या ऑफसेट को स्टोर करने का प्रयास करते हैं unsigned int
, ऐसी संभावना है कि यह अतिप्रवाह कर सकता है और बग पैदा कर सकता है। एक के साथ int
, एक ऋणात्मक संख्या प्राप्त करने की संभावना भी है। यदि एक int
या unsigned int
व्यापक है, तो प्रोग्राम सही ढंग से चलेगा लेकिन मेमोरी को बेकार कर देगा।
यदि आप पोर्टेबिलिटी चाहते हैं तो आपको आम तौर पर सही प्रकार का उपयोग करना चाहिए। बहुत से लोग सुझाएंगे कि आप बिना हस्ताक्षर किए गणित का उपयोग करें (जैसे कि गंदा, सूक्ष्म कीड़े की तरह से बचने के लिए 1U < -3
)। उस प्रयोजन के लिए, मानक पुस्तकालय एक संकेतक को दूसरे से हटाने के परिणामस्वरूप हस्ताक्षरित प्रकार के रूप ptrdiff_t
में परिभाषित करता है <stddef.h>
।
कहा गया कि, वर्कअराउंड सभी पते और ऑफ़सेट्स के खिलाफ या INT_MAX
तो 0
या INT_MIN
उपयुक्त के रूप में सीमा-जाँच कर सकता है , और आपके द्वारा किसी भी मामले में हस्ताक्षर किए गए और अहस्ताक्षरित मात्रा की तुलना करने के बारे में संकलक चेतावनी को चालू करें। आपको हमेशा, हमेशा, हमेशा C में ओवरफ्लो के लिए अपने एरे एक्सेस को चेक करते रहना चाहिए।
ऐसा इसलिए है क्योंकि size_t एक int (शायद एक संरचना) के अलावा कुछ भी हो सकता है। विचार यह है कि यह अंतर्निहित प्रकार से काम करता है यह decouples।
size_t
एक अहस्ताक्षरित पूर्णांक प्रकार के रूप में निर्दिष्ट किया गया है । C11 of6.5.3.4 5 "दोनों ऑपरेटरों के परिणाम का मूल्य ( sizeof
_Alignof
) कार्यान्वयन-परिभाषित है, और इसका प्रकार (एक अहस्ताक्षरित पूर्णांक प्रकार) है size_t
,"।
इसकी परिभाषा SIZE_T
यहां मिलती है:
https://msdn.microsoft.com/en-us/library/cc441980.aspx और https://msdn.microsoft.com/en-us/library/cc230394.aspx
यहां आवश्यक जानकारी देना:
SIZE_T
एक ULONG_PTR
बाइट्स की अधिकतम संख्या का प्रतिनिधित्व करता है जिस पर एक सूचक इंगित कर सकता है।
इस प्रकार इस प्रकार घोषित किया गया है:
typedef ULONG_PTR SIZE_T;
A ULONG_PTR
एक लम्बी लम्बी प्रकार है जिसका उपयोग सूचक परिशुद्धता के लिए किया जाता है। पॉइंटर अंकगणित करने के लिए पॉइंटर को लंबे समय तक टाइप करते समय इसका उपयोग किया जाता है।
इस प्रकार इस प्रकार घोषित किया गया है:
typedef unsigned __int3264 ULONG_PTR;
SIZE_T
नहीं size_t
, ओपी के बारे में क्या पूछा।
SIZE_T
इससे बिलकुल अलग है size_t
। आप एक प्रकार का चर घोषित नहीं कर सकते SIZE_T
।