C Language
प्रारंभ
खोज…
सी में चर की शुरुआत
स्पष्ट आरंभीकरण की अनुपस्थिति में, बाहरी और static
चर को शून्य से आरंभिक होने की गारंटी है; स्वचालित चर ( register
चर सहित) में अनिश्चित 1 (यानी, कचरा) प्रारंभिक मूल्य हैं।
स्केलर वैरिएबल को तब इनिशियलाइज़ किया जा सकता है जब उन्हें एक समान चिन्ह और एक एक्सप्रेशन के साथ नाम के साथ परिभाषित किया जाता है:
int x = 1;
char squota = '\'';
long day = 1000L * 60L * 60L * 24L; /* milliseconds/day */
बाहरी और static
चर के लिए, इनिलाइज़र एक स्थिर अभिव्यक्ति 2 होना चाहिए; आरंभीकरण एक बार किया जाता है, वैचारिक रूप से कार्यक्रम के निष्पादन से पहले।
स्वचालित और register
चर के लिए, इनिलाइज़र एक स्थिर होने के लिए प्रतिबंधित नहीं है: यह किसी भी अभिव्यक्ति हो सकती है जिसमें पहले से परिभाषित मान शामिल हैं, यहां तक कि फ़ंक्शन कॉल भी।
उदाहरण के लिए, नीचे कोड स्निपेट देखें
int binsearch(int x, int v[], int n)
{
int low = 0;
int high = n - 1;
int mid;
...
}
के बजाय
int low, high, mid;
low = 0;
high = n - 1;
वास्तव में, स्वचालित चर का आरंभीकरण असाइनमेंट स्टेटमेंट के लिए संक्षिप्त है। पसंद करने के लिए कौन सा रूप काफी हद तक स्वाद का विषय है। हम आम तौर पर स्पष्ट असाइनमेंट का उपयोग करते हैं, क्योंकि घोषणाओं में इनिशियलाइज़र देखने के लिए कठिन हैं और उपयोग के बिंदु से दूर हैं। दूसरी ओर, चर केवल तभी घोषित किए जाने चाहिए जब वे उपयोग किए जाने वाले हों।
एक सरणी की शुरुआत:
एक सरणी को ब्रेसिज़ में संलग्न इनिशियलाइज़र की सूची के साथ इसकी घोषणा के बाद शुरू किया जा सकता है और कॉमा द्वारा अलग किया जा सकता है।
उदाहरण के लिए, प्रत्येक माह में दिनों की संख्या के साथ एक सरणी दिनों को आरम्भ करने के लिए:
int days_of_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
(ध्यान दें कि जनवरी इस संरचना में महीने के शून्य के रूप में एन्कोडेड है।)
जब सरणी का आकार छोड़ दिया जाता है, तो कंपाइलर इनिशियलाइज़र की गिनती करके लंबाई की गणना करेगा, जिनमें से इस मामले में 12 हैं।
यदि निर्दिष्ट आकार की तुलना में किसी सरणी के लिए कम इनिलाइज़र हैं, तो अन्य सभी प्रकार के चर के लिए शून्य होंगे।
बहुत सारे इनिशियलाइज़र रखना एक त्रुटि है। इनिशियलाइज़र के दोहराव को निर्दिष्ट करने का कोई मानक तरीका नहीं है - लेकिन जीसीसी के पास ऐसा करने के लिए एक एक्सटेंशन है।
C89 / C90 या C के पुराने संस्करणों में, किसी भी सरणी के बीच में एक तत्व को इनिशियलाइज़ करने का कोई तरीका नहीं था, साथ ही सभी पूर्ववर्ती मूल्यों की आपूर्ति किए बिना।
C99 और इसके बाद के संस्करण के साथ, निर्दिष्ट इनिशियलाइज़र आपको किसी सरणी के मनमाने तत्वों को आरंभीकृत करने की अनुमति देता है, जो शून्य के रूप में किसी भी अनधिकृत मान को छोड़ देता है।
चरित्र सरणियों को आरम्भिक करना:
चरित्र सरणियाँ आरंभीकरण का एक विशेष मामला है; एक स्ट्रिंग ब्रेस और कॉमा नोटेशन के बजाय इस्तेमाल किया जा सकता है:
char chr_array[] = "hello";
अब और समतुल्य के लिए एक आशुलिपि है:
char chr_array[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
इस स्थिति में, सरणी का आकार छह है (पांच अक्षर प्लस '\0'
)।
1 सी में एक घोषित, गैर-पंजीकृत चर क्या होता है? क्या इसका कोई मूल्य है?
2 ध्यान दें कि एक स्थिर अभिव्यक्ति को ऐसे कुछ के रूप में परिभाषित किया जाता है जिसका संकलन-समय पर मूल्यांकन किया जा सकता है। तो, int global_var = f();
अमान्य है। एक और आम गलतफहमी एक स्थिर अभिव्यक्ति के रूप में एक const
योग्य चर के बारे में सोच रही है। C में, const
अर्थ "रीड-ओनली" है, न कि "कम्पाइल टाइम कंटीन्यू"। तो, वैश्विक अंतर जैसे कि const int SIZE = 10; int global_arr[SIZE];
और const int SIZE = 10; int global_var = SIZE;
सी। में कानूनी नहीं हैं।
संरचनाओं की प्रारंभिक संरचना और सरणियाँ
संरचनाओं की संरचना और सरणियों को ब्रेसिज़ में संलग्न मूल्यों की एक श्रृंखला द्वारा शुरू किया जा सकता है, संरचना के प्रति सदस्य एक मूल्य।
struct Date
{
int year;
int month;
int day;
};
struct Date us_independence_day = { 1776, 7, 4 };
struct Date uk_battles[] =
{
{ 1066, 10, 14 }, // Battle of Hastings
{ 1815, 6, 18 }, // Battle of Waterloo
{ 1805, 10, 21 }, // Battle of Trafalgar
};
ध्यान दें कि सरणी आरंभीकरण को आंतरिक ब्रेसिज़ के बिना लिखा जा सकता है, और कई बार अतीत में (1990 से पहले, कहते हैं) अक्सर इसके बिना लिखा जा सकता है:
struct Date uk_battles[] =
{
1066, 10, 14, // Battle of Hastings
1815, 6, 18, // Battle of Waterloo
1805, 10, 21, // Battle of Trafalgar
};
हालांकि यह काम करता है, यह अच्छी आधुनिक शैली नहीं है - आपको नए कोड में इस नोटेशन का उपयोग करने का प्रयास नहीं करना चाहिए और कंपाइलर चेतावनी को ठीक करना चाहिए जो आमतौर पर उपज देता है।
निर्दिष्ट इनिशियलाइज़र भी देखें।
नामित इनिशियलाइज़र का उपयोग करना
C99 ने नामित इनिशियलाइज़र की अवधारणा पेश की । ये आपको यह निर्दिष्ट करने की अनुमति देते हैं कि किसी सरणी, संरचना या संघ के कौन से तत्व निम्नलिखित मानों द्वारा आरंभिक हैं।
सरणी तत्वों के लिए नामित इनिशियलाइज़र
सादे int
तरह एक सरल प्रकार के लिए:
int array[] = { [4] = 29, [5] = 31, [17] = 101, [18] = 103, [19] = 107, [20] = 109 };
वर्गाकार कोष्ठकों में शब्द, जो किसी भी पूर्णांक पूर्णांक की अभिव्यक्ति हो सकती है, यह निर्दिष्ट करता है कि सरणी के किस तत्व को =
चिन्ह के बाद शब्द के मान से आरम्भ किया जाना है। अनिर्दिष्ट तत्व डिफ़ॉल्ट आरंभिक हैं, जिसका अर्थ है कि शून्य परिभाषित हैं। उदाहरण क्रम में निर्दिष्ट आरंभीकृत दिखाता है; उन्हें क्रम में होना जरूरी नहीं है। उदाहरण अंतराल को दर्शाता है; वे वैध हैं। उदाहरण एक ही तत्व के लिए दो अलग-अलग इनिशियलाइज़ेशन नहीं दिखाता है; यह भी अनुमत है (ISO / IEC 9899: 2011, .76.7.9 इनिशियलाइज़ेशन, The19 इनिशियलाइज़र सूची क्रम में होगा, प्रत्येक इनिशियलाइज़र किसी विशेष सबोबिज के लिए प्रदान किया गया है जो उसी उप-विषयक के लिए किसी भी पहले सूचीबद्ध इनिशियलाइज़र को ओवरराइड करता है )।
इस उदाहरण में, सरणी के आकार को स्पष्ट रूप से परिभाषित नहीं किया गया है, इसलिए निर्दिष्ट शुरुआती निर्दिष्ट में निर्दिष्ट अधिकतम सूचकांक सरणी के आकार को निर्धारित करता है - जो उदाहरण में 21 तत्व होगा। यदि आकार को परिभाषित किया गया था, तो सरणी के अंत से परे एक प्रविष्टि को शुरू करना एक त्रुटि होगी, हमेशा की तरह।
संरचनाओं के लिए नामित इनिशियलाइज़र
आप निर्दिष्ट कर सकते हैं कि संरचना के किन तत्वों का उपयोग करके आरंभ किया गया है .
element
संकेतन:
struct Date
{
int year;
int month;
int day;
};
struct Date us_independence_day = { .day = 4, .month = 7, .year = 1776 };
यदि तत्व सूचीबद्ध नहीं हैं, तो वे डिफ़ॉल्ट आरंभीकृत (शून्य) हैं।
यूनियनों के लिए नामित इनिशियलाइज़र
आप निर्दिष्ट कर सकते हैं कि संघ का कौन सा तत्व निर्दिष्ट इनिशियलाइज़र के साथ इनिशियलाइज़ है।
सी मानक से पहले, union
को शुरू करने का कोई तरीका नहीं था। C89 / C90 मानक आपको एक union
के पहले सदस्य को शुरू करने की अनुमति देता है - इसलिए किस सदस्य की पसंद पहले मामलों में सूचीबद्ध है।
struct discriminated_union
{
enum { DU_INT, DU_DOUBLE } discriminant;
union
{
int du_int;
double du_double;
} du;
};
struct discriminated_union du1 = { .discriminant = DU_INT, .du = { .du_int = 1 } };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du = { .du_double = 3.14159 } };
ध्यान दें कि C11 आपको एक संरचना के अंदर अनाम यूनियन सदस्यों का उपयोग करने की अनुमति देता है, ताकि आपको पिछले उदाहरण में du
नाम की आवश्यकता न हो:
struct discriminated_union
{
enum { DU_INT, DU_DOUBLE } discriminant;
union
{
int du_int;
double du_double;
};
};
struct discriminated_union du1 = { .discriminant = DU_INT, .du_int = 1 };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du_double = 3.14159 };
संरचनाओं के सरणियों के लिए नामित इनिशियलाइज़र आदि
इन निर्माणों को संरचनाओं के सरणियों के लिए जोड़ा जा सकता है जिसमें एरेस आदि तत्व होते हैं, ब्रेसिज़ के पूर्ण सेट का उपयोग यह सुनिश्चित करता है कि अंकन अस्पष्ट है।
typedef struct Date Date; // See earlier in this example
struct date_range
{
Date dr_from;
Date dr_to;
char dr_what[80];
};
struct date_range ranges[] =
{
[3] = { .dr_from = { .year = 1066, .month = 10, .day = 14 },
.dr_to = { .year = 1066, .month = 12, .day = 25 },
.dr_what = "Battle of Hastings to Coronation of William the Conqueror",
},
[2] = { .dr_from = { .month = 7, .day = 4, .year = 1776 },
.dr_to = { .month = 5, .day = 14, .year = 1787 },
.dr_what = "US Declaration of Independence to Constitutional Convention",
}
};
सरणी इनिशियलाइज़र में श्रेणियाँ निर्दिष्ट करना
जीसीसी एक एक्सटेंशन प्रदान करता है जो आपको एक सरणी में तत्वों की एक श्रृंखला निर्दिष्ट करने की अनुमति देता है जिसे एक ही इनिशलाइज़र दिया जाना चाहिए:
int array[] = { [3 ... 7] = 29, 19 = 107 };
ट्रिपल डॉट्स को संख्याओं से अलग करने की जरूरत है, ऐसा नहीं है कि डॉट्स में से एक को फ्लोटिंग पॉइंट नंबर ( मैक्सिमम मच रूल) के हिस्से के रूप में व्याख्या किया जाए।