Simple C array declaration / assignment question

2019-02-17 16:17发布

问题:

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.

回答1:

you can declare static array with data to initialize from:

static int initvalues[3] = {1,2,3};
…
if(1)
    memmove(values,initvalues,sizeof(values));


回答2:

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


回答3:

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


回答4:

 //compile time initialization
 int values[3] = {1,2,3};

//run time assignment
 value[0] = 1;
 value[1] = 2;
 value[2] = 3;


回答5:

#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

int *setarray(int *ar,char *str)
{
    int offset,n,i=0;
    while (sscanf(str, " %d%n", &n, &offset)==1)
    {
        ar[i]=n;
        str+=offset;
        i+=1;
    }
    return ar;
}

int *setarray2(int *ar,int num,...)
{
   va_list valist;
   int i;
   va_start(valist, num);

   for (i = 0; i < num; i++) 
        ar[i] = va_arg(valist, int);
   va_end(valist);
   return ar;
}

int main()
{
    int *size=malloc(3*sizeof(int*)),i;
    setarray(size,"1 2 3");

    for(i=0;i<3;i++)
        printf("%d\n",size[i]);

    setarray2(size,3 ,4,5,6);
    for(i=0;i<3;i++)
        printf("%d\n",size[i]);

    return 0;
}


回答6:

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


回答7:

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


回答8:

There is also this... :)

char S[16]="";
strncpy(S,"Zoodlewurdle...",sizeof(S)-1);

Test what happens if you declare S[8] or S[32], to see why this is so effective.

I wrote my own string functions based on the logic of OpenBSD's strlcpy, aimed at ensuring a terminator byte MUST exist in the event of overflow, and standard strncpy won't do this so you have to watch carefully how you use it.

The method above is effective because the ="" at declaration ensures 0 bytes throughout, and sizeof(S)-1 ensures that if you overdo the quoted string passed to strncpy, you get truncation and no violation of the last 0 byte, so this is safe against overflow now, AND on accessing the string later. I aimed this at ANSI C so it ought to be safe anywhere.



回答9:

I would post this as a comment, but I don't have enough reputation. Another (perhaps dirty) way of initializing an array is to wrap it in a struct.

#include <stdio.h>

struct wrapper { int array[3]; };

int main(){
    struct wrapper a;
    struct wrapper b = {{1, 2, 3}};

    a = b;

    printf("%i %i %i", a.array[0], a.array[1], a.array[2]);

    return 0;
}