5

I have structure

struct ABC {
  int a; 
  int b;
}

and array of it as

struct ABC xyz[100];

I want to initialize it a = 10 and b = 20; for all array element.

Which is better way ?

abelenky
  • 63,815
  • 23
  • 109
  • 159
Hemant
  • 63
  • 1
  • 5

5 Answers5

15

While there is no particularly elegant way to initialize a big array like this in C, it is possible. You do not have to do it in runtime, as some answers falsely claim. And you don't want to do it in runtime, suppose the array is const?

The way I do it is by defining a number of macros:

struct ABC {
  int a; 
  int b;
};

#define ABC_INIT_100 ABC_INIT_50 ABC_INIT_50
#define ABC_INIT_50  ABC_INIT_10 ABC_INIT_10 ABC_INIT_10 ABC_INIT_10 ABC_INIT_10
#define ABC_INIT_10  ABC_INIT_2 ABC_INIT_2 ABC_INIT_2 ABC_INIT_2 ABC_INIT_2
#define ABC_INIT_2   ABC_INIT_1 ABC_INIT_1
#define ABC_INIT_1   {10, 20},

int main()
{
  struct ABC xyz[100] =
  {
    ABC_INIT_100
  };
}

Note that macros like these can be combined in any way, to make any number of initializations. For example:

#define ABC_INIT_152 ABC_INIT_100 ABC_INIT_50 ABC_INIT_2
Lundin
  • 195,001
  • 40
  • 254
  • 396
9

With GCC you can use its extended syntax and do:

struct ABC xyz[100] = { [0 ... 99].a = 10, [0 ... 99].b = 20 };

For a portable solution I'd probably initialize one instance, and use a loop to copy that instance to the rest:

struct ABC xyz[100] = { [0].a = 10, [0].b = 20 };

for(size_t i = 1; i < sizeof xyz / sizeof *xyz; ++i)
  xyz[i] = xyz[0];

This is somewhat cleaner to me than having the actual values in the loop. It can be said to express the desired outcome at a slightly higher level.

The above syntax ([0].a and [0].b) is not an extension, it's typical C99.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • The portable version is strictly speaking not _initialization_, but runtime assignment. How would you do that if xyz was `const`? – Lundin Feb 03 '14 at 14:44
  • @Lundin True of course, like all the other looping suggestions. I don't think it can be done with `const`, without a honking big explicit init, or macros (like your answer). – unwind Feb 03 '14 at 14:53
  • @lundin on the flip side, how would you use macros if the array in question were allocated on the stack inside a function, and the array size were a function argument? You can make any answer not apply by adding extra requirements, but there's no indication the OP was looking for a const array; given the nature of the question it's more likely he was simply looking for a way to avoid a lot of typing (which both your solution and the loop-based solutions provide.) While it's not *strictly* initialization, it *is* what most people mean by the term when speaking casually. – JVMATL Feb 03 '14 at 18:27
  • Also, fwiw, I like that this version better captures the intent of setting all elements to the same default value, and it doesn't break if the size of the array changes (or is dynamic.) – JVMATL Feb 03 '14 at 18:29
  • @JVMATL Local scope VLAs are allocated in runtime so then there is no benefit of using initialization rather than assignment. The difference between initialization and assignment only matters when speaking of the default values of variables, which can be determined at compile-time. – Lundin Feb 04 '14 at 07:28
  • @Lundin replying almost 4 years late, yes, but, an array of 100 constant structs initialized with the *exact same value* - that's hardly useful... – Antti Haapala -- Слава Україні Dec 17 '17 at 21:05
  • @AnttiHaapala Welcome to embedded systems. We have flash memory since 20+ years back, and before that EEPROM. To default initialize all NVM variables is very useful. Also, if you see my answer to this post, you can use macros to create sequences, or mix sequences with individual initialization. – Lundin Dec 18 '17 at 07:24
  • @Lundin I am pretty sure you didn't have arrays of 100 `const struct` each set to the exact same value in your EEPROM... – Antti Haapala -- Слава Україні Dec 18 '17 at 07:27
  • @AnttiHaapala I can think of plenty of programs I have written where I do. For example, one such program has a 64kb data flash area where settings are stored, full with various large arrays of structs, all default-initialized to various values. – Lundin Dec 18 '17 at 07:31
  • @Lundin Sure (I'm in embedded too), but were they really `const`? There is some redundancy to having more than one copy of read-only data, that could/should be factored out, perhaps. – unwind Dec 18 '17 at 08:24
  • @unwind Typically you have to const-qualify just to tell the linker to allocate the variables in flash. But they aren't really read-only, since it is flash/eeprom. So you access them through volatile pointers. – Lundin Dec 18 '17 at 08:41
1
for(unsigned int i=0; i<100; i++)
{
    xyz[i].a = 10;
    xyz[i].b = 20;
}
n0p
  • 3,399
  • 2
  • 29
  • 50
  • This is strictly speaking not _initialization_, but runtime assignment. How would you do that if xyz was `const`? – Lundin Feb 03 '14 at 14:45
  • @Lundin Why would you need more than 1 copy of the same values, then? – Brave Sir Robin Feb 03 '14 at 14:46
  • @rmartinjak That would entirely depend on the nature of the application. Suppose there exist one scenario where all values are individual, and another where they are all the same. Then you use the const array as input to a function. – Lundin Feb 03 '14 at 14:48
0

There's no explicit language support for initializing all the elements in an array of substructures to specific, non-zero default values, in the the way there is for initializing all elements to zero; you either have to initialize each element explicitly in the source at compile-time or you have to write a for() loop and initialize each element at startup.

As user @lundin points out in another answer, you can use preprocessor macros to reduce the typing involved in explicitly initializing those values, but as far as the C compiler is concerned, you're still initializing each element explicitly.

JVMATL
  • 2,064
  • 15
  • 25
  • There is language syntax for this in standard C. You do not need a loop in runtime. – Lundin Feb 03 '14 at 14:46
  • Updated answer to clarify what there is, and is not syntax for, since the first version was obviously misleading. @Lundin the preprocessor-based solution is clever, but I think it's a bit of a stretch to claim that there is "language syntax for [something] in standard C" just because you can accomplish something with preprocessor tricks. The preprocessor behavior may be specified in the standard, but it's not 'C' per se. – JVMATL Feb 03 '14 at 18:07
  • If you can do it with some mechanism that's accepted by a fully confirming C compiler, then there is C syntax for it. Regarding whether the preprocessor is "C syntax" or not, see "language syntax summary" in annex A of the standard :) – Lundin Feb 05 '14 at 12:56
0

I'm not a c expert (so when you come for my blood...)

This complies and works fine!

typedef struct
{
    double var1;
    double var2;
    double var3;
    double var4;
}VectorData;

#define MAX_INDEX 100

VectorData Data[] = {[0 ... MAX_INDEX] = {0.0, 0.0, 0.0, 0.0}};

This allows you to imply the array size from MAX_INDEX. In this case you have an array with 101 elements.