C में size_t क्या है?


626

मैं size_tसी में भ्रमित हो रहा हूं। मुझे पता है कि यह sizeofऑपरेटर द्वारा लौटाया गया है । लेकिन वास्तव में यह क्या है? क्या यह एक डेटा प्रकार है?

मान लीजिए कि मेरे पास एक forलूप है:

for(i = 0; i < some_size; i++)

क्या मुझे उपयोग करना चाहिए int i;या size_t i;?


11
यदि वे आपके एकमात्र विकल्प हैं, intतो यदि some_sizeहस्ताक्षर किए गए हैं, size_tतो इसका उपयोग करें ।
नैट

8
@ यह गलत है। POSIX का ssize_t प्रकार है लेकिन वास्तव में उपयोग करने के लिए सही प्रकार ptrdiff_t है।
स्टीवन स्टीवर्ट-गैलस

2
जवाब निम्न स्तर के प्रोग्रामिंग के रूप में स्पष्ट नहीं हैं : C, असेंबली, और Intel® 64 पर प्रोग्राम निष्पादन । जैसा कि पुस्तक में कहा गया है, एक इंडेक्स का उपयोग करना int iएक विशाल सरणी को संबोधित करने के लिए पर्याप्त नहीं हो सकता है। तो size_t iआप अधिक सूचकांकों को संबोधित करके उपयोग कर सकते हैं, इसलिए भले ही आपके पास एक विशाल सरणी हो जो समस्या नहीं होनी चाहिए। size_tएक डेटा प्रकार है: आमतौर पर एक unsigned long intलेकिन यह आपके सिस्टम पर निर्भर करता है।
ब्रूनो

जवाबों:


461

विकिपीडिया से :

1999 आईएसओ सी मानक (C99) के अनुसार, size_tकम से कम 16 बिट का एक अहस्ताक्षरित पूर्णांक प्रकार है (अनुभाग 7.17 और 7.18.3 देखें)।

size_tकई सी / सी ++ मानकों द्वारा परिभाषित एक अहस्ताक्षरित डेटा प्रकार है, उदाहरण के लिए C99 ISO / IEC 9899 मानक, जिसमें परिभाषित किया गया है stddef.h1 यह आगे शामिल करके आयात किया जा सकता है stdlib.hक्योंकि यह फ़ाइल आंतरिक रूप से उप शामिल है stddef.h

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

निहितार्थ के रूप में, size_tकिसी भी सरणी सूचकांक को रखने के लिए एक प्रकार की गारंटी है।


4
"लाइब्रेरी फ़ंक्शंस जो आकार लेते हैं या वापस करते हैं, उनसे उम्मीद करते हैं कि वे ... size_t" को छोड़कर उस स्टेट () का उपयोग फ़ाइल के आकार के लिए off_t का उपयोग करते हैं
ड्रेमन

64
@ टिप्पणी वह टिप्पणी एक मौलिक भ्रम को दर्शाती है। size_tस्मृति में वस्तुओं के लिए है। C मानक भी परिभाषित नहीं करता है stat()या off_t(वे POSIX परिभाषाएँ हैं) या डिस्क या फ़ाइल सिस्टम के साथ कुछ भी करने के लिए - यह खुद को FILEधाराओं पर रोक देता है । वर्चुअल मेमोरी प्रबंधन फ़ाइल सिस्टम और फ़ाइल प्रबंधन से पूरी तरह से अलग है जहां तक ​​आकार की आवश्यकताएं हैं, इसलिए off_tयहाँ उल्लेख अप्रासंगिक है।
19013 में jw013

3
@ jw013: मैं शायद ही इसे एक बुनियादी भ्रम कहूंगा, लेकिन आप एक दिलचस्प बात करते हैं। फिर भी, उद्धृत पाठ "इन-मेमोरी ऑब्जेक्ट्स के आकार" नहीं कहता है, और "ऑफ़सेट" शायद ही किसी आकार प्रकार के लिए एक अच्छा नाम है, चाहे वह जहां भी संग्रहीत किया जाए।
ड्रेमन

