किसी सरणी के सभी सदस्यों को समान मान के लिए कैसे प्रारंभ करें?


968

मेरे पास C में एक बड़ा सरणी है ( C ++ नहीं है अगर इससे कोई फर्क पड़ता है)। मैं एक ही मूल्य के सभी सदस्यों को इनिशियलाइज़ करना चाहता हूँ।

मैं शपथ ले सकता था कि मैं एक बार ऐसा करने का एक सरल तरीका जानता था। मैं memset()अपने मामले में उपयोग कर सकता हूं, लेकिन क्या ऐसा करने का कोई तरीका नहीं है जो सी सिंटैक्स में बनाया गया है?


16
अब तक किसी भी उत्तर में निर्दिष्ट प्रारंभिक संकेतन का उल्लेख नहीं है जो C99 और इसके बाद के संस्करण के साथ संभव है। उदाहरण के लिए: enum { HYDROGEN = 1, HELIUM = 2, CARBON = 6, NEON = 10, … };और struct element { char name[15]; char symbol[3]; } elements[] = { [NEON] = { "Neon", "Ne" }, [HELIUM] = { "Helium", "He" }, [HYDROGEN] = { "Hydrogen", "H" }, [CARBON] = { "Carbon", "C" }, … };। यदि आप दीर्घवृत्त निकालते हैं , तो वे टुकड़े C99 या C11 के तहत संकलन करते हैं।
जोनाथन लेफ़लर

वास्तव में एबेलेंकी का जवाब नामित आरंभीकरण का उपयोग कर रहा है, लेकिन पूरी तरह से प्रारंभिक कोड नहीं बना है
Rob11311

मेमसेट () मदद कर सकता है, लेकिन मूल्य पर निर्भर करता है।
निक

2
memset()विशिष्ट चर्चा: stackoverflow.com/questions/7202411/… मुझे लगता है कि यह केवल 0. के लिए काम करता है
Ciro Santilli 审查 flow flow flow '

जवाबों:


1238

जब तक कि मान 0 नहीं है (जिस स्थिति में आप इनिशियलाइज़र के कुछ भाग को छोड़ सकते हैं और संबंधित तत्वों को 0 पर इनिशियलाइज़ किया जाएगा), कोई आसान तरीका नहीं है।

हालांकि, स्पष्ट समाधान की अनदेखी न करें:

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };

अनुपलब्ध मान वाले तत्वों को 0 से आरंभ किया जाएगा:

int myArray[10] = { 1, 2 }; // initialize to 1,2,0,0,0...

तो यह सभी तत्वों को 0 से आरंभ करेगा:

int myArray[10] = { 0 }; // all elements 0

C ++ में, एक खाली इनिशियलाइज़ेशन लिस्ट भी हर एलिमेंट को 0. इनिशियलाइज़ करेगी। C के साथ इसकी अनुमति नहीं है:

int myArray[10] = {}; // all elements 0 in C++

याद रखें कि स्थिर भंडारण अवधि वाली वस्तुएं 0 को इनिशियलाइज़ करेंगी यदि कोई इनिशियलाइज़र निर्दिष्ट नहीं है:

static int myArray[10]; // all elements 0

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


27
C ++ मानक के माध्यम से पढ़ना, आप int array [10] = {} भी कर सकते हैं; जीरो इनिशियलाइज़ करने के लिए। मेरे पास यह जाँचने के लिए C मानक नहीं है कि यह मान्य C है और साथ ही।
वर्कमाड 3

54
C99 मानक के खंड 6.7.8 की शुरुआत को देखते हुए, ऐसा नहीं लगता है कि एक खाली इनिशियलाइज़र सूची की अनुमति है।
जोनाथन लेफ्लर

7
C99 में संरचना और सरणी आरंभीकरण के लिए कई अच्छी विशेषताएं हैं; एक विशेषता यह नहीं है (लेकिन फोरट्रान IV, 1966, था) एक सरणी के लिए एक विशेष इनिशियलाइज़र को दोहराने का एक तरीका है।
जोनाथन लेफ्लर

8
@CetinSert: आपका क्या मतलब है कि यह काम नहीं करता है? यह वही करता है जो यह उत्तर कहता है कि इसे करना चाहिए। यह वह नहीं करता है जो आपके कोड में टिप्पणी कहती है, लेकिन वह टिप्पणी गलत है।
बेंजामिन लिंडले

