2013-11-22 3 views
2

지정 초기화 프로그램을 사용하여 const struct을 초기화하려고합니다. 그러나 struct 요소 중 하나는 고정 너비 배열입니다. 나는 이미 배열을 적절한 크기의 또 다른 고정 너비 배열로 초기화하고 싶은 내용이 있습니다.지정한 초기화 프로그램에서 배열 복사

지정된 초기화 프로그램으로이를 수행 할 수있는 방법이 있습니까? 내가 성취하려는 것을 간단하게 (실패한 예) 아래에 설명합니다.

struct foo { 
    uint8_t array1[4]; 
    uint8_t array2[4]; 
} 

uint8_t array[4] = { 
    1, 2, 3, 4 
}; 

struct foo const bar = { 
    .array1 = array,  // incompatible pointer to integer conversion 
    .array2 = { *array } // only copies the first element 
}; 
+0

'struct foo'는'array1'과'array2'로'int [4]'로 정의되어 있다고 가정합니까? 배열이 포인터로 정의 된 경우 작동합니다 :'int * array1'. 그러나 분명히 당신은 그런 식으로 정보를 잃어 버립니다. – Kninnug

+0

@Kninnug, 데이터는 복사되지 않고 공유되지만 괜찮을 수도 있습니다. –

+0

당신은 그것을 하나씩 할 수는 있지만, 그것은보기 흉하고 튼튼하지는 않습니다. –

답변

1

짧은 대답 : 할 수 없습니다. C는 (표준 라이브러리 -) 함수를 사용하지 않고 배열을 복사하지 않습니다. 경고는 배열이 정적이거나 일정한 경우에도 배열 전체를 할당 할 수 없다는 사실에서 기인합니다. 배열이 할당에서 r 값으로 사용될 때 포인터는 쇠퇴하므로 다른 배열 (전체적으로)에 할당 될 수 없습니다.

가장 쉬운 방법은 memcpy을 사용하는 것이지만 분명히 그 기능 내에 있어야합니다.

+0

감사합니다. 내가 할 수있는 마법이 있었으면 좋겠어. 그렇지 않다면, 'memcpy'라고. –

+0

불행히도. 나는 몇 가지 어려운 증거를 찾기 위해 C99 표준을 감추고 있지만, 순수 C (구문)를 사용하여 배열을 복사 할 수있는 방법은 없습니다. – Kninnug

+0

@Kninnug 배열이 호환 가능한 구조체에 포함 된 경우 수행 할 수 있습니다. 그러나 구조체는 함수 밖에서 복사하여 초기화 할 수 없으므로이 상황에서는 도움이되지 않습니다. – tab

0

다른 배열에서 복사하여 배열을 초기화 할 수 없습니다 수 있지만, 처리기 매크로를 사용하는 것이 도움이 될 수 있습니다

 
#define ARRAY_INIT {1, 2, 3, 4} 

struct foo const bar = { 
    .array1 = ARRAY_INIT, 
    .array2 = ARRAY_INIT 
}; 
+0

바이트를 복사 할 배열은 동적 데이터를 포함합니다. –

+0

글쎄, 동적 데이터로 초기화 할 수 없습니다. 컴파일시 알려줘야합니다. – wildplasser

+0

@wildplasser - 문제의 객체가 정적이거나 전역 범위를 가지고있는 경우에만 이것이 사실이라고 생각합니다. 적어도 저에게는 효과가있는 것 같습니다. –

1

바는 전역 범위를 가지고, 또는 당신에게 다음, static으로 선언하는 경우 해당 멤버가 배열인지 여부에 관계없이 지정된 이니셜 라이저를 사용하여 비 직접적인 값에서 초기화 할 수 없습니다. 경우

그러나 : 바 일부 함수의 스택에 선언하고,

  • 귀하의 고정 된 크기의 배열이 정말에만 4 개 요소,
  • 이 있는가

    1. 당신은 수 있습니다 다음과 같이 빠져 나올 수 있습니다 :

      #include <stdio.h> 
      #include <stdint.h> 
      
      struct foo { 
          uint8_t array1[4]; 
          uint8_t array2[4]; 
      }; 
      
      #define ARRAY_INIT(a) { a[0], a[1], a[2], a[3] } 
      
      int main (int argc, char **argv) { 
          uint8_t arr_init[4] = { 
           1, 2, 3, 4 
          }; 
          struct foo const bar = { 
           .array1 = ARRAY_INIT(arr_init), 
           .array2 = ARRAY_INIT(arr_init), 
          }; 
          printf("%d, %d\n", bar.array1[0], bar.array2[3]); 
          return (0); 
      } 
      

      초기화 코드 배열은 befor로 표시되어야합니다. 스택 프레임에서 초기화되고있는 것. 또는 함수 매개 변수에서 올 수 있습니다.

      물론 배열이 이보다 훨씬 큰 경우에는 이와 같은 매크로를 사용하면 매우 혼란 스러울 것입니다.

    +0

    초기화에는 비 상수 요소를 사용할 수 없지만 지정된 이니셜 라이저 구문 자체는 대상 범위 또는 저장 장치에 의해 제한되지 않습니다. static struct foo f = {.array1 = {[0] = 1, [1] = 2, [3] = 3, [4] = 4}}'는 완벽하게 유효합니다. – tab

    +0

    @tab - 예 - 맞습니다 - 제 답변을 명확히했습니다. –