1157

I have a large array in C (not C++ if that makes a difference). I want to initialize all members of the same value.

I could swear I once knew a simple way to do this. I could use memset() in my case, but isn't there a way to do this that is built right into the C syntax?

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
Matt
  • 84,419
  • 25
  • 57
  • 67
  • 25
    None of the answers so far mentions the designated initializer notation that is feasible with C99 and above. For example: `enum { HYDROGEN = 1, HELIUM = 2, CARBON = 6, NEON = 10, … };` and `struct element { char name[15]; char symbol[3]; } elements[] = { [NEON] = { "Neon", "Ne" }, [HELIUM] = { "Helium", "He" }, [HYDROGEN] = { "Hydrogen", "H" }, [CARBON] = { "Carbon", "C" }, … };`. If you remove the ellipsis `…`, those fragments do compile under C99 or C11. – Jonathan Leffler May 11 '14 at 14:40
  • Actually abelenky's answer is using designated initializer, but isn't fully formed initialising code – Rob11311 Jun 05 '14 at 14:17
  • memset() can help, but depends of the value. – Nick Feb 13 '15 at 12:23
  • 2
    `memset()` specific discussion: http://stackoverflow.com/questions/7202411/memsetarr-1-sizeofarr-sizeofint-not-clearing-an-integer-array I think it only works for 0. – Ciro Santilli OurBigBook.com May 10 '16 at 18:55
  • @Nick `memset()` only works for `0`, `UINT_MAX`, and arrays whose elements are one `char` in size. – user16217248 Sep 26 '22 at 20:10
  • 1
    @user16217248 also work for "cyclic" numbers like 0x1212, 0x0303 etc. ;) but yes, most often you need zeros – Nick Sep 28 '22 at 08:12

26 Answers26

1478

Unless that value is 0 (in which case you can omit some part of the initializer and the corresponding elements will be initialized to 0), there's no easy way.

Don't overlook the obvious solution, though:

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

Elements with missing values will be initialized to 0:

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

So this will initialize all elements to 0:

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

In C++, an empty initialization list will also initialize every element to 0. This is not allowed with C until C23:

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

Remember that objects with static storage duration will initialize to 0 if no initializer is specified:

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

And that "0" doesn't necessarily mean "all-bits-zero", so using the above is better and more portable than memset(). (Floating point values will be initialized to +0, pointers to null value, etc.)

Benjamin Buch
  • 4,752
  • 7
  • 28
  • 51
aib
  • 45,516
  • 10
  • 73
  • 79
  • 63
    Looking at section 6.7.8 Initialization of the C99 standard, it does not appear that an empty initializer list is allowed. – Jonathan Leffler Oct 14 '08 at 13:59
  • 11
    C99 has a lot of nice features for structure and array initialization; the one feature it does not have (but Fortran IV, 1966, had) is a way to repeat a particular initializer for an array. – Jonathan Leffler Oct 14 '08 at 14:00
  • What about float * = new float[10]; will this initialize to zero as well? – Miek Aug 30 '12 at 17:42
  • That will call the default constructor, which, once you get past the argument of whether there actually *is* a constructor for primitive types, should do zero-initialization as well. – aib Aug 30 '12 at 18:54
  • Though of course you should be asking whether `std::vector(10)` does zero-initialization, instead. – aib Aug 30 '12 at 18:59
  • @aib can we use the same technique to initialize a 2 D array allocated on heap using malloc(sizeof(int [ROW][COL])). Thanks – abhi Mar 15 '13 at 13:40
  • 2
    I don't think I've seen this yet: `int myArray[] = {[3] = 123, [7] = 23};` Gives you `{0, 0, 0, 123, 0, 0, 0, 23}` – akofink Apr 24 '13 at 13:49
  • 2
    @akofink: Check out qrdl's answer just below. It's a GCC extension. – aib Apr 24 '13 at 17:16
  • Can somebody prove this statement using the C Standard? Is it already included in C90? "Unless that value is 0 (in which case you can omit some part of the initializer and the corresponding elements will be initialized to 0)" – Niklas Peter Nov 21 '14 at 09:07
  • In other news, apparently you cannot use a variable as the size if you want to initialize it on the same line. – jfa Mar 08 '15 at 02:44
  • 1
    @neo That is wrong, and the answer is correct. See http://www.cplusplus.com/doc/tutorial/arrays/ - "If declared with less, the remaining elements are set to their default values (which for fundamental types, means they are filled with zeroes)" – Max Barraclough Dec 22 '19 at 13:07
  • @MaxBarraclough: I think `{0}` in an initialization expression will yield the default value for every type of object except maybe unions--false for boolean, integer zero for all integer types, floating-point zero for all floating-point types, null for all pointer types, and structs whose values are all set to the default values of their respective types. – supercat Jan 30 '20 at 16:06
  • I read through the C99, and C11 standards and I can't find any reference to the array initialization by a single value in braces as mentioned above. int arraything[6] = {8}; Could someone point out where that comes from? – Fratink May 06 '20 at 14:54
  • 2
    @Fratink See §6.7.8.21: "If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration." – aib Jul 28 '20 at 16:43