9
@CetinSert: आप केवल एक ही दावा करते हैं, उस टिप्पणी में, सभी तत्व -1 पर सेट होंगे। यह उत्तर सही दावा करता है, कि सभी अनिर्दिष्ट तत्व शून्य पर सेट हो जाते हैं। आपके कोड के परिणाम इस दावे के अनुरूप हैं।
बेंजामिन लिंडले

394

यदि आपका कंपाइलर GCC है तो आप सिंटैक्स का उपयोग कर सकते हैं:

int array[1024] = {[0 ... 1023] = 5};

विस्तृत विवरण देखें: http://gcc.gnu.org/onbuildocs/gcc-4.1.2/gcc/Designated-Inn.html


12
और वह वाक्य रचना संकलित बायनेरिज़ के फ़ाइल आकार में भारी वृद्धि का कारण बनती है। N = 65536 (1024 के बजाय) के लिए, मेरा बाइनरी 15 केबी से 270 केबी आकार में कूदता है !!
Cetin Sert

50
@CetinSert कंपाइलर को 65536 ints को स्टेटिक डेटा में जोड़ना है , जो कि 256 K है - आपके द्वारा देखे गए आकार में वृद्धि।
qrdl

15
@CetinSert मुझे क्यों करना चाहिए? यह एक मानक संकलक व्यवहार है, जो निर्दिष्ट आरंभीकरण के लिए विशिष्ट नहीं है। यदि आप वैधानिक रूप से 65536 सेकेंड का इनिशियलाइज़ करते हैं int, int foo1 = 1, foo2 = 1, ..., foo65536 =1;तो आपको समान आकार में वृद्धि मिलेगी।
क्यूर्डल

27
बेहतर अभी तक: "इंट सरणी [] = {[0 ... 1023] = 5}", सरणी का आकार स्वचालित रूप से 1024, आसान और संशोधित करने के लिए सुरक्षित हो जाएगा।
फ्रेंकोइस

4
@ फ्रैंकोइस या एक 2 डी सरणी के लिए bool array[][COLS] = { [0...ROWS-1][0...COLS-1] = true}, हालांकि मैं निश्चित नहीं हूं कि यह पूर्ण रूप से अधिक पठनीय है।
g33kz0r

178

एक ही मान के साथ एक बड़े सरणी को कई कॉपी-पेस्ट के बिना सांख्यिकीय रूप से आरम्भ करने के लिए, आप मैक्रोज़ का उपयोग कर सकते हैं:

#define VAL_1X     42
#define VAL_2X     VAL_1X,  VAL_1X
#define VAL_4X     VAL_2X,  VAL_2X
#define VAL_8X     VAL_4X,  VAL_4X
#define VAL_16X    VAL_8X,  VAL_8X
#define VAL_32X    VAL_16X, VAL_16X
#define VAL_64X    VAL_32X, VAL_32X

int myArray[53] = { VAL_32X, VAL_16X, VAL_4X, VAL_1X };

यदि आपको मूल्य बदलने की आवश्यकता है, तो आपको केवल एक स्थान पर प्रतिस्थापन करना होगा।

संपादित करें: संभव उपयोगी एक्सटेंशन

( जोनाथन लेफ़लर के सौजन्य से )

आप इसे आसानी से सामान्यीकृत कर सकते हैं:

#define VAL_1(X) X
#define VAL_2(X) VAL_1(X), VAL_1(X)
/* etc. */

एक संस्करण का उपयोग करके बनाया जा सकता है:

#define STRUCTVAL_1(...) { __VA_ARGS__ }
#define STRUCTVAL_2(...) STRUCTVAL_1(__VA_ARGS__), STRUCTVAL_1(__VA_ARGS__)
/*etc */ 

जो संरचनाओं या यौगिक सरणियों के साथ काम करता है।

#define STRUCTVAL_48(...) STRUCTVAL_32(__VA_ARGS__), STRUCTVAL_16(__VA_ARGS__)

struct Pair { char key[16]; char val[32]; };
struct Pair p_data[] = { STRUCTVAL_48("Key", "Value") };
int a_data[][4] = { STRUCTVAL_48(12, 19, 23, 37) };

स्थूल नाम परक्राम्य हैं।


12
मैं केवल चरम मामलों में इस पर विचार करूंगा, निश्चित रूप से इसे व्यक्त करने के लिए एक अधिक आकर्षक तरीका है।
u0b34a0f6ae

47
यदि डेटा को ROM-सक्षम होना चाहिए, तो मेमसेट का उपयोग नहीं किया जा सकता है।
प्रो। फाल्कन कॉन्ट्रैक्ट ने