30
@Draemon अच्छा बिंदु। यह उत्तर विकिपीडिया को उद्धृत करता है, जो इस मामले में मेरी राय में, सबसे अच्छा स्पष्टीकरण नहीं है। सी मानक स्वयं अधिक स्पष्ट है: यह ऑपरेटर size_tके परिणाम के प्रकार के रूप में परिभाषित करता है sizeof(7.17p2 के बारे में <stddef.h>)। धारा 6.5 में बताया गया है कि सी अभिव्यक्ति कैसे काम करती है (6.5.3.4 sizeof)। चूंकि आप sizeofएक डिस्क फ़ाइल पर लागू नहीं कर सकते हैं (ज्यादातर क्योंकि C यह भी परिभाषित नहीं करता है कि डिस्क और फाइलें कैसे काम करती हैं), भ्रम की कोई गुंजाइश नहीं है। दूसरे शब्दों में, विकिपीडिया को दोष दें (और विकिपीडिया को उद्धृत करने के लिए यह उत्तर और वास्तविक सी मानक नहीं)।
jw013

2
@Draemon - मैं "मूलभूत भ्रम" के आकलन से भी सहमत हूँ। यदि आपने C / C ++ मानकों को नहीं पढ़ा है, तो आप सोच सकते हैं कि "ऑब्जेक्ट" "ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग" को संदर्भित करता है, जो यह नहीं करता है। सी मानक पढ़ें, जिसमें उन ओओपी वस्तुओं में से कोई भी नहीं है, लेकिन अभी तक ऑब्जेक्ट हैं, और पता करें। जवाब आपको आश्चर्य में डाल सकता है!
हीथ हुननिकट

220

size_tएक अहस्ताक्षरित प्रकार है। इसलिए, यह किसी भी नकारात्मक मूल्यों का प्रतिनिधित्व नहीं कर सकता (<0)। आप इसका उपयोग तब करते हैं जब आप कुछ गिन रहे हों, और सुनिश्चित करें कि यह नकारात्मक नहीं हो सकता। उदाहरण के लिए, strlen()रिटर्न एsize_t क्योंकि एक स्ट्रिंग की लंबाई कम से कम 0 होनी चाहिए।

आपके उदाहरण में, यदि आपका लूप इंडेक्स हमेशा 0 से अधिक होने वाला है, तो यह उपयोग करने के लिए समझ में आता है size_t या किसी अन्य अहस्ताक्षरित डेटा प्रकार ।

जब आप किसी size_tऑब्जेक्ट का उपयोग करते हैं , तो आपको यह सुनिश्चित करना होगा कि अंकगणित सहित सभी संदर्भों में इसका उपयोग किया जाता है, आप गैर-नकारात्मक मान चाहते हैं। उदाहरण के लिए, मान लें कि आपके पास:

size_t s1 = strlen(str1);
size_t s2 = strlen(str2);

और आप की लंबाई str2और के अंतर को खोजना चाहते हैं str1। आप ऐसा नहीं कर सकते हैं:

int diff = s2 - s1; /* bad */

इसका कारण यह है कि निर्दिष्ट मान diffहमेशा एक सकारात्मक संख्या होने जा रहा है, तब भी s2 < s1, क्योंकि गणना अहस्ताक्षरित प्रकारों के साथ की जाती है। इस मामले में, आपके उपयोग का मामला क्या है, इस पर निर्भर करते हुए, आप और int(या long long) के उपयोग से बेहतर हो सकते हैं ।s1s2

C / POSIX में कुछ कार्य हैं जिनका उपयोग / उपयोग किया जाना चाहिए size_t, लेकिन ऐतिहासिक कारणों से नहीं। उदाहरण के लिए, दूसरा पैरामीटर fgetsआदर्श रूप से होना चाहिए size_t, लेकिन है int


8
@ आलोक: दो प्रश्न: 1) का आकार क्या है size_t? 2) मुझे size_tकुछ पसंद क्यों करना चाहिए unsigned int?
लेज़र

