सी चार सरणी आरंभीकरण


119

मुझे यकीन नहीं है कि निम्नलिखित तरीकों से आरंभ करने के बाद चार सरणी में क्या होगा।

1. char buf[10] = "";
2. char buf[10] = " ";
3।char buf[10] = "a";

मामले 2 के लिए, मुझे लगता है कि buf[0]होना चाहिए ' ', buf[1]होना चाहिए '\0', और से buf[2]करने के लिए buf[9]यादृच्छिक सामग्री हो जाएगा। मामले 3 के लिए, मुझे लगता है कि buf[0]होना चाहिए 'a', buf[1]होना चाहिए '\ 0', और से buf[2]करने के लिए buf[9]यादृच्छिक सामग्री हो जाएगा।

क्या वो सही है?

और केस 1 के लिए, इसमें क्या होगा buf? buf[0] == '\0'और से buf[1]करने के लिए buf[9]यादृच्छिक सामग्री हो जाएगा?


2
ठीक है, मेरा संकलक आपके (सही) कोड को स्वीकार नहीं करता है: "सरणी प्रकार 'चार [10]' असाइन करने योग्य नहीं है"।
मार्टिन आर

@ मार्टिनआर अब यह काम करेगा ...
22

1
@lkkeepmoving: संकलन नहींchar buf[10]; buf = "a"; करता है । - कृपया इसे पहले आज़माएँ, और फिर प्रश्न में अपना वास्तविक कोड कॉपी / पेस्ट करें । यह आपके और आपके प्रश्न के सभी पाठकों के लिए बहुत काम बचाता है।
मार्टिन आर।

@MartinR इसके लिए क्षमा करें। मुझे लगा कि मैं बुफ़ को बाद में सौंप सकता हूं लेकिन ऐसा लगता है कि नहीं। अब कोड चलता है।
lkkeepmoving

जवाबों:


222

यह नहीं है कि आप किसी सरणी को कैसे आरंभ करते हैं, बल्कि इसके लिए:

  1. पहली घोषणा:

    char buf[10] = "";

    के बराबर है

    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  2. दूसरी घोषणा:

    char buf[10] = " ";

    के बराबर है

    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
  3. तीसरी घोषणा:

    char buf[10] = "a";

    के बराबर है

    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};

जैसा कि आप देख सकते हैं, कोई यादृच्छिक सामग्री नहीं: यदि कम इनिशियलाइज़र हैं, तो शेष ऐरे के साथ आरंभीकृत किया जाता है 0। यह तब भी होता है जब किसी फ़ंक्शन के अंदर ऐरे को घोषित किया जाता है।


46
प्रश्न पूछने वाले व्यक्ति के लिए, यह इंगित करने योग्य है कि C मानक को शेष तत्वों (संकलक द्वारा) के लिए शून्य के साथ गद्देदार होने के लिए किसी भी आंशिक रूप से पूर्ण सरणी आरंभीकरण की आवश्यकता होती है। यह सभी डेटा प्रकारों के लिए जाता है, न कि केवल char
धान

4
@ उफ़ क्यों बुफ़ के अंत में कोई '\' है?
22 अक्टूबर को lkkeepmoving

14
@lkkeepmoving 0और '\0समान मूल्य है।
ahउ सिप

1
@lkkeepmoving इनिशियलाइज़ेशन और असाइनमेंट दो अलग-अलग जानवर हैं, इस प्रकार C आपको एक चार्ट के लिए इनिशियलाइज़र के रूप में एक स्ट्रिंग प्रदान करता है, लेकिन एरे असाइनमेंट्स को रोक देता है (जैसा कि ouah ने कहा)।
लोरेंजो डोनाटी - कोडिडैक्ट डॉट कॉम

3
@ स्पेसर char buff[3] = "abcdefghijkl";अमान्य है। char p3[5] = "String";भी अमान्य है। char p[6] = "String";मान्य है और जैसा है वैसा ही है char p[6] = {'S', 't', 'r', 'i', 'n', 'g'};
१ah

28

संपादित करें: ओपी (या एक संपादक) ने चुपचाप मूल प्रश्न के कुछ उद्धरणों में से कुछ को बदल दिया जब मैंने यह उत्तर प्रदान करने के बाद कुछ बिंदुओं पर दोहरे उद्धरण चिह्नों को बदल दिया।

आपके कोड का परिणाम संकलक त्रुटियों में होगा। आपका पहला कोड टुकड़ा:

char buf[10] ; buf = ''