9
Preprocessor वास्तव में #defines से कोड जेनरेट करेगा। बड़े सरणी आयामों के साथ निष्पादन योग्य आकार बढ़ेगा। लेकिन निश्चित रूप से (विचार के लिए;)
लियोनिद

7
@Alcott, पुराने कंप्यूटर पर और अभी भी कई एम्बेडेड सिस्टम पर, कोड को अंततः EPROM या ROM में रखा गया है । ROM- सक्षम का अर्थ एम्बेडेड सिस्टम, "कोड पुट इन फ्लैश" से भी है, क्योंकि इसमें एक ही निहितार्थ होता है, अर्थात मेमोरी को रनटाइम नहीं लिखा जा सकता है। यानी मेमरी को अपडेट करने या बदलने के लिए किसी अन्य निर्देश का उपयोग नहीं किया जा सकता है। स्थिरांक है, हालांकि, व्यक्त की और दिखाया या पहले कार्यक्रम शुरू होने से रोम-एड जा सकता है।
प्रो। फाल्कन कॉन्ट्रैक्ट का उल्लंघन

4
@ u0b34a0f6ae: ध्यान रखें कि आप इस पद्धति का उपयोग कर सकते हैं, भले VAL_1Xही एक पूर्णांक एक सूची न हो। Amigable राज्यों की तरह, यह भी एम्बेडेड सिस्टम के लिए जाने का एक तरीका है जहां आप EEPROM या फ़्लैश मेमोरी के init मानों को परिभाषित करना चाहते हैं। दोनों ही मामलों में आप उपयोग नहीं कर सकते memset()
मार्टिन शेहरर

63

आप यह सुनिश्चित करें कि सरणी के हर सदस्य को स्पष्ट रूप से आरंभ नहीं हो जाता चाहते हैं, सिर्फ घोषणा से आयाम को छोड़ देते हैं:

int myArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

कंपाइलर इनिशियलाइज़र सूची से आयाम को घटा देगा। दुर्भाग्य से, बहुआयामी सरणियों के लिए केवल सबसे बाहरी आयाम छोड़ा जा सकता है:

int myPoints[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

ठीक है, लेकिन

int myPoints[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

नहीं है।


क्या ये सही है ? int myPoints[10][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };
प्रवीण गौड़ा IV

10
नहीं, आप अंतरतम आयाम को छोड़ रहे हैं, जिसकी अनुमति नहीं है। यह एक संकलक त्रुटि देगा।
फ्रैंक एसबगैटा

4
शुरुआती और लंबाई के अनुमान दोनों को C99 में पेश किया गया था।
पालिक

3
@Palec: पूर्व-मानक C (K & R 1st संस्करण प्रकाशित होने के बाद से और शायद उससे कुछ समय पहले) के दिनों से C - लंबाई में अनुमान नहीं था। C99 में नामित इनिशियलाइज़र नए थे, लेकिन यह नामित इनिशियलाइज़र का उपयोग नहीं कर रहा है।
जोनाथन लेफ़लर

53

मैंने कुछ कोड देखे जो इस वाक्यविन्यास का उपयोग करते थे:

char* array[] = 
{
    [0] = "Hello",
    [1] = "World"
};   

जहां यह विशेष रूप से उपयोगी हो जाता है, यदि आप एक ऐसा सरणी बना रहे हैं जो इंडेक्स के रूप में एनम का उपयोग करता है:

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

#define _ITEM(x) [x] = #x

char* array[] = 
{
    _ITEM(ERR_OK),
    _ITEM(ERR_FAIL),
    _ITEM(ERR_MEMORY)
};   

यह चीजों को क्रम में रखता है, भले ही आप कुछ एनुम-वैल्यू को ऑर्डर से बाहर लिखते हों।

इस तकनीक के बारे में और अधिक जानकारी यहाँ और यहाँ मिल सकती है


8
यह C99 इनिशियलाइज़र सिंटैक्स है, जो पहले से ही कुछ अन्य उत्तरों द्वारा कवर किया गया है। आप उपयोगी रूप से घोषणा कर सकते हैं char const *array[] = { ... };या यहां तक ​​कि char const * const array[] = { ... };, आप नहीं कर सकते?
जोनाथन लेफ़लर

22
int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

मुझे लगता है कि यह इससे बेहतर है

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5...

सरणी परिवर्तन का आकार बढ़ाएँ।


12
रिकॉर्ड के लिए, यह मूल रूप से सिर्फ एक धीमा, अधिक क्रियात्मक संस्करण हैmemset(myArray, VALUE, ARRAY_SIZE);
बेन्सन

18
आप 255 से अधिक मूल्य वाले इंट सरणी को इनिशियलाइज़ करने के लिए मेमरी का उपयोग कैसे करेंगे? मेमरी केवल तभी काम करती है जब सरणी बाइट आकार का हो।
मैट

21
@ बेन्सन: आप ऊपर दिए गए कोड को प्लेटफ़ॉर्म पर आकार (int)> sizeof (char) से नहीं बदल सकते। कोशिश करो।
क्रिसव्यू

13

आप पूरी स्टेटिक इनिशियलाइज़र चीज़ को ऊपर बताए अनुसार कर सकते हैं, लेकिन यह एक वास्तविक बुमेरर हो सकता है जब आपका ऐरे साइज़ बदलता है (जब आपका एरे एम्बिगेंस हो जाता है, यदि आप उपयुक्त अतिरिक्त इनिशियलाइज़र नहीं जोड़ते हैं तो आपको कचरा मिलता है)।

मेमसेट आपको काम करने के लिए एक रनटाइम हिट देता है, लेकिन सही किया गया कोई कोड आकार सरणी आकार में परिवर्तन के लिए प्रतिरक्षा नहीं है। मैं इस समाधान का उपयोग लगभग सभी मामलों में करूंगा, जब सरणी कुछ दर्जन तत्वों से बड़ी थी।

यदि यह वास्तव में महत्वपूर्ण था कि सरणी को सांख्यिकीय रूप से घोषित किया गया था, तो मैं मेरे लिए कार्यक्रम लिखने और इसे निर्माण प्रक्रिया का हिस्सा बनाने के लिए एक कार्यक्रम लिखूंगा।


क्या आप memsetसरणी को इनिशियलाइज़ करने के लिए उस उपयोग पर कुछ उदाहरण जोड़ सकते हैं ?
सल्पाजो डी एरियेरेज़

8

यहाँ एक और तरीका है:

static void
unhandled_interrupt(struct trap_frame *frame, int irq, void *arg)
{
    //this code intentionally left blank
}

static struct irqtbl_s vector_tbl[XCHAL_NUM_INTERRUPTS] = {
    [0 ... XCHAL_NUM_INTERRUPTS-1] {unhandled_interrupt, NULL},
};

देख:

सी-एक्सटेंशन

नामित इनिट्स

फिर प्रश्न पूछें: कोई C एक्सटेंशन का उपयोग कब कर सकता है?

ऊपर दिया गया कोड नमूना एक एम्बेडेड सिस्टम में है और दूसरे कंपाइलर से प्रकाश को कभी नहीं देखेगा।


6

'सामान्य' डेटा प्रकारों (जैसे इंटर्न एरे) को इनिशियलाइज़ करने के लिए, आप ब्रैकेट नोटेशन का उपयोग कर सकते हैं, लेकिन यह अंतिम के बाद मानों को शून्य कर देगा, अगर एरे में अभी भी जगह है:

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};

5

यदि सरणी int के आकार के साथ int या कुछ भी हो रहा है या आपके मेम-पैटर्न का आकार एक int (यानी सभी zeroes या 0xA5A5A5A5) में सटीक बार फिट बैठता है, तो सबसे अच्छा तरीका यह है कि आपसेट () का उपयोग करें ।

अन्यथा अनुक्रमणिका को लूप में मेम्ची () कहें।


5

थोड़ा जीभ-में-गाल जवाब; बयान लिखें

array = initial_value

आपकी पसंदीदा सरणी-सक्षम भाषा में (मेरा फोरट्रान है, लेकिन कई अन्य हैं), और इसे अपने सी कोड से लिंक करें। आप शायद इसे एक बाहरी कार्य होने के लिए लपेटना चाहते हैं।


4

दिए गए मान के साथ किसी भी प्रकार के सरणी को आरंभीकृत करने का एक तेज़ तरीका है। यह बड़े सरणियों के साथ बहुत अच्छी तरह से काम करता है। एल्गोरिथम निम्नानुसार है:

  • सरणी के पहले तत्व (सामान्य तरीके से) को इनिशियलाइज़ करें
  • प्रतिलिपि भाग जिसे भाग में सेट किया गया है जिसे सेट नहीं किया गया है, प्रत्येक अगले प्रतिलिपि ऑपरेशन के साथ आकार दोगुना

के लिए 1 000 000तत्वों intसरणी यह 4 बार नियमित रूप से पाश प्रारंभ (i5, 2 कोर, 2.3 GHz, 4GiB स्मृति, 64 बिट्स) की तुलना में तेजी है:

loop runtime 0.004248 [seconds]

memfill() runtime 0.001085 [seconds]


#include <stdio.h>
#include <time.h>
#include <string.h>
#define ARR_SIZE 1000000

void memfill(void *dest, size_t destsize, size_t elemsize) {
   char   *nextdest = (char *) dest + elemsize;
   size_t movesize, donesize = elemsize;

   destsize -= elemsize;
   while (destsize) {
      movesize = (donesize < destsize) ? donesize : destsize;
      memcpy(nextdest, dest, movesize);
      nextdest += movesize; destsize -= movesize; donesize += movesize;
   }
}    
int main() {
    clock_t timeStart;
    double  runTime;
    int     i, a[ARR_SIZE];

    timeStart = clock();
    for (i = 0; i < ARR_SIZE; i++)
        a[i] = 9;    
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("loop runtime %f [seconds]\n",runTime);

    timeStart = clock();
    a[0] = 10;
    memfill(a, sizeof(a), sizeof(a[0]));
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("memfill() runtime %f [seconds]\n",runTime);
    return 0;
}

2
क्षमा करें, लेकिन यह सच नहीं है। हो सकता है कि आप अपने परीक्षणों (डिबग मोड के साथ परीक्षण?) के दौरान संकलन अनुकूलन चालू करना भूल गए। अगर मैं इसका परीक्षण करता हूं, तो लूप मेम्फिल की तुलना में लगभग हमेशा 50% तेज होता है (मेरी मशीन पर कुछ लोड झटके के कारण 'हमेशा')। और मेमसेट (ए, 0, साइज़ोफ़ (ए)) का उपयोग करना; लूपफिल से भी दोगुना तेज है।
RS1980

2
किसी भी बेंचमार्किंग कोड के साथ, आपको बेहद सावधान रहने की जरूरत है। टाइम कोड को 10 बार निष्पादित करने के लिए लूप जोड़ना (और सरणी का आकार 20M तक दोगुना करना) दिखाता है - मेरे लिए, मैकबुक प्रो पर मैकओएस सिएरा 10.12.3 के साथ और जीसीसी 6.3.0 का उपयोग करके - कि पहली बार, लूप लगभग 4600 00s लेता है, जबकि memfill()कोड लगभग 1200 00 लेता है। हालाँकि, बाद के पुनरावृत्तियों पर, लूप में लगभग 900-1000 er लगते हैं जबकि memfill()कोड 1000-1300 er होता है। कैश भरने के लिए पहले पुनरावृति संभवतः समय से प्रभावित होती है। परीक्षणों को उल्टा करें और memfill()पहली बार धीमा हो।
जोनाथन लेफ़लर

2

किसी ने भी आरम्भ क्रम का उल्लेख आरंभीकृत सरणी के तत्वों तक पहुँचने के लिए नहीं किया है। मेरा उदाहरण कोड इसका एक उदाहरण देगा।

#include <iostream>

void PrintArray(int a[3][3])
{
    std::cout << "a11 = " << a[0][0] << "\t\t" << "a12 = " << a[0][1] << "\t\t" << "a13 = " << a[0][2] << std::endl;
    std::cout << "a21 = " << a[1][0] << "\t\t" << "a22 = " << a[1][1] << "\t\t" << "a23 = " << a[1][2] << std::endl;
    std::cout << "a31 = " << a[2][0] << "\t\t" << "a32 = " << a[2][1] << "\t\t" << "a33 = " << a[2][2] << std::endl;
    std::cout << std::endl;
}

int wmain(int argc, wchar_t * argv[])
{
    int a1[3][3] =  {   11,     12,     13,     // The most
                        21,     22,     23,     // basic
                        31,     32,     33  };  // format.

    int a2[][3] =   {   11,     12,     13,     // The first (outer) dimension
                        21,     22,     23,     // may be omitted. The compiler
                        31,     32,     33  };  // will automatically deduce it.

    int a3[3][3] =  {   {11,    12,     13},    // The elements of each
                        {21,    22,     23},    // second (inner) dimension
                        {31,    32,     33} };  // can be grouped together.

    int a4[][3] =   {   {11,    12,     13},    // Again, the first dimension
                        {21,    22,     23},    // can be omitted when the 
                        {31,    32,     33} };  // inner elements are grouped.

    PrintArray(a1);
    PrintArray(a2);
    PrintArray(a3);
    PrintArray(a4);

    // This part shows in which order the elements are stored in the memory.
    int * b = (int *) a1;   // The output is the same for the all four arrays.
    for (int i=0; i<9; i++)
    {
        std::cout << b[i] << '\t';
    }

    return 0;
}

आउटपुट है:

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

11      12      13      21      22      23      31      32      33

4
<iostream>मान्य नहीं है Cके रूप में std::cout, std::cin, आदि का हिस्सा है std::namespaceऔर Cसमर्थन नहीं करता है namespaces। उपयोग करने का प्रयास <stdio.h>के लिए printf(...)बजाय।
फ्रांसिस कुगलर

2

सभी बकवास के माध्यम से काटना, संक्षिप्त उत्तर यह है कि यदि आप संकलन समय पर अनुकूलन चालू करते हैं तो आप इससे बेहतर नहीं करेंगे:

int i,value=5,array[1000]; 
for(i=0;i<1000;i++) array[i]=value; 

जोड़ा गया बोनस: कोड वास्तव में सुपाठ्य है :)