472

If your compiler is GCC you can use following "GNU extension" syntax:

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

Check out detailed description: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
qrdl
  • 34,062
  • 14
  • 56
  • 86
  • @qrdl I tried initializing a 2D array dynamically allocated on heap using malloc(sizeof(int [row][col])) and got compile time error on line where is used this line : arr[row][col] = {[0 ... row -1] [0 ... col-1] = -1}; The error i got was "expected expression before '{' token" Any idea on this? Thanks – abhi Mar 15 '13 at 13:43
  • 2
    @abhi What you are trying to do isn't an initialisation but assignment, this syntax cannot be used in such situation, you will be better off using `memset()` – qrdl Mar 16 '13 at 12:15
  • @qrdl thanks for the response.. so basically for dynamic allocation i can't use this technique. correct? – abhi Mar 16 '13 at 12:24
  • 23
    And that syntax causes a huge increase in the file size of compiled binaries. For N = 65536 (instead of 1024), my binary jumps from 15 KB to 270 KB in size!! – Cetin Sert Mar 28 '13 at 15:15
  • 77
    @CetinSert Compiler has to add 65536 `int`s into static data, which is 256 K - exactly the size increase you've observed. – qrdl Mar 29 '13 at 09:53
  • @qrdl why don't you mention it in your answer? – Cetin Sert Mar 29 '13 at 11:14
  • 21
    @CetinSert Why should I? It is a standard compiler behaviour, not specific for designated initialisers. If you statically initialise 65536 `int`s, like `int foo1 = 1, foo2 = 1, ..., foo65536 =1;` you will get the same size increase. – qrdl Mar 29 '13 at 20:48
  • 36
    better yet: "int array[] = {[0 ... 1023] = 5}", the size of array will automatically be set to 1024, easier and safer to modify. – Francois Apr 11 '13 at 09:19
  • 5
    @Francois or for a 2d array, `bool array[][COLS] = { [0...ROWS-1][0...COLS-1] = true}`, though I'm not certain that's more readable than the full form. –  Apr 13 '13 at 06:59
  • 2
    I thought when you say `gcc` it also applies in `g++`. – mr5 Dec 13 '13 at 04:12
  • Why should the ,65536 int s be added? Aren't you specifying its size to be 1024? – AlphaGoku Feb 18 '19 at 05:38
  • 2
    @AkshayImmanuelD Please read the discussion with Cetin Sert from the beginning – qrdl Feb 18 '19 at 07:39
  • Is there any way to do something like this for structs? If so, please answer here: https://stackoverflow.com/questions/61240589/how-to-initialize-a-struct-to-0-in-c. – Gabriel Staples Apr 30 '20 at 18:47
  • @qrdl Could this method be used by g++? – John Jan 17 '21 at 05:40
200

