views:

404

answers:

6

In higher level languages I would be able something similar to this example in C and it would be fine. However, when I compile this C example it complains bitterly. How can I assign new arrays to the array I declared?

int values[3];

if(1)
   values = {1,2,3};

printf("%i", values[0]);

Thanks.

+5  A: 

You can only do multiple assignment of the array, when you declare the array:

int values[3] = {1,2,3};

After declaration, you'll have to assign each value individually, i.e.

if (1) 
{
  values[0] = 1;
  values[1] = 2;
  values[2] = 3;
}

Or you could use a loop, depending on what values you want to use.

if (1)
{
  for (i = 0 ; i < 3 ; i++)
  { 
    values[i] = i+1;
  }
}
Mark Rushakoff
This works for 3 values, but what if I had an array with 50 values?
Daniel Wood
Then you would use a loop, or you would `memmove`/`memcpy` like @hacker suggests in another answer.
Mark Rushakoff
memcpy seems tidiest. Thanks for your help.
Daniel Wood
+1  A: 

you can declare static array with data to initialize from:

static int initvalues[3] = {1,2,3};
…
if(1)
    memmove(values,initvalues,sizeof(values));
Michael Krelin - hacker
Can I not do memmove(values,{1,2,3},sizeof(values)); ?
Daniel Wood
No, you can not do it like that.
hlovdal
I think you could: memmove(values, (int[3]){1,2,3}, sizeof(int[3])); See my answer below.
Karl Voigtland
There's no need to use `memmove` over `memcpy` here - the arrays definitely do not overlap.
caf
Why do you think I used memmove "over memcpy"? I just used memmove. ;-)
Michael Krelin - hacker
@Michael: what @caf meant is that in the given scenario there's no need to move memory because source and dest don't overlap. That way, memcpy may be slightly faster. See this http://stackoverflow.com/questions/1201319/what-is-the-difference-between-memmove-and-memcpy
jweyrich
+1  A: 
 //compile time initliaztion
 int values[3] = {1,2,3}

//run time assignment
 value[0] = 1;
 value[1] = 2;
 value[2] = 3;
pierr
+4  A: 

In C99, using compound literals, you could do:

memcpy(values, (int[3]){1, 2, 3}, sizeof(int[3]));

or

int* values = (int[3]){1, 2, 3};
Karl Voigtland
+1; keep in mind that in the latter case, the array will have automatic storage duration, ie returning it from a function will get you eaten by a grue
Christoph
Christoph, would that mean that `memmove`ing from such an array would involve first initializing it in automatic storage and then copying it over?
Michael Krelin - hacker
@hacker: in priciple, yes, in practice, the compiler will optimize it away (for gcc, `-O1` is enough)
Christoph
Christoph, thanks, that was my guess.
Michael Krelin - hacker
On the other hand, are you sure it is really automatic storage? Isn't this similar to string literals? Or would using `const` keyword make it behave the way string literals would?
Michael Krelin - hacker
@hacker: yes, `const` compound literals may be shared the same way strings are (this is an implementation detail and has no bearing on language semantics); non-const literals are guaranteed to be distinct on each entry to the enclosing block
Christoph
Yes, but now that I think of it, I don't think I've ever seen non-const literals in C before…
Michael Krelin - hacker
Also, keep in mind as the answerer said that this is C99, not the more popular ISO C90.
BobbyShaftoe
A: 

It is also possible to hide the memcpy by using the compiler's block copy of structs. It makes the code ugly because of all the .i and i: but maybe it solves your specific problem.

typedef struct {
    int i[3];
} inta;

int main()
{
    inta d = {i:{1, 2, 3}};

    if (1)
        d = (inta){i:{4, 5, 6}};

    printf("%d %d %d\n", d.i[0], d.i[1], d.i[2]);

    return 0;
}
eyalm
A: 

This works and optimizes better under gcc with -O3 (the compiler completely removes the code), whereas the memcpy forces the memory to be copied in all cases.

template <typename Array>
struct inner
{
    Array x;
};


template <typename Array>
void assign(Array& lhs, const Array& rhs)
{
    inner<Array>& l( (inner<Array>&)(lhs));
    const inner<Array>& r( (inner<Array>&)(rhs));
    l = r;
}

int main()
{
    int x[100];
    int y[100];

    assign(x, y);
}
Matthew Herrmann