7
सवाल विशेष रूप से आरंभीकरण के लिए पूछा गया। यह स्पष्ट रूप से आरंभीकरण नहीं है, लेकिन आरंभीकरण के बाद किया गया असाइनमेंट है । यह तुरंत किया जा सकता है, लेकिन यह अभी भी आरंभीकरण नहीं है।
एंडी

कई बार कहे जाने वाले फ़ंक्शन के अंदर एक बड़ी स्थिर लुकअप तालिका के लिए पूरी तरह से उपयोगी नहीं है।
मार्टिन बोनर मोनिका

... मूल प्रश्न का हिस्सा होने वाले कार्यों के अंदर स्थिर लुकअप तालिकाओं को याद न करें - इसे सरल रखें। उस ने कहा, @Community ने शायद इसे बंद कर दिया है।
JWDN

1
  1. यदि आपका सरणी स्थिर घोषित किया गया है या वैश्विक है, तो सरणी के सभी तत्वों में पहले से ही डिफ़ॉल्ट मान 0 है।
  2. कुछ संकलक सरणी डिबग मोड में 0 से डिफ़ॉल्ट सेट करते हैं।
  3. डिफ़ॉल्ट को 0 पर सेट करना आसान है: int array [10] = {0};
  4. हालाँकि, अन्य मानों के लिए, आपने मेमसेट () या लूप का उपयोग किया है;