For statically initializing a large array with the same value, without multiple copy-paste, you can use macros:

#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 };

If you need to change the value, you have to do the replacement at only one place.

Edit: possible useful extensions

(courtesy of Jonathan Leffler)

You can easily generalize this with:

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

A variant can be created using:

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

that works with structures or compound arrays.

#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) };

macro names are negotiable.

Community
  • 1
  • 1
mouviciel
  • 66,855
  • 13
  • 106
  • 140
  • 14
    I would only consider this in extreme cases, surely a memset is the more elegant way to express it. – u0b34a0f6ae Oct 14 '09 at 10:41
  • Of course memset() is the way to go. I understood that OP was looking for an alternative. – mouviciel Oct 14 '09 at 11:31
  • 52
    If the data must be ROM-able, memset can not be used. – Prof. Falken Jul 05 '10 at 09:24
  • 11
    Preprocessor will actually generate the code from #defines. With larger array dimensions the executable size will grow. But definitely + for the idea ;) – Leonid Oct 03 '10 at 12:31
  • 3
    memset initializes with a char. It can't be used to init an int array to a value like 42.. The value 0 can be used to init to zero. the value -1 can be used to init the array to -1. – EvilTeach May 08 '11 at 02:45
  • @AmigableClarkKant, what did you mean by "ROM-able"? – Alcott Feb 08 '12 at 01:44
  • 9
    @Alcott, on old computers and still on many embedded systems, the code is eventually placed in an [EPROM](http://en.wikipedia.org/wiki/EPROM "EPROM explanation on Wikipedia") or [ROM](http://en.wikipedia.org/wiki/Read-only_memory "ROM explanation on Wikipedia"). ROM-able has also come to mean, in embedded systems, "code put in flash", because it has about the same implications, namely that the memory can not be written runtime. I.e. memset or any other instruction to update or change memory can not be used. Constants, though, can be expressed and flashed or ROM-ed before the program starts. – Prof. Falken Feb 08 '12 at 08:49
  • (Unless the flash is used as a regular filesystem in say, Linux or Windows, in which case the flash is used in the same way a hard drive would.) @Alcott. – Prof. Falken Feb 08 '12 at 08:55
  • 4
    @u0b34a0f6ae: Keep in mind that you can use this method also if `VAL_1X` isn't a single integer but a list. Like Amigable states, this is also the way to go for embedded systems where you want to define the init values of a EEPROM or Flash memory. In both cases you can't use `memset()`. – Martin Scharrer Feb 05 '13 at 09:01
  • @mouviciel - question: Is the array index included for a reason in your example? i.e. in my ANSI C compiler `int myArray[] = { VAL_32X, VAL_16X, VAL_4X, VAL_1X };` works just fine. I am just not sure if there is a subtle disadvantage for not using an explicit index value. +1 for your answer. – ryyker Sep 12 '13 at 18:28
  • 1
    "VAL_64X is... defined somewhere... 42. Wait? What is this supposed to do?" If we ever work together, please just use a few extra lines of code, and dumb them down enough so that someone like me can understand :) – original_username Apr 19 '14 at 13:51
  • 1
    FYI the `VAL_N()` macros can be used multiple times with different values. Ex: `int A[]={ VAL_4(0), VAL_2(1), VAL_4(2) };` expands to `int A[]={ 0,0,0,0, 1,1, 2,2,2,2 };` Just realized this. – Matthew K. Jun 11 '22 at 01:37
  • FYI here's how to pass a list of values so e.g. `int A[]={VAL_4(0,1)};` expands to `int A[]={0,1,0,1,0,1,0,1};`. You need to change the macros to be able to pass them commas. Add `#define SA(...) __VA_ARGS__` and replace every use of `VAL_N(X)` with `VAL_N(SA(X))` Ex: replace `#define VAL_2(X) VAL_1(X),VAL_1(X)` with `#define VAL_2(X) VAL_1(SA(X)),VAL_1(SA(X))` Then use it like this: option 1: `int A[]={VAL_4(SA(0,1))};` or option 2: add `#define COMMA ,` and then `int A[]={VAL_4(0 COMMA 1)};` You can mix them too: `{VAL_4(SA(0,1)),VAL_8(3)}` becomes `{0,1,0,1,0,1,0,1,3,3,3,3,3,3,3,3}`. – Matthew K. Jun 11 '22 at 02:09