2
@ लेज़र: का आकार size_tहै sizeof(size_t)। सी मानक की गारंटी जो SIZE_MAXकम से कम 65535 होगी। ऑपरेटर size_tद्वारा लौटाया गया प्रकार है sizeof, और मानक पुस्तकालय में उपयोग किया जाता है (उदाहरण के लिए strlenरिटर्न size_t)। जैसा कि ब्रेंडन ने कहा, जैसा size_tहोना चाहिए वैसा नहीं होगा unsigned int
आलोक सिंघल

4
@ लेज़र - हाँ, size_tएक अहस्ताक्षरित प्रकार होने की गारंटी है।
आलोक सिंघल

2
@Celeritas नहीं, मेरा मतलब है कि एक अहस्ताक्षरित प्रकार केवल गैर-नकारात्मक मूल्यों का प्रतिनिधित्व कर सकता है। मुझे शायद "यह नकारात्मक मूल्यों का प्रतिनिधित्व नहीं कर सकता" कहा जाना चाहिए था।
आलोक सिंघल

4
@ जैसनऑस्टर, दो के पूरक सी मानक में एक आवश्यकता नहीं है। यदि s2 - s1ओवरफ्लो का मान a है int, तो व्यवहार अपरिभाषित है।
आलोक सिंघल

73

size_t एक प्रकार है जो किसी भी सरणी सूचकांक को पकड़ सकता है।

कार्यान्वयन के आधार पर, यह निम्नलिखित में से कोई भी हो सकता है:

unsigned char

unsigned short

unsigned int

unsigned long

unsigned long long

यहां बताया गया है कि मेरी मशीन कैसे size_tपरिभाषित की जाती stddef.hहै:

typedef unsigned long size_t;

4
निश्चित रूप typedef unsigned long size_tसे संकलक निर्भर है। या आप यह सुझाव दे रहे हैं कि ऐसा हमेशा होता है?
chux -

4
@chux: वास्तव में, सिर्फ इसलिए कि एक कार्यान्वयन इसे परिभाषित करता है जैसे कि इसका मतलब यह नहीं है कि सभी करते हैं। बिंदु में मामला: 64-बिट विंडोज। unsigned long32-बिट है, size_t64-बिट है।
टिम Timस

2
क्या वास्तव में size_t का उद्देश्य है? जब मैं अपने लिए एक चर बना सकता हूं जैसे: "int mysize_t;" या "लंबी mysize_t" या "अहस्ताक्षरित लंबी mysize_t"। किसी ने मेरे लिए यह चर क्यों बनाया होगा?
मिडकिन

1
@midkin size_tएक वैरिएबल नहीं है। यह एक प्रकार है जिसका उपयोग आप तब कर सकते हैं जब आप किसी ऑब्जेक्ट का आकार मेमोरी में दर्शाना चाहते हैं।
अर्जुन श्रीधरन

1
क्या यह सच है कि size_t32-बिट मशीन पर हमेशा 32 बिट्स होते हैं, इसी तरह 64 बिट्स?
जॉन वू

70

यदि आप अनुभवजन्य प्रकार हैं ,

echo | gcc -E -xc -include 'stddef.h' - | grep size_t

Ubuntu 14.04 64-बिट GCC 4.8 के लिए आउटपुट:

typedef long unsigned int size_t;

ध्यान दें कि stddef.hGCC द्वारा प्रदान किया गया है और src/gcc/ginclude/stddef.hGCC 4.2 के तहत glibc नहीं है ।

दिलचस्प C99 दिखावे

  • mallocsize_tतर्क के रूप में लेता है, इसलिए यह अधिकतम आकार निर्धारित करता है जिसे आवंटित किया जा सकता है।

    और चूंकि यह भी वापस आ गया है sizeof, मुझे लगता है कि यह किसी भी सरणी के अधिकतम आकार को सीमित करता है।

    यह भी देखें: C में किसी सरणी का अधिकतम आकार क्या है?


1
मेरे पास एक ही वातावरण है, हालांकि, मैंने 32 बिट्स के लिए परीक्षण किया है, जीसीसी के "-m32" विकल्प को पारित करते हुए, इसका परिणाम था: "टाइप किएडिफ अहस्ताक्षरित int size_t"। इस भयानक आदेश @Ciro को साझा करने के लिए धन्यवाद, इसने मेरी बहुत मदद की! :-)
सिल्विओप्रोग

