जवाबों:
size_tप्रकार अहस्ताक्षरित पूर्णांक प्रकार का परिणाम है कि है sizeofऑपरेटर (औरoffsetof इसलिए यह बहुत बड़ी सबसे बड़ी वस्तु आपके सिस्टम संभाल कर सकते हैं (जैसे, 8Gb की एक स्थिर सरणी) के आकार को रोकने के लिए होने की गारंटी है, ऑपरेटर)।
size_tप्रकार से भी बड़ा, बराबर करने के लिए, या छोटे एक से हो सकता है unsigned int, और अपने संकलक अनुकूलन के लिए इसके बारे में मान्यताओं बना सकता है।
आपको सी 99 मानक, खंड 7.17 में अधिक सटीक जानकारी मिल सकती है, जिसका एक प्रारूप इंटरनेट पर पीडीएफ प्रारूप में उपलब्ध है , या सी 11 मानक, खंड 7.19 में भी पीडीएफ प्रारूप के रूप में उपलब्ध है ।
size_tप्रतिनिधित्व कर सकते हैं! यदि ऐसा नहीं होता, तो कौन करता है?
क्लासिक सी (ब्रायन केर्निघन और डेनिस रिची द्वारा सी प्रोग्रामिंग भाषा, अप्रेंटिस-हॉल, 1978 में वर्णित सी की शुरुआती बोली) प्रदान नहीं की गई size_t। size_tपोर्टेबिलिटी की समस्या को खत्म करने के लिए C मानक समिति की शुरुआत की गई
एम्बेडेड.कॉम पर विस्तार से बताया गया है (बहुत अच्छे उदाहरण के साथ)
संक्षेप में, size_t कभी भी नकारात्मक नहीं होता है, और यह प्रदर्शन को अधिकतम करता है क्योंकि यह टाइप किए गए अनिश्चित प्रकार का पूर्णांक प्रकार होना चाहिए जो काफी बड़ा है - लेकिन बहुत बड़ा नहीं है - लक्ष्य मंच पर सबसे बड़ी संभव वस्तु के आकार का प्रतिनिधित्व करने के लिए।
आकार कभी भी नकारात्मक नहीं होना चाहिए, और वास्तव size_tमें एक अहस्ताक्षरित प्रकार है। इसके अलावा, क्योंकि size_tअहस्ताक्षरित है, तो आप संख्याओं को स्टोर कर सकते हैं जो मोटे तौर पर संबंधित हस्ताक्षरित रूप में दो बार बड़े होते हैं, क्योंकि हम साइन बिट का उपयोग कर सकते हैं, जैसे कि अहस्ताक्षरित पूर्णांक में अन्य सभी बिट्स। जब हम एक और अधिक लाभ प्राप्त करते हैं, तो हम उन संख्याओं की सीमा को गुणा कर रहे हैं जिन्हें हम लगभग दो के कारक से दर्शा सकते हैं।
तो, आप पूछते हैं, क्यों नहीं बस एक का उपयोग करें unsigned int? हो सकता है कि यह बड़ी संख्या में पकड़ बनाने में सक्षम न हो। एक कार्यान्वयन में जहां unsigned int32 बिट्स है, यह सबसे बड़ी संख्या का प्रतिनिधित्व कर सकता है 4294967295। कुछ प्रोसेसर, जैसे कि IP16L32, 4294967295बाइट्स से बड़ी वस्तुओं को कॉपी कर सकते हैं ।
तो, आप पूछते हैं, क्यों नहीं एक का उपयोग करें unsigned long int? यह कुछ प्लेटफार्मों पर एक प्रदर्शन टोल को ठीक करता है। मानक सी के लिए आवश्यक है कि longकम से कम 32 बिट्स पर कब्जा हो। IP16L32 प्लेटफ़ॉर्म प्रत्येक 32-बिट को 16-बिट शब्दों की एक जोड़ी के रूप में लागू करता है। इन प्लेटफार्मों पर लगभग सभी 32-बिट ऑपरेटरों को दो निर्देशों की आवश्यकता होती है, यदि अधिक नहीं, क्योंकि वे दो 16-बिट विखंडू में 32 बिट्स के साथ काम करते हैं। उदाहरण के लिए, 32-बिट लंबे समय तक चलने के लिए आमतौर पर दो मशीन निर्देशों की आवश्यकता होती है - प्रत्येक 16-बिट चंक को स्थानांतरित करने के लिए।
का प्रयोग size_tसे बचा जाता है इस प्रदर्शन टोल। इस शानदार लेख के अनुसार , "टाइप size_tएक टाइपडिफ है जो कुछ अहस्ताक्षरित पूर्णांक प्रकार के लिए एक उपनाम है, आमतौर पर unsigned intया unsigned longलेकिन संभवतः भी unsigned long long। प्रत्येक मानक सी कार्यान्वयन को अहस्ताक्षरित पूर्णांक का चयन करना है जो कि पर्याप्त बड़ा है - लेकिन जरूरत से ज्यादा बड़ा नहीं है - लक्ष्य मंच पर सबसे बड़ी संभव वस्तु के आकार का प्रतिनिधित्व करने के लिए। "
unsigned intऔर यह एक सिस्टम से दूसरे सिस्टम में भिन्न होता है। यह कम से कम होना आवश्यक है 65536, लेकिन यह आमतौर पर 4294967295और 18446744073709551615कुछ प्रणालियों पर (2 ** 64-1) हो सकता है।
unsigned char) के बारे में सभी पूर्ण गारंटी को हटा दिया है । मानक में कहीं भी स्ट्रिंग '65535' या '65536' शामिल नहीं है, और '+32767' केवल नोट (1.9: 9) में संभव सबसे बड़े पूर्णांक के रूप में प्रतिनिधित्व करता है int; कोई गारंटी भी INT_MAXनहीं दी जाती है कि इससे छोटा नहीं हो सकता है!
Size_t प्रकार, sizeof ऑपरेटर द्वारा लौटाया गया प्रकार है। यह एक अहस्ताक्षरित पूर्णांक है जो मेजबान मशीन पर समर्थित किसी भी मेमोरी रेंज के बाइट्स में आकार को व्यक्त करने में सक्षम है। यह (सामान्यतया) ptrdiff_t से संबंधित है जिसमें ptrdiff_t एक हस्ताक्षरित पूर्णांक मान है जैसे कि sizeof (ptrdiff_t) और sizeof (size_t) समान हैं।
C कोड लिखते समय आपको मेमोरी रेंज के साथ काम करते समय हमेशा size_t का उपयोग करना चाहिए ।
दूसरी ओर इंट प्रकार को मूल रूप से (हस्ताक्षरित) पूर्णांक मान के आकार के रूप में परिभाषित किया गया है जिसका उपयोग मेजबान मशीन पूर्ण रूप से पूर्णांक अंकगणित करने के लिए कर सकती है। उदाहरण के लिए, कई पुराने पीसी प्रकार के कंप्यूटरों पर मूल्य sizeof (size_t) 4 (बाइट्स) होगा, लेकिन आकार (int) 2 (बाइट) होगा। 16 बिट अंकगणित 32 बिट अंकगणित से तेज था, हालांकि सीपीयू 4 गीब तक की (तार्किक) मेमोरी स्पेस को संभाल सकता था।
जब आप दक्षता के बारे में परवाह करते हैं तो इंट प्रकार का उपयोग करें क्योंकि इसकी वास्तविक परिशुद्धता कंपाइलर विकल्प और मशीन वास्तुकला दोनों पर दृढ़ता से निर्भर करती है। विशेष रूप से C मानक निम्नलिखित इनवेरिएंट्स को निर्दिष्ट करता है: sizeof (char) <= sizeof (छोटा) <= sizeof (int) <= sizeof (long) प्रत्येक के लिए प्रोग्रामर के लिए उपलब्ध परिशुद्धता के वास्तविक प्रतिनिधित्व पर कोई अन्य सीमाएं नहीं रखता है। ये आदिम प्रकार।
नोट: यह जावा के समान नहीं है (जो वास्तव में प्रत्येक प्रकार के 'चार', 'बाइट', 'शॉर्ट', 'इंट' और 'लॉन्ग') के लिए बिट परिशुद्धता को निर्दिष्ट करता है।
size_tकिसी भी एक वस्तु के आकार का प्रतिनिधित्व करने में सक्षम है (जैसे: संख्या, सरणी, संरचना)। संपूर्ण मेमोरी रेंज अधिक हो सकती हैsize_t
size_t- मुझे उम्मीद है कि आपका मतलब यह नहीं है। अधिकांश समय हम सरणियों से नहीं निपटते हैं जहां पते की कार्डिनैलिटी + पोर्टेबिलिटी भी मायने रखती है। इन मामलों में आप लेंगे size_t। हर दूसरे मामले में आप सूचकांकों को (हस्ताक्षरित) पूर्णांक से बाहर निकालते हैं। क्योंकि भ्रम की स्थिति (जो बिना किसी चेतावनी के आती है) अहस्ताक्षरित लोगों के अनियंत्रित व्यवहार से गिरफ्तार करना पोर्टेबिलिटी समस्याओं से अधिक सामान्य और बदतर है जो अन्य मामलों में उत्पन्न हो सकती है।
किसी भी संभावित वस्तु के आकार को संग्रहीत करने के लिए size_t पर्याप्त बड़ा होना चाहिए। अहस्ताक्षरित int को उस स्थिति को संतुष्ट नहीं करना है।
उदाहरण के लिए 64 बिट सिस्टम में int और अहस्ताक्षरित int 32 बिट वाइड हो सकते हैं, लेकिन size_t को 4G से बड़ी संख्या को संग्रहीत करने के लिए पर्याप्त होना चाहिए
size_tकि केवल इतना बड़ा होना होगा यदि कंपाइलर एक प्रकार के एक्स को स्वीकार कर सकता है जैसे कि साइज़ोफ़ (एक्स) 4 जी से बड़ा मूल्य प्राप्त करेगा। अधिकांश संकलक उदासीनता को अस्वीकार कर देंगे typedef unsigned char foo[1000000000000LL][1000000000000LL], और यहां तक foo[65536][65536];कि वैध रूप से खारिज कर दिया जा सकता है अगर यह एक प्रलेखित कार्यान्वयन-परिभाषित सीमा से अधिक हो।
विषय पर शोध करते समय glibc मैनुअल 0.02 का यह अंश भी प्रासंगिक हो सकता है:
2.4 जारी करने से पहले GCC के size_t प्रकार और संस्करणों के साथ एक संभावित समस्या है। ANSI C के लिए आवश्यक है कि size_t हमेशा एक अहस्ताक्षरित प्रकार का हो। मौजूदा सिस्टम की हेडर फाइलों के साथ अनुकूलता के लिए, GCC stddef.h' to be whatever type the system'sआकार_t को sys / type.h में परिभाषित करता है। अधिकांश यूनिक्स सिस्टम जो 'sys / type.h' में size_t को परिभाषित करते हैं, इसे एक हस्ताक्षरित प्रकार मानते हैं। लाइब्रेरी में कुछ कोड size_t पर एक अहस्ताक्षरित प्रकार होने पर निर्भर करता है, और यदि यह हस्ताक्षरित है तो सही ढंग से काम नहीं करेगा।
GNU C लाइब्रेरी कोड जो साइज़_ टी को अहस्ताक्षरित करने की अपेक्षा करता है, सही है। एक हस्ताक्षरित प्रकार के रूप में size_t की परिभाषा गलत है। हमारी योजना है कि संस्करण 2.4 में, GCC हमेशा size_t को एक अहस्ताक्षरित प्रकार, और fixincludes' script will massage the system'ssys / type.h 'के रूप में परिभाषित करेगा ताकि इससे संघर्ष न हो।
इस बीच, हम जीएनयू सी लाइब्रेरी को संकलित करते समय आकार_ के लिए एक अहस्ताक्षरित प्रकार का उपयोग करने के लिए स्पष्ट रूप से जीसीसी को बताकर इस समस्या के आसपास काम करते हैं। `कॉन्फ़िगर 'स्वचालित रूप से पता लगा लेगा कि आकार_ के लिए जीसीसी किस प्रकार का उपयोग करता है यदि आवश्यक हो तो इसे ओवरराइड करने की व्यवस्था करें।
अगर मेरा कंपाइलर 32 बिट पर सेट है, size_tतो इसके लिए टाइपराइफ के अलावा और कुछ नहीं है unsigned int। यदि मेरा कंपाइलर 64 बिट पर सेट है, size_tतो इसके लिए टाइपराइफ के अलावा और कुछ नहीं है unsigned long long।
unsigned longकुछ OS पर दोनों मामलों के लिए परिभाषित किया जा सकता है ।
size_t एक पॉइंटर का आकार है।
तो 32 बिट्स में या आम ILP32 (पूर्णांक, लंबा, सूचक) मॉडल size_t 32 बिट्स है। और 64 बिट्स या सामान्य LP64 (लंबे, पॉइंटर) मॉडल size_t में 64 बिट्स (पूर्णांक अभी भी 32 बिट्स हैं)।
अन्य मॉडल हैं लेकिन ये हैं कि जी ++ का उपयोग (कम से कम डिफ़ॉल्ट रूप से)
size_tजरूरी नहीं कि एक पॉइंटर के समान आकार हो, हालांकि यह आमतौर पर है। एक पॉइंटर को मेमोरी में किसी भी स्थान पर इंगित करने में सक्षम होना चाहिए; size_tकेवल सबसे बड़ी एकल वस्तु के आकार का प्रतिनिधित्व करने के लिए पर्याप्त बड़ा होना चाहिए।