66

If you want to ensure that every member of the array is explicitly initialized, just omit the dimension from the declaration:

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

The compiler will deduce the dimension from the initializer list. Unfortunately, for multidimensional arrays only the outermost dimension may be omitted:

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

is OK, but

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

is not.

Frank Szczerba
  • 5,000
  • 3
  • 31
  • 31
  • is this correct ? `int myPoints[10][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };` – Praveen Gowda I V Apr 20 '12 at 12:51
  • 12
    No. You are omitting the innermost dimension, which is not allowed. This will give a compiler error. – Frank Szczerba Apr 20 '12 at 16:22
  • 4
    Both initializers and length inference were introduced in C99. – Palec Jan 05 '14 at 20:55
  • 3
    @Palec: No — length inference has been in C since the days of pre-standard C (since K&R 1st Edition was published, and probably a while before that). Designated initializers were new in C99, but this isn't using designated initializers. – Jonathan Leffler Feb 14 '17 at 22:25
60

I saw some code that used this syntax:

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

Where it becomes particularly useful is if you're making an array that uses enums as the index:

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

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

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

This keeps things in order, even if you happen to write some of the enum-values out of order.

More about this technique can be found here and here.

abelenky
  • 63,815
  • 23
  • 109
  • 159
  • 9
    This is C99 initializer syntax, already covered by some of the other answers. You could usefully make the declaration into `char const *array[] = { ... };` or even `char const * const array[] = { ... };`, couldn't you? – Jonathan Leffler Apr 29 '12 at 06:29
23
int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

I think this is better than

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

incase the size of the array changes.

Tarski
  • 5,360
  • 4
  • 38
  • 47
12

You can do the whole static initializer thing as detailed above, but it can be a real bummer when your array size changes (when your array embiggens, if you don't add the appropriate extra initializers you get garbage).

memset gives you a runtime hit for doing the work, but no code size hit done right is immune to array size changes. I would use this solution in nearly all cases when the array was larger than, say, a few dozen elements.

If it was really important that the array was statically declared, I'd write a program to write the program for me and make it part of the build process.

plinth
  • 48,267
  • 11
  • 78
  • 120
9

Here is another way:

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},
};

See:

C-Extensions

Designated inits

Then ask the question: When can one use C extensions?

The code sample above is in an embedded system and will never see the light from another compiler.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
humble_guru
  • 526
  • 1
  • 3
  • 3
9

I know the original question explicitly mentions C and not C++, but if you (like me) came here looking for a solution for C++ arrays, here's a neat trick:

If your compiler supports fold expressions, you can use template magic and std::index_sequence to generate an initializer list with the value that you want. And you can even constexpr it and feel like a boss:

#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

You can take a look at the code at work (at Wandbox)

Clemens Sielaff
  • 708
  • 10
  • 15
8

A slightly tongue-in-cheek answer; write the statement

array = initial_value

in your favourite array-capable language (mine is Fortran, but there are many others), and link it to your C code. You'd probably want to wrap it up to be an external function.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
6

For initializing 'normal' data types (like int arrays), you can use the bracket notation, but it will zero the values after the last if there is still space in the array:

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};
warren
  • 32,620
  • 21
  • 85
  • 124
5

If the array happens to be int or anything with the size of int or your mem-pattern's size fits exact times into an int (i.e. all zeroes or 0xA5A5A5A5), the best way is to use memset().

Otherwise call memcpy() in a loop moving the index.

ddimitrov
  • 3,293
  • 3
  • 31
  • 46
5

