There are several different things going on here.
One is that, strictly speaking, initialization is quite a bit different than assignment. They look pretty similar, but they're almost completely different "under the hood" (so to speak).
And then one of the big differences between initialization and assignment is that there are some special things you can do in initializations. The biggest one is the one you're asking about: the list-of-values syntax {1, 2, 3, 4, 5}
is (with a special exception which we'll get to) only valid in initializers.
There's also the issue that you can't assign to arrays at all. After you do
int test[5];
or
int test[5] = whatever;
you can't later do the assignment
test = anything_else; /* WRONG */
at all. There is nothing you can put on the right-hand sign of that assignment operator (that is, in the place of "anything_else
") that will assign new values to all the elements of the array test
in one fell swoop. Arrays are "second class citizens" in C, and part of that second-class status is that arrays can't be assigned.
In particular, even if you tried to do
int test[] = {1, 2, 3, 4, 5};
int newvals[] = {6, 7, 8, 9, 10};
test = newvals; /* WRONG */
this would not work. One compiler I tried it with just now says "array type 'int [5]' is not assignable".
If you want to copy values from one array to another, you can do it with the standard library function memcpy
, if you want. So this would work:
memcpy(test, newvals, 5 * sizeof(int));
This basically just does a bitwise copy of 5 int's worth of data from newvals
to test
.
So, you might be wondering, is there a way to skip the explicit newvals
array and do something like
memcpy(test, {6, 7, 8, 9, 10}, 5 * sizeof(int)); /* WRONG */
Once upon a time, the answer was "no". Once upon a time, there was just no way to have a "temporary array value" like {6, 7, 8, 9, 10}
. The only place you could put the list-of-values syntax {6, 7, 8, 9, 10}
was, as I said earlier, in an initialization. That's because, in an initialization, you're not creating a "temporary array value", what you're doing is supplying the initial values for an actual array value.
However, recent versions of C do have a way to do this. (And it's not really all that "recent" any more; I think it's been at least ten years by now.) It looks like this:
memcpy(test, (int [5]){6, 7, 8, 9, 10}, 5 * sizeof(int));
Notice that you can't just say {6, 7, 8, 9, 10}
; you have to put that (int [5])
thing in front of it, that looks like a cast, to tell the compiler what kind of temporary structure you intend to represent with the stuff between the braces {
…}
.
You can read more about the "second class" status of arrays, and the inability to assign them, in this answer.
const
, the value of its elements can be changed after the definition. Arrays are not lvalues, so talking about the value of an array is somewhat confusing and the C Standard carefully avoid doing so, but it is IMHO even more confusing to use value to refer to the array's address, despite the fact that arrays decay as pointers to their first element when used in most expression contexts... – Edeastruct
indeed have a value and the C99 trick can also be used to change this value in a single assignment. – Edea