1

I believe it's a simple question: Is there a way to initialize an array with values that are nonzero without using loops?

One way I know is to use Range Initialization to initialize the array with the values I want. For example:

int main()
{
   /* Using Designated Range Initialization*/
   int my_array[10] = {[0 ... 3] = 5, [4 ... 7] = 15, [8 ... 9] = 30};
   /* Using Explicit initialization for each element */
   int other_array[10] = {5, 5, 5, 5, 15, 15, 15, 15, 30, 30};

   return 0;
}

However, this method is just an extension of the GCC compiler, and not part of ISO C. So given this possible non-portability between systems, is there a way to do an array initialization in a similar way? Of course, without using loops.

Also, the method I'm looking for is just beyond the explicit initialization of each element of the array.

  • 1
    Does just listing out all the values suffice: `int my_array[10] = {5,5,5,5,15,15,15,15,15,30,30};`? – kaylum Aug 13 '21 at 22:27
  • Thanks for the answer! But this can be a tedious task if it is a very large array. – onlyMinimum Aug 13 '21 at 22:31
  • True. But you haven't stated what your exact requirements are other than "an alternative". So if you have other specific requirements then suggest updating your question to say so. – kaylum Aug 13 '21 at 22:32
  • Indeed! I will update the question trying to be more restrictive. – onlyMinimum Aug 13 '21 at 22:37

3 Answers3

4

The only portable alternative is to list them all explicitly.

int my_array[] = {
    5, 5, 5, 5,
    15, 15, 15, 15,
    30, 30
};

This can of course be cumbersome if the array is large. In that case, you can use a simple script in bash or awk to create the declaration. It can write it to a header file that you merge in with #include.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I was not aware of using awk or bash scripts for this purpose. Thank you in advance for the answer. – onlyMinimum Aug 13 '21 at 22:33
  • @onlyMinimum The idea of using of `awk/bash` to generate a `.h` is a good one. I would have suggested it (also, using `perl/python`). You could even write the generator in C, although a scripting/macro language is usually more convenient. This would have been called macro programming (in the past for full fledged macro processors (e.g. `m4`--another choice)), but the modern term is _metaprogramming_ – Craig Estey Aug 13 '21 at 23:04
  • @CraigEstey, haven't reached that level of programming knowledge yet, but that's what I'm trying to achieve. – onlyMinimum Aug 13 '21 at 23:11
4

Code needs to explicitly initialize the non-zero array elements.

Could use macro magic if there is a pattern:

#define ONE(x) (x), (x)+1, (x)+2, (x)+3, (x)+4, (x)+5, (x)+6, (x)+7, (x)+8, (x)+9
#define TEN(x) ONE(x),ONE((x)+10),ONE((x)+20),ONE((x)+30),ONE((x)+40), \
    ONE((x)+50),ONE((x)+60),ONE((x)+70),ONE((x)+80),ONE((x)+90)

int main() {
  int count[100] = { TEN(1) };
  printf("%d %d\n", count[0], count[99] );
}

Output

1 100

Example for OP

#define X2(x) (x), (x)
// Note the nested macro
#define X4(x) X2(x), X2(x)
#define X8(x) X4(x), X4(x)
#define X10(x) X8(x), X2(x)
#define X16(x) X8(x), X8(x)
// ....


int main()
{
   int my_array[10] = { X4(5), X4(15), X2(30)};
   printf("%d %d\n", my_array[0], my_array[9] );
   return 0;
}

Output

5 30
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
3

From comments under Barmar's answer ...

@CraigEstey, haven't reached that level of programming knowledge yet, but that's what I'm trying to achieve. – onlyMinimum

I guessed as much--that's why I suggested writing the program in C.

Not to worry ... Metaprogramming is a fancy/sexy term, it can be really quite simple to implement/use.


To get you started or give you the idea, here is a generator sample program (e.g. gen.c):

#include <stdio.h>

void
dorange(int lo,int hi,int val)
{

    for (;  lo <= hi;  ++lo)
        printf("%d, ",val);
}

int
main(void)
{
    printf("int myarray[10] = {\n");

    dorange(0,3,5);
    dorange(4,7,15);
    dorange(8,9,30);

    printf("\n");
    printf("};\n");

    return 0;
}

Here is the output of that program:

int myarray[10] = {
5, 5, 5, 5, 15, 15, 15, 15, 30, 30,
};

So, if you were going to put the output into myarray.h using a Makefile:

all: myprogram

# create the target program [after creating the generated file]
myprogram: myprogram.c myarray.h
    cc -o myprogram myprogram.c

# create the generated file
myarray.h: gen
    ./gen > myarray.h

# create the generator program
gen: gen.c
    cc -o gen gen.c

# clean up files ...
clean:
    rm -f gen myarray.h myprogram

Here is myprogram.c:

#include <stdio.h>
#include "myarray.h"

int
main(void)
{

    for (int idx = 0;  idx < sizeof(myarray) / sizeof(myarray[0]);  ++idx)
        printf(" %d",myarray[idx]);

    printf("\n");

    return 0;
}

Here is the output of myprogram:

 5 5 5 5 15 15 15 15 30 30
Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • I liked the implementation! And even more using the shell redirection operator, which I have a little more experience with. – onlyMinimum Aug 14 '21 at 00:19