दोगुना अवैध है। सबसे पहले, सी में, खाली जैसी कोई चीज नहीं है char। आप एक रिक्त स्ट्रिंग को नामित करने के लिए दोहरे उद्धरण चिह्नों का उपयोग कर सकते हैं:

char* buf = ""; 

यह आपको एक NULस्ट्रिंग को एक पॉइंटर देगा , यानी एक एकल-वर्ण स्ट्रिंग जिसमें केवल NULचरित्र होगा। लेकिन आप उनके अंदर कुछ भी नहीं के साथ एकल उद्धरण का उपयोग नहीं कर सकते हैं - जो अपरिभाषित है। यदि आपको NULचरित्र निर्दिष्ट करने की आवश्यकता है , तो आपको इसे निर्दिष्ट करना होगा:

char buf = '\0';

चरित्र से विमुख करने के लिए बैकस्लैश आवश्यक है '0'

char buf = 0;

एक ही बात को पूरा करता है, लेकिन पूर्व पढ़ने के लिए कम अस्पष्ट है, मुझे लगता है।

दूसरे, जब आप परिभाषित किए गए हैं, तो आप सरणियों को प्रारंभ नहीं कर सकते।

char buf[10];

ऐरे को घोषित करता है और परिभाषित करता है। सरणी पहचानकर्ता bufअब मेमोरी में एक पता है, और आप bufअसाइनमेंट के माध्यम से अंक नहीं बदल सकते हैं । इसलिए

buf =     // anything on RHS

गैरकानूनी है। आपके दूसरे और तीसरे कोड के टुकड़े इस कारण से अवैध हैं।

किसी सरणी को आरंभ करने के लिए, आपको इसे परिभाषा के समय करना होगा:

char buf [10] = ' ';

आपको पहले वर्ण के साथ एक 10-वर्ण सरणी देगा जिसमें अंतरिक्ष '\040'और शेष जा रहा है NUL, अर्थात '\0'। जब किसी ऐरे को घोषित किया जाता है और उसे इनिशियलाइज़र के साथ परिभाषित किया जाता है, तो एलीमेंट एलिमेंट्स (यदि कोई हो) को निर्दिष्ट इनिशियल वैल्यूज़ के साथ अतीत में स्वचालित रूप से पॉड किया जाता है 0। कोई भी "यादृच्छिक सामग्री" नहीं होगी।

यदि आप ऐरे को घोषित करते हैं और परिभाषित करते हैं, लेकिन इसे प्रारंभ नहीं करते हैं, जैसा कि निम्नलिखित में है:

char buf [10];

आपके पास सभी तत्वों में यादृच्छिक सामग्री होगी।


"एक सरणी को आरंभीकृत करने के लिए, आपको इसे परिभाषा के समय करना होगा ..." यह, और निम्न पंक्ति इसे स्वीकृत उत्तर से बेहतर बनाती है।
लॉरी स्टर्न

26
  1. ये बराबर हैं

    char buf[10] = "";
    char buf[10] = {0};
    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  2. ये बराबर हैं

    char buf[10] = " ";
    char buf[10] = {' '};
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
  3. ये बराबर हैं

    char buf[10] = "a";
    char buf[10] = {'a'};
    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};

8

C11 मानक ड्राफ्ट n1570 6.7.9 इनिशियलाइज़ेशन का प्रासंगिक हिस्सा कहता है:

14 वर्ण प्रकार का एक वर्ण वर्ण स्ट्रिंग शाब्दिक या UTF-8 स्ट्रिंग शाब्दिक द्वारा प्रारंभ किया जा सकता है, वैकल्पिक रूप से ब्रेसिज़ में संलग्न है। स्ट्रिंग शाब्दिक के क्रमिक बाइट्स (यदि कमरा है या यदि सरणी अज्ञात आकार का है, तो समाप्ति शून्य वर्ण सहित) सरणी के तत्वों को इनिशियलाइज़ करता है।

तथा

21 अगर किसी एंग्रेस से ब्रेस-एनक्लोजर लिस्ट में कम इनिशियलाइज़र हैं, तो एग्रीगेट के तत्व या सदस्य हैं, या किसी स्ट्रिंग लिटरल में कम कैरेक्टर हैं, जो एरे में एलीमेंट्स के बचे हुए एलीमेंट्स से बचे हुए साइज के ऐरर को एनालाइज करने के लिए इस्तेमाल करते हैं। स्थैतिक रूप से वैसा ही इनिशियलाइज़ किया जाना चाहिए जैसा स्थैतिक भंडारण अवधि है।