There is a fast way to initialize array of any type with given value. It works very well with large arrays. Algorithm is as follows:

  • initialize first element of the array (usual way)
  • copy part which has been set into part which has not been set, doubling the size with each next copy operation

For 1 000 000 elements int array it is 4 times faster than regular loop initialization (i5, 2 cores, 2.3 GHz, 4GiB memory, 64 bits):

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;
}
Maciej
  • 9,355
  • 2
  • 15
  • 18
  • 2
    Sorry, but this is not true. Maybe you forgot to turn on compile optimization during your tests (tested with debug mode?). If I test this, the loop is nearly always 50% faster than memfill ('always' due to some load jitters on my machine). And using memset(a,0,sizeof(a)); is even twice as fast than loopfill. – RS1980 Mar 17 '16 at 11:37
  • 3
    As with any benchmarking code, you need to be extremely careful. Adding a loop to execute the timing code 10 times (and doubling the size of the array to 20M) shows — for me, running on a MacBook Pro with macOS Sierra 10.12.3 and using GCC 6.3.0 — that the first time, using the loop takes around 4600 µs, while the `memfill()` code takes around 1200 µs. However, on subsequent iterations, the loop takes about 900-1000 µs while the `memfill()` code takes 1000-1300 µs. The first iteration is probably impacted by the time to fill the cache. Reverse the tests and `memfill()` is slow first time. – Jonathan Leffler Feb 14 '17 at 23:51
4
  1. If your array is declared as static or is global, all the elements in the array already have default default value 0.
  2. Some compilers set array's the default to 0 in debug mode.
  3. It is easy to set default to 0 : int array[10] = {0};
  4. However, for other values, you have use memset() or loop;

example: int array[10]; memset(array,-1, 10 *sizeof(int));

Hannah Zhang
  • 489
  • 5
  • 5
3
int array[1024] = {[0 ... 1023] = 5};

As the above works fine but make sure no spaces between the ... dots.

wovano
  • 4,543
  • 5
  • 22
  • 49
Ratan Raj
  • 349
  • 2
  • 4
2

Nobody has mentioned the index order to access the elements of the initialized array. My example code will give an illustrative example to it.

#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;
}

The output is:

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
hkBattousai
  • 10,583
  • 18
  • 76
  • 124
  • 4
    `` isn't valid `C` as `std::cout`, `std::cin`, etc is part of the `std::namespace` and `C` doesn't support `namespaces`. Try using `` for `printf(...)` instead. – Francis Cugler Jan 28 '18 at 19:35
2

Cutting through all the chatter, the short answer is that if you turn on optimization at compile time you won't do better than this:

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

Added bonus: the code is actually legible :)

JWDN
  • 382
  • 3
  • 13
  • 9
    The question specifically asked for initialization. This is explicitly not initialization, but assignment done _after_ initialization. It might be done immediately, but it's still not initialization. – Andy Feb 09 '17 at 21:48
  • Entirely not helpful for a large static lookup table inside a function called many times. – Martin Bonner supports Monica Feb 21 '18 at 10:28
  • ...don't recall static lookup tables inside functions being part of the original question - keep it simple. That said, @Community probably nailed it. – JWDN Feb 16 '19 at 16:24
1

I know that user Tarski answered this question in a similar manner, but I added a few more details. Forgive some of my C for I'm a bit rusty at it since I'm more inclined to want to use C++, but here it goes.


If you know the size of the array ahead of time...

#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" );
}

There are a few caveats above; one is that UINT myArray[size]; is not directly initialized upon declaration, however the very next code block or function call does initialize each element of the array to the same value you want. The other caveat is, you would have to write an initializing function for each type you will support and you would also have to modify the printArray() function to support those types.


You can try this code with an online complier found here.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
1

For delayed initialization (i.e. class member constructor initialization) consider:

int a[4];

unsigned int size = sizeof(a) / sizeof(a[0]);
for (unsigned int i = 0; i < size; i++)
  a[i] = 0;
Sooth
  • 2,834
  • 23
  • 26
1