2
मामला खुद भ्रामक नहीं है। यह भ्रमित दिमाग है जो कई सवाल पूछने की कोशिश करता है, और कई जवाब देता है। मुझे आश्चर्य है कि यह जवाब और अर्जुन श्रीधरन द्वारा दिया गया एक प्रश्न अभी भी लोगों को पूछने और जवाब देने से नहीं रोकता है।
बायोकैबरमैन

1
महान जवाब, क्योंकि यह वास्तव में आपको बताता है किsize_t कम से कम एक लोकप्रिय लिनक्स डिस्ट्रो पर क्या है
एंड्रे पोर्टनॉय


19

चूंकि किसी ने अभी तक इसका उल्लेख नहीं किया है, इसलिए प्राथमिक भाषाई महत्व size_tयह है कि sizeofऑपरेटर उस प्रकार का मान लौटाता है। इसी तरह, प्राथमिक महत्व ptrdiff_tयह है कि एक पॉइंटर को दूसरे से घटाने पर उस प्रकार का मान प्राप्त होगा। लाइब्रेरी फ़ंक्शंस जो इसे स्वीकार करते हैं, क्योंकि यह ऐसे फ़ंक्शंस को ऑब्जेक्ट्स के साथ काम करने की अनुमति देगा, जिनका आकार सिस्टम पर UINT_MAX से अधिक होता है, जहां ऐसी ऑब्जेक्ट मौजूद हो सकते हैं, बिना कॉलर्स को मजबूर करने के लिए कोड को सिस्टम पर "अहस्ताक्षरित" से बड़ा मान पास करने के लिए जहां बड़े प्रकार हैं सभी संभव वस्तुओं के लिए पर्याप्त होगा।


मेरा सवाल हमेशा से रहा है: यदि आकार का अस्तित्व कभी नहीं था, तो क्या size_t की आवश्यकता होगी?
डीन पी

