2009-10-17 6 views
5

На языках более высокого уровня я мог бы что-то похожее на этот пример на C, и все было бы хорошо. Однако, когда я компилирую этот пример, он жалуется горько. Как я могу назначить новые массивы объявленному массиву?Простой запрос/задание массива C

int values[3]; 

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

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

Спасибо.

+1

Смотрите здесь для некоторых идей: Http: // StackOverflow.com/questions/1223736/c-change-all-values-of-the-array-of-structure-in-one-line/1223806 # 1223806 –

ответ

1

вы можете объявить статический массив с данными для инициализации из:

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

Могу ли я не делать memmove (значения, {1,2,3}, sizeof (значения)); ? –

+0

Нет, вы не можете так сделать. – hlovdal

+1

Я думаю, вы могли бы: memmove (values, (int [3]) {1,2,3}, sizeof (int [3])); См. Мой ответ ниже. –

11

Вы можете только сделать множественное присваивание массива, при объявлении массива:

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

После объявления, вы должны присвоить значение каждого в отдельности, т.е.

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

Или вы может использовать цикл, в зависимости от того, какие значения вы хотите использовать.

if (1) 
{ 
    for (i = 0 ; i < 3 ; i++) 
    { 
    values[i] = i+1; 
    } 
} 
+0

Это работает для 3 значений, но что, если бы у меня был массив с 50 значениями ? –

+0

Тогда вы бы использовали цикл, или вы бы 'memmove' /' memcpy', как @hacker предлагает в другом ответе. –

+0

memcpy кажется tidiest. Спасибо за вашу помощь. –

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

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

В C99, используя compound literals, вы могли бы сделать:

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

или

int* values = (int[3]){1, 2, 3}; 
+3

+1; имейте в виду, что в последнем случае массив будет иметь автоматическую продолжительность хранения, т. е. возврат его из функции заставит вас съесть грусть – Christoph

+0

Christoph, это означало бы, что 'memmove'ing из такого массива будет включать в себя первую инициализацию в автоматическом хранилище, а затем скопировать его? –

+0

@hacker: в принципе, да, на практике компилятор будет оптимизировать его (для gcc, '-O1' достаточно) – Christoph

0

Также можно скрыть memcpy с помощью блок-копии структурных структур компилятора. Это делает код уродливым из-за всех .i и i: но, возможно, он решает вашу конкретную проблему.

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

Это работает и оптимизирует лучше при НКУ с -O3 (компилятор полностью удаляет код), в то время как тетсру заставляет память для копирования во всех случаях.

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

Вопрос помечен C, а не C++. Этот ответ является C++ и полностью недействителен в C. –

0

Существует также это ... :)

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

Испытание, что происходит, если вы объявите S [8] или S [32], чтобы понять, почему это так эффективно.

Я написал свои собственные строковые функции, основанные на логике strbcpy OpenBSD, направленные на то, чтобы гарантировать, что байт терминатора ДОЛЖЕН существовать в случае переполнения, а стандартная strncpy не сделает этого, поэтому вам нужно внимательно следить за тем, как вы его используете ,

Описанные выше метод является эффективным, поскольку ="" в декларации обеспечивает 0 байт во всем, и sizeof(S)-1 гарантирует, что если вы переборщите цитируемую строку, переданную в strncpy, вы получаете усечения и без нарушения последних 0 байт, так что это безопасно против переполнение, а также доступ к строке позже. Я нацелил это на ANSI C, поэтому он должен быть в безопасности.

+1

Я понимаю, что это строка, а не массив целых чисел, но может быть способ для перевода метода соответственно, без необходимости писать свой собственный итерационный код. – Lostgallifreyan

+0

'strncpy' для массивов символов, поскольку ___ - целым массивам? –

0

Я бы разместил это как комментарий, но у меня недостаточно репутации. Другой (возможно, грязный) способ инициализации массива состоит в том, чтобы обернуть его в структуру.

#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; 
} 
1
#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; 
} 
+0

вы также можете сгенерировать sscanf из функции, а затем вернуть массив – frozenat99

+0

Добро пожаловать в Stack Overflow. Вскоре прочитайте страницу [О программе]. Когда вы отвечаете на вопрос в течение 6 лет после его запроса (и у него есть голосовые и принятые ответы), у вас должно быть что-то особенное - новый подход или, возможно, продукт изменился с тех пор, как были даны исходные ответы. К счастью для вас, ни один из других ответов не предполагает разбора строкового представления значений массива - так что все в порядке. Я не уверен, что это хороший механизм, но он другой. Ваш вызов 'malloc()' не выделяет достаточно места на любой машине, где 'sizeof (char)! = Sizeof (int)'. –

+0

отредактировал malloc, если использование строк не работает, вы также можете использовать функции из stdarg.h – frozenat99