If the size of the array is known in advance, one could use a Boost preprocessor C_ARRAY_INITIALIZE macro to do the dirty job for you:

#include <boost/preprocessor/repetition/enum.hpp>
#define C_ARRAY_ELEMENT(z, index, name) name[index]
#define C_ARRAY_EXPAND(name,size) BOOST_PP_ENUM(size,C_ARRAY_ELEMENT,name)
#define C_ARRAY_VALUE(z, index, value) value
#define C_ARRAY_INITIALIZE(value,size) BOOST_PP_ENUM(size,C_ARRAY_VALUE,value)
ferdymercury
  • 698
  • 4
  • 15
1

To initialize with zeros -

  char arr[1000] = { 0 };

It is better to do with normal "for loop" for initialing other than 0.

  char arr[1000];
  for(int i=0; i<arr.size(); i++){
     arr[i] = 'A';
  }
0

method 1 :

int a[5] = {3,3,3,3,3}; 

formal initialization technique.

method 2 :

int a[100] = {0};

but its worth to note that

int a[10] = {1}; 

doesn't initialize all values to 1

this way of initialization exclusively for 0

if you just do

int a[100];

some compilers tend to take garbage value hence its always preferred to do

int a[1000] = {0};
0

Just as a follow up of the answer of Clemens Sielaff. This version requires C++17.

template <size_t Cnt, typename T>                                               
std::array<T, Cnt> make_array_of(const T& v)                                           
{                                                                               
    return []<size_t... Idx>(std::index_sequence<Idx...>, const auto& v)        
    {                                                                           
        auto identity = [](const auto& v, size_t) { return v; };                
        return std::array{identity(v, Idx)...};                                 
    }                                                                           
    (std::make_index_sequence<Cnt>{}, v);                                       
}

You can see it in action here.

Pavel Vazharov
  • 115
  • 1
  • 4
-2

I see no requirements in the question, so the solution must be generic: initialization of an unspecified possibly multidimensional array built from unspecified possibly structure elements with an initial member value:

#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);
}

Result:

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 changed to (char*)start+element_size

sambowry
  • 2,436
  • 1
  • 16
  • 13
  • 1
    I'm dubious of whether or not this is a solution. I'm not sure whether `sizeof(void)` is even valid. – Chris Lutz Oct 13 '09 at 23:58
  • 3
    It doesn't work. Only the first two are initialised, the remainder are all uninitialised. I'm using GCC 4.0 on Mac OS X 10.4. – dreamlax Oct 14 '09 at 00:22
  • This invokes undefined behaviour because the source data in the second `memcpy()` overlaps with the destination space. With a naïve implementation of `memcpy()`, it may work but it is not required that the system makes it work. – Jonathan Leffler Feb 14 '17 at 23:10
-2
#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;
}

It will give the o/p 5 5 5 5 5 5 ...... till the size of whole array

Dadhich Sourav
  • 289
  • 6
  • 19
-2

Back in the day (and I'm not saying it's a good idea), we'd set the first element and then:

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

Not even sure it would work any more (that would depend on the implementation of memcpy) but it works by repeatedly copying the initial element to the next - even works for arrays of structures.

Mike
  • 2,721
  • 1
  • 15
  • 20
  • That won't work reliably. IMHO, the Standard should have provided functions that were like `memcpy` but specified bottom-up or top-down copy order in case of overlap, but it doesn't. – supercat Jan 30 '20 at 16:14
  • As I said, it was just something we did that wouldn't work reliably but, back then, we were more focused on efficiency than avoiding undocumented features. While it is more efficient to copy memory forwards, there's nothing in the specification to say it can't copy it backwards, in a random order or split it across multiple threads. memmove () provides the ability to copy without clashes. – Mike Jan 31 '20 at 22:07
  • This is equivalent to the code in another [answer](https://stackoverflow.com/a/1563541/15168) — and flawed. Using `memmove()` does not make it work. – Jonathan Leffler Feb 29 '20 at 18:47