c - यदि मानक से 1 है तो 'साइज़ोफ़(चार)' क्यों लिखें?




coding-style (8)

मैं कुछ सी कोडिंग कर रहा था और कुछ सी कोड पढ़ने के बाद मैंने देखा है कि कोड स्निपेट जैसे हैं

char *foo = (char *)malloc(sizeof(char) * someDynamicAmount);

इसलिए मैं पूछना चाहता हूं कि चार सरणी के लिए मेमोरी आवंटित करने के लिए और अधिक सी-ईश रास्ता क्या है? sizeof(char) उपयोग करें और भविष्य में किसी भी मानक परिवर्तन के खिलाफ कोड को प्रमाणित करें या इसे छोड़ दें और सीधे नंबर का उपयोग करें?


मानक जानबूझकर आम प्रकारों के आकार के बारे में अस्पष्ट है। [ Wikipedia ]

हालांकि यह संभावना नहीं है कि char का आकार नहीं बदलेगा, लेकिन short का आकार बदल गया है। मुहावरेदार तरीका है:

type_t *foo = malloc(sizeof(type_t) * someDynamicAmount);

किसी भी प्रकार (सामान्य या जटिल) type_t या के लिए

type_t *foo = malloc(sizeof(*foo) * someDynamicAmount);

ताकि आप बाद में फू के प्रकार में परिवर्तन करने का निर्णय ले सकें और इसे केवल एक ही स्थान पर बदल सकें।


IMHO का सबसे अच्छा अभ्यास sizeof(*foo) लिखना है। फिर आप को कवर किया जाता है अगर फू का प्रकार बदल जाता है और आकार को ठीक नहीं किया जाता है।


आप सही हैं, मानक से, गुणा बेमतलब है। उस ने कहा, यह एक आदत की तरह लग रहा है कि किसी को लगातार हो गया है। यदि आप हमेशा sizeof() उपयोग करते हैं sizeof() , प्रकार की परवाह किए बिना, आप कभी नहीं भूलते हैं।

char *foo = (char *)malloc(sizeof(char) * someDynamicAmount);
int  *bar = (int  *)malloc(sizeof(int)  * someDynamicAmount);

की तुलना करें:

float*baz = malloc(sizeof(float) * someDynamicAmount);
int  *bar = malloc(sizeof(int)   * someDynamicAmount);
char *foo = malloc(sizeof(char)  * someDynamicAmount);

बनाम:

float*baz = malloc(sizeof(float) * someDynamicAmount);
int  *bar = malloc(sizeof(int)   * someDynamicAmount);
char *foo = malloc(someDynamicAmount);

मुझे पहला संस्करण पसंद है। क्या आप दूसरा पसंद करते हैं?


मैं इरादों को स्पष्ट करने के लिए sizeof(char) करता हूं। अगर कोई कभी भी फैसला करता है कि वह फू चाहता है, तो उसे पता है कि उसे पता है कि उसे काम करने के लिए sizeof(int) करना होगा।

या इसे छोड़ दें और संख्या का उपयोग करें

इसके अलावा जादू की संख्या का उपयोग करने के लिए यह बहुत अच्छा कोडिंग अभ्यास नहीं है।


यह सब कोडिंग स्टाइल का मामला है। कई शैलियों मौजूद हैं।

वास्तव में इस सवाल का जवाब देने के लिए, लोग लिखते हैं

malloc(n * sizeof(char))

उनके सभी कोड रखने के लिए जो malloc संगत का उपयोग करता है। अगली बार उन्हें int आवश्यकता हो सकती है और फिर वे उसी तरह कोड लिख सकते हैं,

malloc(n * sizeof(int))

तो इसका कारण कोडिंग शैली को सुसंगत रखना है। हालांकि sizeof(char) वास्तव में हमेशा 1 होने की गारंटी है और इसलिए यह बहुत ही शानदार है। यह स्व-दस्तावेजीकरण कोड लिखने का एक तरीका है।

हालांकि, सी में मॉलोक का उपयोग करने का सबसे आम तरीका शायद है

type* t = malloc(n * sizeof(*t));

या 100% समकक्ष:

type* t = malloc(n * sizeof *t);

चूंकि साइड-इफेक्ट के लिए sizeof के ऑपरेटर का मूल्यांकन नहीं किया गया है, यह कोड सुरक्षित है, भले ही चर t अभी तक आरंभिक नहीं है।

तीसरी संभावित शैली एक प्रकार से सही है, जो सरणी पॉइंटर्स का उपयोग करेगी, क्योंकि हम जो आवंटित करते हैं वह वास्तव में सरणियाँ हैं:

type (*t)[n] = malloc( sizeof(type[n]) );

यह शायद सबसे सही तरीका है, जहां तक ​​टाइप शुद्धता का संबंध है। एक सरणी का आकार आवंटित किया गया है, और हम एक सरणी सूचक के साथ आवंटित सरणी पर इंगित करते हैं।

हालाँकि, इस शैली के साथ समस्या यह है कि सरणी पॉइंटर्स सिंटैक्स में अतिरिक्त जटिलता जोड़ते हैं: आपको इस सरणी को (*t)[i] बजाय t[i] रूप में डी-रेफर करना होगा। यह कोड को पढ़ने में कठिन बनाता है। (और एक साइड-नोट के रूप में, यदि n एक पूर्णांक स्थिर अभिव्यक्ति नहीं है, तो कोड पुराने, पुराने Cilers पर संकलित नहीं होगा।)


सामान्य मुहावरा है

T *p = malloc(N * sizeof *p);

या

T *p;
...
p = malloc(N * sizeof *p);

इस तरह से आपको टाइप के बारे में चिंता करने की ज़रूरत नहीं है।


C99 मानक का हवाला देते हुए, खंड 6.5.3.4 sizeof ऑपरेटर :

जब एक ऐसे ऑपरेंड पर लागू किया जाता है जिसमें टाइप चार, अहस्ताक्षरित चार या हस्ताक्षरित चार (या एक योग्य संस्करण) होता है, तो परिणाम 1 होता है । जब एक ऑपरेंड पर लागू होता है जिसमें सरणी प्रकार होता है, तो परिणाम सरणी में बाइट्स की कुल संख्या होती है। जब एक ऐसे ऑपरेंड पर लागू किया जाता है जिसमें संरचना या संघ प्रकार होता है, तो परिणाम ऐसी वस्तु में बाइट्स की कुल संख्या है, जिसमें आंतरिक और अनुगामी पैडिंग शामिल है।

अर्थात्, मानक द्वारा sizeof char == 1 , कार्यान्वयन द्वारा नहीं। इसलिए sizeof(char) लिए और इसी तरह के मामलों में malloc() को कॉल करते समय sizeof(char) को छोड़ना बिल्कुल सही है। IMHO, यह अत्यधिक असंभव है कि भविष्य का C मानक कार्यान्वयन-विशिष्ट आकार के char को अनुमति देगा, क्योंकि बहुत अधिक कोड पहले से ही इस पर निर्भर करता है कि 1 और बैकवर्ड संगतता C में बहुत महत्वपूर्ण है।

इसलिए, सवाल केवल शैली के बारे में है, न कि शुद्धता के बारे में और यहां मैं एपीग्रामग्राम के उत्तर का समर्थन करता हूं ।







coding-style