उदाहरण: int array [10]; मेमसेट (सरणी, -1, 10 * आकार (इंट));


0
#include<stdio.h>
int main(){
int i,a[50];
for (i=0;i<50;i++){
    a[i]=5;// set value 5 to all the array index
}
for (i=0;i<50;i++)
printf("%d\n",a[i]);
   return 0;
}

यह ओ / पी 5 5 5 5 5 5 5 ...... पूरे सरणी के आकार तक देगा


0

मुझे पता है कि उपयोगकर्ता Tarskiने इस प्रश्न का एक समान तरीके से उत्तर दिया था, लेकिन मैंने कुछ और विवरण जोड़े। मेरी सी के लिए कुछ माफ़ कर दो क्योंकि मैं उस पर थोड़ा कठोर हूँ क्योंकि मैं C ++ का उपयोग करना चाहता हूँ, लेकिन यहाँ यह जाता है।


यदि आप समय से पहले सरणी का आकार जानते हैं ...

#include <stdio.h>

typedef const unsigned int cUINT;
typedef unsigned int UINT;

cUINT size = 10;
cUINT initVal = 5;

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal );
void printArray( UINT* myArray ); 

int main() {        
    UINT myArray[size]; 
    /* Not initialized during declaration but can be
    initialized using a function for the appropriate TYPE*/
    arrayInitializer( myArray, size, initVal );

    printArray( myArray );

    return 0;
}

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal ) {
    for ( UINT n = 0; n < size; n++ ) {
        myArray[n] = initVal;
    }
}

void printArray( UINT* myArray ) {
    printf( "myArray = { " );
    for ( UINT n = 0; n < size; n++ ) {
        printf( "%u", myArray[n] );

        if ( n < size-1 )
            printf( ", " );
    }
    printf( " }\n" );
}