@ डीनपी: शायद नहीं, हालांकि तब एक सवाल होगा कि चीजों के लिए किस प्रकार के तर्क का उपयोग किया जाना चाहिए malloc()। व्यक्तिगत रूप से, मैंने देखा संस्करणों किस प्रकार के तर्कों में आ सकें पसंद आया है | int, longऔर long longकुछ कार्यान्वयन को लागू करने जैसे छोटे प्रकार और दूसरों को बढ़ावा देने के साथ, lmalloc(long n) {return (n < 0 || n > 32767) ? 0 : imalloc(n);}[कुछ प्लेटफार्मों पर, कॉल करने imalloc(123)बुला की तुलना में सस्ता होगा lmalloc(123);, और यहां तक कि एक मंच है जहां पर size_t16 है बिट्स, कोड जो एक `long` मान में गणना की गई आकार आवंटित करना चाहता है ...
15

... आवंटन को असफल होने पर भरोसा करने में सक्षम होना चाहिए यदि मूल्य आवंटन से बड़ा है तो संभाल सकता है।
सुपरकैट

11

size_tअस्तित्व में रहने की आवश्यकता क्यों है और हम यहां कैसे पहुंचे:

व्यावहारिक शब्दों में, size_tऔर ptrdiff_t64-बिट कार्यान्वयन पर 64 बिट्स विस्तृत होने की गारंटी है, 32 बिट्स एक 32-बिट कार्यान्वयन पर, और इसी तरह। वे किसी भी मौजूदा प्रकार को यह कहने के लिए मजबूर नहीं कर सकते थे कि, प्रत्येक संकलक पर, बिना विरासत कोड को तोड़ने के।

एक size_tया ptrdiff_tआवश्यक रूप से के रूप में ही नहीं है intptr_tया uintptr_t। वे कुछ निश्चित आर्किटेक्चर पर भिन्न थे जो 80 के दशक के उत्तरार्ध में अभी भी उपयोग में थे size_tऔर ptrdiff_tमानक में जोड़े गए थे, और अप्रचलित हो रहे थे जब C99 ने कई नए प्रकार जोड़े लेकिन अभी तक नहीं गए (जैसे कि 16-बिट विंडोज)। 16-बिट संरक्षित मोड में x86 में खंडित मेमोरी थी जहां सबसे बड़ा संभव सरणी या संरचना आकार में केवल 65,536 बाइट्स हो सकती है, लेकिन farरजिस्टरों की तुलना में 32 बिट्स चौड़ा होने के लिए एक सूचक की आवश्यकता होती है। उन पर, intptr_t32 बिट्स चौड़े होंगे लेकिन size_tऔरptrdiff_tएक रजिस्टर में 16 बिट्स चौड़े और फिट हो सकते हैं। और कौन जानता था कि भविष्य में किस तरह का ऑपरेटिंग सिस्टम लिखा जा सकता है? सिद्धांत रूप में, i386 आर्किटेक्चर 48-बिट पॉइंटर्स के साथ 32-बिट सेगमेंटेशन मॉडल प्रदान करता है जिसे किसी भी ऑपरेटिंग सिस्टम ने वास्तव में उपयोग नहीं किया है।

एक मेमोरी ऑफ़सेट का प्रकार नहीं हो सकता है longक्योंकि अभी तक बहुत अधिक विरासत कोड मानता है कि longवास्तव में 32 बिट्स चौड़ा है। इस धारणा को UNIX और Windows API में भी बनाया गया था। दुर्भाग्य से, बहुत सारी अन्य विरासत कोड ने यह भी माना कि एक longपॉइंटर को पकड़ने के लिए पर्याप्त चौड़ा है, एक फ़ाइल ऑफसेट, सेकंड की संख्या जो 1970 के बाद से समाप्त हो गई है, और इसी तरह। POSIX अब पूर्व की बजाय बाद की धारणा को सच होने के लिए मजबूर करने के लिए एक मानकीकृत तरीका प्रदान करता है, लेकिन न तो बनाने के लिए एक पोर्टेबल धारणा है।

यह intइसलिए नहीं हो सका क्योंकि 90 के दशक में int64 बिट्स के चौड़े हिस्से में केवल कुछ मुट्ठी भर कंपाइलर थे । फिर वे long32 बिट्स को चौड़ा करके वास्तव में अजीब हो गए । मानक के अगले संशोधन ने इसे intअधिक से अधिक व्यापक होने के लिए अवैध घोषित किया long, लेकिन intअभी भी अधिकांश 64-बिट सिस्टम पर 32 बिट्स चौड़ा है।

यह नहीं हो सकता है long long int, जो वैसे भी बाद में जोड़ा गया था, क्योंकि यह 32-बिट सिस्टम पर भी कम से कम 64 बिट्स चौड़ा होने के लिए बनाया गया था।

इसलिए, एक नए प्रकार की आवश्यकता थी। यहां तक ​​कि अगर यह नहीं थे, तो उन सभी अन्य प्रकारों का मतलब एक सरणी या वस्तु के भीतर ऑफसेट के अलावा कुछ और था। और अगर 32-से-64-बिट माइग्रेशन के फ़िस्को से एक सबक था, तो यह विशिष्ट होना चाहिए कि किस प्रकार के गुणों के लिए आवश्यक गुण हैं, और एक का उपयोग न करें जो विभिन्न कार्यक्रमों में अलग-अलग चीजों का मतलब है।


"से असहमत हैं size_tऔर ptrdiff_t64-बिट कार्यान्वयन पर 64 बिट्स विस्तृत होने की गारंटी है ", आदि गारंटी ओवरस्टैटेड है। की सीमा size_tमुख्य रूप से कार्यान्वयन की मेमोरी क्षमता द्वारा संचालित होती है। "एन-बिट कार्यान्वयन" मुख्य रूप से पूर्णांकों की मूल प्रोसेसर चौड़ाई है। निश्चित रूप से कई कार्यान्वयन समान आकार की मेमोरी और प्रोसेसर बस की चौड़ाई का उपयोग करते हैं, लेकिन बहुत सारे मेमोरी वाले संकीर्ण प्रोसेसर या संकीर्ण प्रोसेसर मौजूद होते हैं और इन दो कार्यान्वयन गुणों को अलग करते हैं।
chux -

8

size_tऔर intविनिमेय नहीं हैं। उदाहरण के लिए 64-बिट लिनक्स size_t64-बिट आकार में (जैसे sizeof(void*)) है, लेकिन int32-बिट है।

यह भी ध्यान दें कि size_tअहस्ताक्षरित है। यदि आपको हस्ताक्षरित संस्करण की आवश्यकता है तो ssize_tकुछ प्लेटफार्मों पर है और यह आपके उदाहरण के लिए अधिक प्रासंगिक होगा।

एक सामान्य नियम के रूप में मैं का उपयोग कर सुझाव है कि intसबसे सामान्य मामलों के लिए और केवल का उपयोग size_t/ ssize_tजब वहाँ (के साथ इसके लिए एक विशिष्ट की जरूरत है mmap()उदाहरण के लिए)।


3

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


3
मैं आपका तर्क स्वीकार नहीं कर सकता। आप कहते हैं कि यह बेहतर है कि अतिप्रवाह बग चुपचाप आपके सरणी के भीतर वैध डेटा तक पहुंच जाता है?
माफ़-सॉफ्ट

1
@ माफ-मुलायम सही है। यदि त्रुटि पूर्ववत हो जाती है, तो यह प्रोग्राम क्रैश से भी बदतर बना देता है। यह उत्तर क्यों मिला?
yoyo_fun

यदि यह आपके सरणी में मान्य डेटा तक पहुँचता है तो यह बग नहीं है क्योंकि अहस्ताक्षरित प्रकार हस्ताक्षरित प्रकार की सीमा पर अतिप्रवाह नहीं होगा। क्या है ये तर्क लोग? मान लीजिए कि किसी कारण से आप 256 से अधिक तत्व सरणी पर पुनरावृति करने के लिए चार का उपयोग करते हैं ... हस्ताक्षर किए गए 127 पर अतिप्रवाह होगा और 128 वें तत्व को सिगसेव करेगा, लेकिन यदि आप अहस्ताक्षरित का उपयोग करते हैं, तो यह पूरे सरणी के माध्यम से जाएगा। फिर, जब आप एक int का उपयोग कर रहे हैं, तो आपके सरणियाँ वास्तव में 2 बिलियन तत्वों से बड़ी नहीं होंगी इसलिए किसी भी तरह से कोई फर्क नहीं पड़ता ...
बैंगनी आइस

1
मैं किसी भी स्थिति की कल्पना नहीं कर सकता जिसमें पूर्णांक अतिप्रवाह एक बग नहीं है, चाहे वह सकारात्मक या नकारात्मक के आसपास लपेटता हो। सिर्फ इसलिए कि आप एक segfault नहीं मिलता है इसका मतलब यह नहीं है कि आप सही व्यवहार देखें! और आप एक विभाजन दोष का अनुभव कर सकते हैं, या नहीं, चाहे आपकी ऑफसेट सकारात्मक हो या नकारात्मक; यह सब आपकी मेमोरी लेआउट पर निर्भर करता है। @PurpleIce, मुझे नहीं लगता कि आप इस उत्तर के रूप में एक ही बात कह रहे हैं; आपकी दलील यह प्रतीत होती है कि आपको उस डेटा प्रकार का चयन करना चाहिए, जिसमें आप जो सबसे बड़ा मूल्य रखना चाहते हैं, वह केवल सामान्य सामान्य ज्ञान है।
सोरेन ब्योर्नस्टैड

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

3

size_t अहस्ताक्षरित पूर्णांक डेटा प्रकार है। GNU C लाइब्रेरी का उपयोग करने वाले सिस्टम पर, यह अहस्ताक्षरित int या अहस्ताक्षरित long int होगा। size_t आमतौर पर सरणी अनुक्रमण और लूप काउंटिंग के लिए उपयोग किया जाता है।


1

size_t या किसी भी अहस्ताक्षरित प्रकार को लूप वेरिएबल के रूप में देखा जा सकता है क्योंकि लूप वैरिएबल आमतौर पर 0 से अधिक या उसके बराबर होते हैं।

जब हम एक size_t ऑब्जेक्ट का उपयोग करते हैं , तो हमें यह सुनिश्चित करना होगा कि सभी संदर्भों में इसका उपयोग किया जाता है, जिसमें अंकगणित भी शामिल है, हम केवल गैर-नकारात्मक मान चाहते हैं। उदाहरण के लिए, निम्नलिखित कार्यक्रम निश्चित रूप से अप्रत्याशित परिणाम देगा:

// C program to demonstrate that size_t or
// any unsigned int type should be used 
// carefully when used in a loop

#include<stdio.h>
int main()
{
const size_t N = 10;
int a[N];

// This is fine
for (size_t n = 0; n < N; ++n)
a[n] = n;

// But reverse cycles are tricky for unsigned 
// types as can lead to infinite loop
for (size_t n = N-1; n >= 0; --n)
printf("%d ", a[n]);
}

Output
Infinite loop and then segmentation fault

1

size_tएक अहस्ताक्षरित पूर्णांक डेटा प्रकार है जो केवल 0 और 0 से अधिक पूर्णांक मान निर्दिष्ट कर सकता है। यह किसी भी वस्तु के आकार के बाइट्स को मापता है और sizeofऑपरेटर द्वारा लौटाया जाता है। constका सिंटैक्स प्रतिनिधित्व है size_t, लेकिन constआप बिना प्रोग्राम चला सकते हैं।

const size_t number;

size_tनियमित रूप से सरणी अनुक्रमण और लूप काउंटिंग के लिए उपयोग किया जाता है। यदि कंपाइलर है 32-bitतो यह काम करेगा unsigned int। यदि कंपाइलर है तो 64-bitवह इस पर unsigned long long intभी काम करेगा । size_tसंकलक प्रकार के आधार पर अधिकतम आकार के लिए ।

size_tपहले से ही पर परिभाषित <stdio.h>हेडर फाइल है, लेकिन यह भी द्वारा परिभाषित कर सकते हैं <stddef.h>, <stdlib.h>, <string.h>, <time.h>, <wchar.h>हेडर।

  • उदाहरण (साथ const)
#include <stdio.h>

int main()
{
    const size_t value = 200;
    size_t i;
    int arr[value];

    for (i = 0 ; i < value ; ++i)
    {
        arr[i] = i;
    }

    size_t size = sizeof(arr);
    printf("size = %zu\n", size);
}

आउटपुट -: size = 800


  • उदाहरण (बिना const)
#include <stdio.h>

int main()
{
    size_t value = 200;
    size_t i;
    int arr[value];

    for (i = 0 ; i < value ; ++i)
    {
        arr[i] = i;
    }

    size_t size = sizeof(arr);
    printf("size = %zu\n", size);
}

आउटपुट -: size = 800


-3

मेरी समझ से, size_tएक unsignedपूर्णांक है जिसका बिट आकार देशी वास्तुकला के सूचक को पकड़ने के लिए पर्याप्त है।

इसलिए:

sizeof(size_t) >= sizeof(void*)

16
सच नहीं। प्वाइंटर का आकार इससे बड़ा हो सकता है size_t। कई उदाहरण: x86 वास्तविक मोड पर C कंपाइलरों में 32 बिट FARया HUGEपॉइंटर्स हो सकते हैं, लेकिन size_t अभी भी 16 बिट्स हैं। एक अन्य उदाहरण: वाटकॉम सी में विस्तारित मेमोरी के लिए एक विशेष वसा सूचक का उपयोग किया गया था जो कि 48 बिट्स चौड़ा size_tथा , लेकिन नहीं था। हार्वर्ड वास्तुकला के साथ एम्बेडेड नियंत्रक पर, आपके पास कोई सहसंबंध नहीं है, क्योंकि दोनों को अलग-अलग पते के स्थान की चिंता है।
पैट्रिक श्ल्टर

1
और उस पर stackoverflow.com/questions/1572099/… 128 बिट बिंदुओं और 32 बिट के साथ एएस / 400 के अधिक उदाहरण हैंsize_t
पैट्रिक श्लुटर

यह स्पष्ट रूप से गलत है। हालाँकि, आइए इसे यहां रखें
एंटटी हवाला
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.