इस प्रकार, यदि पर्याप्त जगह है , तो '\ 0' को जोड़ दिया जाता है , और शेष वर्णों को उस मान static char c;से आरंभ किया जाता है, जो किसी फ़ंक्शन के भीतर आरम्भ किया जाएगा।

आखिरकार,

10 यदि ऐसी वस्तु जिसमें स्वत: भंडारण अवधि है, को स्पष्ट रूप से प्रारंभ नहीं किया गया है, तो इसका मूल्य अनिश्चित है। यदि स्थिर या थ्रेड स्टोरेज अवधि वाली कोई वस्तु स्पष्ट रूप से आरंभ नहीं की जाती है, तो:

[-]

  • यदि इसमें अंकगणित प्रकार है, तो इसे (सकारात्मक या अहस्ताक्षरित) शून्य से आरंभ किया जाता है;

[-]

इस प्रकार, charअंकगणित प्रकार का शेष सरणी होना भी शून्य के साथ आरंभ होने की गारंटी है।


3

दिलचस्प रूप से पर्याप्त है, कार्यक्रम में किसी भी समय किसी भी तरह से सरणियों को शुरू करना संभव है, बशर्ते कि वे structया एक सदस्य हों union

उदाहरण कार्यक्रम:

#include <stdio.h>

struct ccont
{
  char array[32];
};

struct icont
{
  int array[32];
};

int main()
{
  int  cnt;
  char carray[32] = { 'A', 66, 6*11+1 };    // 'A', 'B', 'C', '\0', '\0', ...
  int  iarray[32] = { 67, 42, 25 };

  struct ccont cc = { 0 };
  struct icont ic = { 0 };

  /*  these don't work
  carray = { [0]=1 };           // expected expression before '{' token
  carray = { [0 ... 31]=1 };    // (likewise)
  carray = (char[32]){ [0]=3 }; // incompatible types when assigning to type 'char[32]' from type 'char *'
  iarray = (int[32]){ 1 };      // (likewise, but s/char/int/g)
  */

  // but these perfectly work...
  cc = (struct ccont){ .array='a' };        // 'a', '\0', '\0', '\0', ...
  // the following is a gcc extension, 
  cc = (struct ccont){ .array={ [0 ... 2]='a' } };  // 'a', 'a', 'a', '\0', '\0', ...
  ic = (struct icont){ .array={ 42,67 } };      // 42, 67, 0, 0, 0, ...
  // index ranges can overlap, the latter override the former
  // (no compiler warning with -Wall -Wextra)
  ic = (struct icont){ .array={ [0 ... 1]=42, [1 ... 2]=67 } }; // 42, 67, 67, 0, 0, ...

  for (cnt=0; cnt<5; cnt++)
    printf("%2d %c %2d %c\n",iarray[cnt], carray[cnt],ic.array[cnt],cc.array[cnt]);

  return 0;
}

1

मुझे यकीन नहीं है, लेकिन मैं आमतौर पर एक सरणी को "" शुरू करता हूं उस स्थिति में मुझे स्ट्रिंग के अशक्त अंत के बारे में चिंता करने की आवश्यकता नहीं है।

main() {
    void something(char[]);
    char s[100] = "";

    something(s);
    printf("%s", s);
}

void something(char s[]) {
    // ... do something, pass the output to s
    // no need to add s[i] = '\0'; because all unused slot is already set to '\0'
}

आपको वास्तव में निहित इंट नियम का उपयोग नहीं करना चाहिए । आपको एक प्रकार निर्दिष्ट करना चाहिए main()(और आपको इसका उपयोग भी करना चाहिए void, अर्थात int main(void) { ... }। C99 को इस नियम से छुटकारा मिल गया है, इसलिए यह कोड C99 और बाद के लिए संकलित नहीं होगा। यहां ध्यान देने योग्य बात यह है कि C99 से शुरू होता है, यदि आप छोड़ देते हैं return। मुख्य, मुख्य के अंत में एक स्वचालित return 0;रखा / निहित है }। आप अंतर्निहित int नियम का उपयोग कर रहे हैं जो केवल C99 से पहले काम करता है, फिर भी आप अंतर्निहित का उपयोग कर रहे हैं returnजो केवल C99 के साथ काम करता है और बाद में ; ये दोनों स्पष्ट रूप से विरोधाभासी हैं। ।
रस्तजेडी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.