1

when we write something like this

int arr[5] = 0; or int arr[5] = {0};

there is no problem

but when we do something like this

int arr[5];
arr[5] = {0};

an error occurs. Any explanation for this ?

Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
akashbhatia
  • 332
  • 1
  • 5
  • 11
  • 1
    I don't think that `int arr[5] = 0;` should work. What compiler do you have? – Jens Gustedt Feb 01 '11 at 07:40
  • Possible duplicate of [How to initialize all members of an array to the same value](http://stackoverflow.com/questions/201101/how-to-initialize-all-members-of-an-array-to-the-same-value) – phuclv Nov 24 '16 at 13:54

5 Answers5

4

It is simply a part of the language definition that arrays can be initialised, but not directly assigned. You can do what you want in C99 using memcpy() with a compound literal:

int arr[5];

/* ... */

memcpy(&arr, &(int [5]){ 0 }, sizeof arr);

With GCC's typeof extension, you can add a little more safety:

memcpy(&arr, &(typeof(arr)){ 0 }, sizeof arr);

In C89 you must give the source array a name:

{ static const int zero[5] = { 0 }; memcpy(&arr, &zero, sizeof arr); }
caf
  • 233,326
  • 40
  • 323
  • 462
  • Don't use typeof, it is not standard C. There is no reason for the ridiculous anonymous array syntax either, it is just obfuscation and clutters up the code and makes it non-portable. If you need to set an array in runtime, then declare a const array with all values set to zero, then memcpy() that array into the original one. It takes up exactly the same amount of space as your code, but is both readable and portable. – Lundin Feb 01 '11 at 09:05
  • 1
    @Lundin: The compound literal is portable - it has been standard C for more than a decade now. A separate static const array is fine too, but I feel that it is less readable, since you must track down the definition of that source array to see what the `memcpy()` line does. I specifically noted `typeof` as an extension. – caf Feb 01 '11 at 09:21
  • @caf: C99 is far from widely recognized, only used by some PC programmers, and few compilers support it fully. There is no reason to let go of C90 portability just to show off that you know some rarely used syntax from C99. To me, that's not so far from writing some abomination like `#define CLEARMEM_INT(dest, n) { const int _arr[n] = {0}; memcpy(dest, _arr, n); }` (and as we can see, memset() would be more suitable in this specific case anyhow) – Lundin Feb 01 '11 at 10:19
  • 1
    @Lundin: In the main, it is not compiler support that is incomplete but standard library (and nowhere near as big a deal as it is often made out). There is no reason to refuse to learn or acknowledge C99 just because support is not universal; it is available on most modern server systems, major smartphones and many embedded systems (the major holdout being MSVC). I agree that C99-specific features should be noted as such (and I have done so), but I do not agree that we should pretend that they do not exist. – caf Feb 01 '11 at 11:31
  • @caf: Regardless of how widespread C99 is, you shouldn't use superfluous features of any programming language. The C language in particular is very rich on superfluous syntax. Take some of the most horrible features as examples: function-like macros, bit fields, the ?: operator, multiple assignment operators on one line, goto, continue, trigraphs, setjmp/longjmp, etc etc... I can continue to list them for quite a while. C99 added several other such features. Just because it is there in the standard doesn't make it good practice. – Lundin Feb 01 '11 at 11:55
  • @Lundin: Well, any list of superfluous language features is highly subjective (after all, a "language" only requires one judiciously-chosen instruction to be Turing-complete). There are some on your list of "most horrible" that I disagree with you about, and some that I don't - and I'm sure you can find as many different opinions on the matter as you can find C programmers. – caf Feb 02 '11 at 08:57
2

During definition, you can do this assignment.

However, arr[5] means trying to assign value to the 5th index and it expects a single integer value, not values inside curly braces to indicate array initialization.

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
0

int arr[5] means an array of integers with place to hold 5 values having index 0,1,2,3,4. now arr[5] would not point to any element in this array.

u could use

arr[] = {0,0,0,0,0} knowing that there are 5 elements in your array.

or may be memset() could help you.

ayush
  • 14,350
  • 11
  • 53
  • 100
0

The syntax of C is such that arr alone decays to &a[0], the address of the first element, in almost all contexts. So the syntax that would be natural for assigning to arrays arr = { ... }; can't work. So no assignment to an array as a whole is not possible.

The syntax int a[5] = { 0 }; is initialization and this works that it initializes all elements with 0. The best you can do is to always initialize arrays with this "catch all" initializer to have all elements in a known state. Then, if later in your program you decide that you want different values, assign them directly.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

First, please note the linguistic difference between initialization and assignment. The former occurs when a variable is given a value at the same time as it is declared, while the latter is everything else giving the variable a value in runtime. If you set all elements of a variable in a loop, you are doing so in runtime, and therefore assigning values to the array.

The {} is called an initializer list. Initializer lists can only occur at the same line as the variable declaration, and all items inside the list must be constants (assuming C90 standard). They can be used to initialize both arrays or structs (a.k.a "aggregates"), same rules apply to both.

int arr[5] = {0};

What this does in detail, is to set the first element at index [0] to zero. The remaining relements are initialized according to a rule which states that if only a few elements are given in an initializer list, the elements that weren't explicitly initialized by the programmer shall be set to zero by the compiler (ISO 9899:1999 6.7.8 §19).

So the line above sets arr[0] to zero, and then the compiler sets the remaining elements, arr[1] to arr[4], to zero as well. Had you written

int arr[5] = {1};

then the elements of the array would have been initialized to {1, 0, 0, 0, 0}.

Lundin
  • 195,001
  • 40
  • 254
  • 396