ऊपर कुछ गुहाएं हैं; एक यह है कि UINT myArray[size];घोषणा पर सीधे आरंभीकृत नहीं किया जाता है, हालांकि बहुत ही अगले कोड ब्लॉक या फ़ंक्शन कॉल सरणी के प्रत्येक तत्व को उसी मूल्य पर आरंभीकृत करता है जो आप चाहते हैं। अन्य चेतावनी है, आपको initializing functionप्रत्येक के लिए लिखना होगा जिसका typeआप समर्थन करेंगे और आपको printArray()उन प्रकारों का समर्थन करने के लिए फ़ंक्शन को भी संशोधित करना होगा ।


आप इस कोड को यहां पाए गए ऑनलाइन कंप्लेंट के साथ आज़मा सकते हैं


0

विलंबित आरंभीकरण के लिए (यानी वर्ग सदस्य निर्माण आरंभीकरण) पर विचार करें:

int a[4];

unsigned int size = sizeof(a) / sizeof(a[0]);
for (unsigned int i = 0; i < size; i++)
  a[i] = 0;

0

मुझे पता है कि मूल प्रश्न में स्पष्ट रूप से C ++ का उल्लेख नहीं है, लेकिन यदि आप (मेरे जैसा) C ++ सरणियों के समाधान की तलाश में यहां आए हैं, तो यहां एक साफ-सुथरी चाल है:

यदि आपका कंपाइलर फोल्ड एक्सप्रेशन का समर्थन करता है , तो आप टेम्प्लेट मैजिक का उपयोग कर सकते हैं और अपने std::index_sequenceइच्छित मूल्य के साथ एक इनिशलाइज़र सूची तैयार कर सकते हैं। और आप भी constexprइसे महसूस कर सकते हैं और एक बॉस की तरह महसूस कर सकते हैं :

#include <array>

/// [3]
/// This functions's only purpose is to ignore the index given as the second
/// template argument and to always produce the value passed in.
template<class T, size_t /*ignored*/>
constexpr T identity_func(const T& value) {
    return value;
}

/// [2]
/// At this point, we have a list of indices that we can unfold
/// into an initializer list using the `identity_func` above.
template<class T, size_t... Indices>
constexpr std::array<T, sizeof...(Indices)>
make_array_of_impl(const T& value, std::index_sequence<Indices...>) {
    return {identity_func<T, Indices>(value)...};
}

/// [1]
/// This is the user-facing function.
/// The template arguments are swapped compared to the order used
/// for std::array, this way we can let the compiler infer the type
/// from the given value but still define it explicitly if we want to.
template<size_t Size, class T>
constexpr std::array<T, Size> 
make_array_of(const T& value) {
    using Indices = std::make_index_sequence<Size>;
    return make_array_of_impl(value, Indices{});
}

// std::array<int, 4>{42, 42, 42, 42}
constexpr auto test_array = make_array_of<4/*, int*/>(42);
static_assert(test_array[0] == 42);
static_assert(test_array[1] == 42);
static_assert(test_array[2] == 42);
static_assert(test_array[3] == 42);
// static_assert(test_array[4] == 42); out of bounds

आप काम पर कोड (वैंडबॉक्स में) पर एक नज़र डाल सकते हैं


-1

मुझे प्रश्न में कोई आवश्यकता नहीं दिखती है, इसलिए समाधान सामान्य होना चाहिए: अनिर्दिष्ट संभव संरचना के प्रारंभिक तत्वों के साथ अनिर्दिष्ट संभवतः संरचना तत्वों से निर्मित बहुआयामी सरणी का आरोहण:

#include <string.h> 

void array_init( void *start, size_t element_size, size_t elements, void *initval ){
  memcpy(        start,              initval, element_size              );
  memcpy( (char*)start+element_size, start,   element_size*(elements-1) );
}

// testing
#include <stdio.h> 

struct s {
  int a;
  char b;
} array[2][3], init;

int main(){
  init = (struct s){.a = 3, .b = 'x'};
  array_init( array, sizeof(array[0][0]), 2*3, &init );

  for( int i=0; i<2; i++ )
    for( int j=0; j<3; j++ )
      printf("array[%i][%i].a = %i .b = '%c'\n",i,j,array[i][j].a,array[i][j].b);
}

परिणाम:

array[0][0].a = 3 .b = 'x'
array[0][1].a = 3 .b = 'x'
array[0][2].a = 3 .b = 'x'
array[1][0].a = 3 .b = 'x'
array[1][1].a = 3 .b = 'x'
array[1][2].a = 3 .b = 'x'

EDIT: को start+element_sizeबदल दिया गया(char*)start+element_size


1
मुझे इस बात का संदेह है कि यह समाधान है या नहीं। मुझे यकीन नहीं है कि क्या sizeof(void)वैध भी है।
क्रिस लुट्ट्ज

3
यह काम नहीं करता है। केवल पहले दो को आरंभीकृत किया जाता है, शेष सभी को असंवैधानिक किया जाता है। मैं मैक ओएस एक्स 10.4 पर जीसीसी 4.0 का उपयोग कर रहा हूं।
ड्रीमलैक्स

यह अपरिभाषित व्यवहार को आमंत्रित करता है क्योंकि दूसरे memcpy()स्थान पर स्रोत डेटा गंतव्य स्थान के साथ ओवरलैप करता है। के एक भोले-भाले कार्यान्वयन के साथ memcpy(), यह काम कर सकता है लेकिन यह आवश्यक नहीं है कि सिस्टम इसे काम करता है।
जोनाथन लेफ़लर

-1

दिन में वापस (और मैं यह नहीं कह रहा हूं कि यह एक अच्छा विचार है), हम पहला तत्व निर्धारित करेंगे और फिर:

memcpy (&element [1], &element [0], sizeof (element)-sizeof (element [0]);

यह भी सुनिश्चित नहीं है कि यह किसी भी अधिक काम करेगा (जो मेम्ची के कार्यान्वयन पर निर्भर करेगा) लेकिन यह प्रारंभिक तत्व को बार-बार कॉपी करके काम करता है - यहां तक ​​कि संरचनाओं के सरणियों के लिए भी काम करता है।


वह मज़बूती से काम नहीं करेगा। IMHO, मानक को ऐसे कार्य प्रदान करने चाहिए जो memcpyओवरलैप के मामले में निर्दिष्ट बॉटम-अप या टॉप-डाउन कॉपी ऑर्डर जैसे थे , लेकिन ऐसा नहीं है।
सुपरकैट

जैसा कि मैंने कहा, यह कुछ ऐसा था जो हमने किया था लेकिन मज़बूती से काम नहीं करेगा लेकिन, इसके बाद, हम अनिर्दिष्ट सुविधाओं से बचने की तुलना में दक्षता पर अधिक ध्यान केंद्रित कर रहे थे। यद्यपि यह स्मृति को आगे की ओर कॉपी करने के लिए अधिक कुशल है, यह कहने के लिए विनिर्देश में कुछ भी नहीं है कि यह इसे पीछे से कॉपी नहीं कर सकता है, यादृच्छिक क्रम में या इसे कई थ्रेड्स में विभाजित कर सकता है। मेम्मोव () क्लैश के बिना कॉपी करने की क्षमता प्रदान करता है।
माइक

यह एक अन्य उत्तर में कोड के बराबर है - और त्रुटिपूर्ण है। उपयोग करने से memmove()काम नहीं बनता।
जोनाथन लेफ्लर

-2

यदि आप समानांतर में मतलब है, मुझे लगता है कि अल्पविराम ऑपरेटर जब एक अभिव्यक्ति के साथ संयोजन में उपयोग किया जाता है वह कर सकता है:

a[1]=1, a[2]=2, ..., a[indexSize]; 

या यदि आप एक निर्माण में मतलब है, आप कर सकते हैं कि एक लूप में:

for(int index = 0, value = 10; index < sizeof(array)/sizeof(array[0]); index++, value--)
  array[index] = index;

// नोट तर्क सूची में अल्पविराम ऑपरेटर ऊपर वर्णित समानांतर ऑपरेटर नहीं है;

आप एक सरणी घोषणा को आरंभ कर सकते हैं:

array[] = {1, 2, 3, 4, 5};

आप किसी वस्तु को भंडारण के एक निश्चित क्षेत्र को आवंटित करने के लिए मॉलॉक / कॉलोक / एसब्रक / अलोका / आदि को कॉल कर सकते हैं:

int *array = malloc(sizeof(int)*numberOfListElements/Indexes);

और सदस्यों को इसके द्वारा एक्सेस करें:

*(array + index)

आदि।


अल्पविराम ऑपरेटर मुख्य रूप से बाएं से दाएं मूल्यांकन की गारंटी देता है। यदि अभिव्यक्तियों में कोई दुष्प्रभाव नहीं हैं, तो संचालन को समानांतर करना संभव हो सकता है, लेकिन ऐसा करने के लिए एक संकलक के लिए यह असामान्य होगा।
जोनाथन लेफ्लर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.