문제

내가 큰 배열 C(C++경우 차이를 만드는).내가 초기화하고자 하는 모든 구성원은 동일한 값입니다.수 맹세한 내면을 알고 간단한 방법입니다.용 memset() 내 경우에는,그러나 없는 이렇게 하는 방법이 바로 내장 된 C syntax?

도움이 되었습니까?

해결책

지 않으면 그 값을 0(하는 경우 생략할 수 있습니다 몇몇 부분의 이니셜라이저 와 해당하는 요소를 0 으로 초기화됩),쉬운 방법이 없다.

을 간과하지 않는 명백한 솔루션이지만,:

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };

요소 누락된 값을 초기화됩 0:

int myArray[10] = { 1, 2 }; // initialize to 1,2,0,0,0...

그래서 초기화 모든 요소를 0:

int myArray[10] = { 0 }; // all elements 0

에서는 C++,빈 초기화 목록 또한 초기화 모든 요소들은 0 입니다.이 허용되지 않습 C:

int myArray[10] = {}; // all elements 0 in C++

을 기억하는 객체를 가진 정적 저장 기간이 초기화하지 않은 경우 0 이니셜라이저 지정:

static int myArray[10]; // all elements 0

그리고"0"을 의미하지는 않"모든 비트-zero",그렇게 사용하기 위 더 많은 휴대용 보다 작성 memset().(부동 소수점 값이 될 것입니다 초기화를+0,포인터는 null 값,etc.)

다른 팁

컴파일러가 GCC 인 경우 다음 구문을 사용할 수 있습니다.

int array[1024] = {[0 ... 1023] = 5};

자세한 설명을 확인하십시오 :http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/designated-inits.html

다중 사본-페이스트없이 동일한 값으로 큰 배열을 정적으로 초기화하려면 매크로를 사용할 수 있습니다.

#define VAL_1X     42
#define VAL_2X     VAL_1X,  VAL_1X
#define VAL_4X     VAL_2X,  VAL_2X
#define VAL_8X     VAL_4X,  VAL_4X
#define VAL_16X    VAL_8X,  VAL_8X
#define VAL_32X    VAL_16X, VAL_16X
#define VAL_64X    VAL_32X, VAL_32X

int myArray[53] = { VAL_32X, VAL_16X, VAL_4X, VAL_1X };

값을 변경 해야하는 경우 한 곳에서만 교체를해야합니다.

편집 : 가능한 유용한 확장

(의례 조나단 레플러)

다음과 같이 쉽게 일반화 할 수 있습니다.

#define VAL_1(X) X
#define VAL_2(X) VAL_1(X), VAL_1(X)
/* etc. */

변형은 다음을 사용하여 만들 수 있습니다.

#define STRUCTVAL_1(...) { __VA_ARGS__ }
#define STRUCTVAL_2(...) STRUCTVAL_1(__VA_ARGS__), STRUCTVAL_1(__VA_ARGS__)
/*etc */ 

구조 또는 화합물 어레이와 함께 작동합니다.

#define STRUCTVAL_48(...) STRUCTVAL_32(__VA_ARGS__), STRUCTVAL_16(__VA_ARGS__)

struct Pair { char key[16]; char val[32]; };
struct Pair p_data[] = { STRUCTVAL_48("Key", "Value") };
int a_data[][4] = { STRUCTVAL_48(12, 19, 23, 37) };

매크로 이름은 협상 가능합니다.

배열의 모든 구성원이 명시 적으로 초기화되도록하려면 선언에서 차원을 생략하십시오.

int myArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

컴파일러는 이니셜 라이저 목록에서 치수를 추론합니다. 불행히도, 다차원 배열의 경우 가장 바깥 쪽 치수 만 생략 할 수 있습니다.

int myPoints[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

괜찮지 만

int myPoints[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

아니다.

이 구문을 사용한 코드를 보았습니다.

char* array[] = 
{
    [0] = "Hello",
    [1] = "World"
};   

특히 유용 해지는 곳은 열거를 색인으로 사용하는 배열을 만드는 것입니다.

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

#define _ITEM(x) [x] = #x

char* array[] = 
{
    _ITEM(ERR_OK),
    _ITEM(ERR_FAIL),
    _ITEM(ERR_MEMORY)
};   

이렇게하면 열거적인 값 중 일부를 순서대로 쓰지 않더라도 순서대로 유지됩니다.

이 기술에 대한 자세한 내용은 찾을 수 있습니다 여기 그리고 여기.

int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

나는 이것이보다 낫다고 생각한다

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5...

배열의 크기가 변경되는 경우.

위에서 자세히 설명 된대로 전체 정적 이니셜 라이저를 수행 할 수 있지만 배열 크기가 변경 될 때 (배열 Embiggens, 적절한 추가 이니셜 라이저를 추가하지 않으면 쓰레기를 얻는 경우) 실제 범위가 될 수 있습니다.

Memset은 작업을 수행하기위한 런타임 히트를 제공하지만 코드 크기는 어울리지 않습니다. 배열이 수십 개 요소보다 큰 경우 거의 모든 경우 에이 솔루션을 사용합니다.

배열이 정적으로 선언 된 것이 정말 중요하다면, 나는 프로그램을 작성하고 빌드 프로세스의 일부로 만들기위한 프로그램을 작성합니다.

다른 방법은 다음과 같습니다.

static void
unhandled_interrupt(struct trap_frame *frame, int irq, void *arg)
{
    //this code intentionally left blank
}

static struct irqtbl_s vector_tbl[XCHAL_NUM_INTERRUPTS] = {
    [0 ... XCHAL_NUM_INTERRUPTS-1] {unhandled_interrupt, NULL},
};

보다:

C- 확장

지정된 INIT

그런 다음 질문을하십시오 : 언제 C 확장을 사용할 수 있습니까?

위의 코드 샘플은 임베디드 시스템에 있으며 다른 컴파일러에서 빛을 볼 수 없습니다.

'정상'데이터 유형 (예 : int 배열)을 초기화하려면 브래킷 표기법을 사용할 수 있지만 배열에 여전히 공간이있는 경우 마지막 값이 0이됩니다.

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};

약간 혀 뺨에 대한 대답; 성명서를 작성하십시오

array = initial_value

좋아하는 어레이 가능 언어 (광산은 Fortran이지만 다른 많은 사람들이 있습니다)에서 C 코드에 연결합니다. 당신은 아마도 그것을 외부 기능으로 마무리하고 싶을 것입니다.

배열이 int 또는 int 크기 또는 Mem-Pattern의 크기를 가진 어떤 것도 정확한 시간에 int (즉, 모든 0 또는 0xa5a5a5a5)에 맞는 경우 가장 좋은 방법은 사용하는 것입니다. memset ().

그렇지 않으면 인덱스를 움직이는 루프에서 memcpy ()를 호출하십시오.

주어진 값으로 모든 유형의 배열을 초기화하는 빠른 방법이 있습니다. 큰 배열에서 매우 잘 작동합니다. 알고리즘은 다음과 같습니다.

  • 배열의 첫 번째 요소 초기화 (일반적인 방법)
  • 설정되지 않은 부품으로 설정된 복사 부품, 다음 사본 조작마다 크기를 두 배로 늘립니다.

을 위한 1 000 000 집단 int 배열은 일반 루프 초기화보다 4 배 빠릅니다 (i5, 2 코어, 2.3GHz, 4GIB 메모리, 64 비트) :

loop runtime 0.004248 [seconds]

memfill() runtime 0.001085 [seconds]


#include <stdio.h>
#include <time.h>
#include <string.h>
#define ARR_SIZE 1000000

void memfill(void *dest, size_t destsize, size_t elemsize) {
   char   *nextdest = (char *) dest + elemsize;
   size_t movesize, donesize = elemsize;

   destsize -= elemsize;
   while (destsize) {
      movesize = (donesize < destsize) ? donesize : destsize;
      memcpy(nextdest, dest, movesize);
      nextdest += movesize; destsize -= movesize; donesize += movesize;
   }
}    
int main() {
    clock_t timeStart;
    double  runTime;
    int     i, a[ARR_SIZE];

    timeStart = clock();
    for (i = 0; i < ARR_SIZE; i++)
        a[i] = 9;    
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("loop runtime %f [seconds]\n",runTime);

    timeStart = clock();
    a[0] = 10;
    memfill(a, sizeof(a), sizeof(a[0]));
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("memfill() runtime %f [seconds]\n",runTime);
    return 0;
}

초기화 된 배열의 요소에 액세스하기 위해 색인 순서를 언급 한 사람은 없습니다. 내 예제 코드는 예시적인 예를 제공합니다.

#include <iostream>

void PrintArray(int a[3][3])
{
    std::cout << "a11 = " << a[0][0] << "\t\t" << "a12 = " << a[0][1] << "\t\t" << "a13 = " << a[0][2] << std::endl;
    std::cout << "a21 = " << a[1][0] << "\t\t" << "a22 = " << a[1][1] << "\t\t" << "a23 = " << a[1][2] << std::endl;
    std::cout << "a31 = " << a[2][0] << "\t\t" << "a32 = " << a[2][1] << "\t\t" << "a33 = " << a[2][2] << std::endl;
    std::cout << std::endl;
}

int wmain(int argc, wchar_t * argv[])
{
    int a1[3][3] =  {   11,     12,     13,     // The most
                        21,     22,     23,     // basic
                        31,     32,     33  };  // format.

    int a2[][3] =   {   11,     12,     13,     // The first (outer) dimension
                        21,     22,     23,     // may be omitted. The compiler
                        31,     32,     33  };  // will automatically deduce it.

    int a3[3][3] =  {   {11,    12,     13},    // The elements of each
                        {21,    22,     23},    // second (inner) dimension
                        {31,    32,     33} };  // can be grouped together.

    int a4[][3] =   {   {11,    12,     13},    // Again, the first dimension
                        {21,    22,     23},    // can be omitted when the 
                        {31,    32,     33} };  // inner elements are grouped.

    PrintArray(a1);
    PrintArray(a2);
    PrintArray(a3);
    PrintArray(a4);

    // This part shows in which order the elements are stored in the memory.
    int * b = (int *) a1;   // The output is the same for the all four arrays.
    for (int i=0; i<9; i++)
    {
        std::cout << b[i] << '\t';
    }

    return 0;
}

출력은 다음과 같습니다.

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

11      12      13      21      22      23      31      32      33

모든 수다쟁이를 자르면 짧은 대답은 컴파일 시간에 최적화를 켜면 이보다 더 나은 일이 아니라는 것입니다.

int i,value=5,array[1000]; 
for(i=0;i<1000;i++) array[i]=value; 

추가 보너스 : 코드는 실제로 읽을 수 있습니다 :)

  1. 배열이 정적으로 선언되었거나 글로벌 인 경우 배열의 모든 요소에는 이미 기본 기본값 0이 있습니다.
  2. 일부 컴파일러는 디버그 모드에서 배열을 기본값으로 설정합니다.
  3. 기본값을 0 : int array [10] = {0}으로 쉽게 설정하기 쉽습니다.
  4. 그러나 다른 값의 경우 memset () 또는 루프를 사용해야합니다.

예 : INT 배열 [10]; memset (배열, -1, 10 *sizeof (int));

#include<stdio.h>
int main(){
int i,a[50];
for (i=0;i<50;i++){
    a[i]=5;// set value 5 to all the array index
}
for (i=0;i<50;i++)
printf("%d\n",a[i]);
   return 0;
}

그것은 O/P 5 5 5 5 5 5 ... 전체 배열의 크기까지 줄 것입니다.

나는 그 사용자를 알고 있습니다 Tarski 이 질문에 비슷한 방식으로 답변했지만 몇 가지 자세한 내용을 추가했습니다. C ++를 사용하려는 경향이 있기 때문에 약간 녹슬었기 때문에 내 C 중 일부를 용서하십시오.


배열의 크기를 미리 알고 있다면 ...

#include <stdio.h>

typedef const unsigned int cUINT;
typedef unsigned int UINT;

cUINT size = 10;
cUINT initVal = 5;

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal );
void printArray( UINT* myArray ); 

int main() {        
    UINT myArray[size]; 
    /* Not initialized during declaration but can be
    initialized using a function for the appropriate TYPE*/
    arrayInitializer( myArray, size, initVal );

    printArray( myArray );

    return 0;
}

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal ) {
    for ( UINT n = 0; n < size; n++ ) {
        myArray[n] = initVal;
    }
}

void printArray( UINT* myArray ) {
    printf( "myArray = { " );
    for ( UINT n = 0; n < size; n++ ) {
        printf( "%u", myArray[n] );

        if ( n < size-1 )
            printf( ", " );
    }
    printf( " }\n" );
}

위에는 몇 가지 경고가 있습니다. 하나는 그게 다 UINT myArray[size]; 선언시 직접 초기화되지는 않지만 다음 코드 블록 또는 함수 호출은 배열의 각 요소를 원하는 동일한 값으로 초기화합니다. 다른 경고는 당신은 initializing function 각각 type 당신은 지원할 것이며 또한 printArray() 이러한 유형을 지원하는 기능.


온라인 상칭자를 찾은 상태 에서이 코드를 시도 할 수 있습니다. 여기.

지연 초기화 (즉, 클래스 멤버 생성자 초기화)를 고려하십시오.

int a[4];

unsigned int size = sizeof(a) / sizeof(a[0]);
for (unsigned int i = 0; i < size; i++)
  a[i] = 0;

그날 (그리고 나는 그것이 좋은 생각이라고 말하는 것이 아닙니다), 우리는 첫 번째 요소를 설정 한 다음 :

memcpy (&element [1], &element [0], sizeof (element)-sizeof (element [0]);

더 이상 작동하지는 않지만 (Memcpy의 구현에 따라 다름) 초기 요소를 다음 요소에 반복적으로 복사하여 작동합니다.조차도 구조의 배열에 대해서도 작동합니다.

질문에 요구 사항이 없으므로 솔루션은 일반적인 것이어야합니다. 초기 멤버 값을 갖는 지정되지 않은 구조 요소로 구축 된 불특정 다차원 배열의 초기화.

#include <string.h> 

void array_init( void *start, size_t element_size, size_t elements, void *initval ){
  memcpy(        start,              initval, element_size              );
  memcpy( (char*)start+element_size, start,   element_size*(elements-1) );
}

// testing
#include <stdio.h> 

struct s {
  int a;
  char b;
} array[2][3], init;

int main(){
  init = (struct s){.a = 3, .b = 'x'};
  array_init( array, sizeof(array[0][0]), 2*3, &init );

  for( int i=0; i<2; i++ )
    for( int j=0; j<3; j++ )
      printf("array[%i][%i].a = %i .b = '%c'\n",i,j,array[i][j].a,array[i][j].b);
}

결과:

array[0][0].a = 3 .b = 'x'
array[0][1].a = 3 .b = 'x'
array[0][2].a = 3 .b = 'x'
array[1][0].a = 3 .b = 'x'
array[1][1].a = 3 .b = 'x'
array[1][2].a = 3 .b = 'x'

편집하다: start+element_size 바뀌었다 (char*)start+element_size

원래 질문은 C ++가 아닌 C를 명시 적으로 언급하지만 C ++ 배열에 대한 솔루션을 찾고 있다면 여기에 깔끔한 트릭이 있습니다.

컴파일러가 지원되는 경우 접는 표현, 당신은 템플릿 매직을 사용할 수 있습니다 std::index_sequence 원하는 값으로 이니셜 라이저 목록을 생성합니다. 그리고 당신은 심지어 할 수 있습니다 constexpr 그것은 상사처럼 느껴집니다 :

#include <array>

/// [3]
/// This functions's only purpose is to ignore the index given as the second
/// template argument and to always produce the value passed in.
template<class T, size_t /*ignored*/>
constexpr T identity_func(const T& value) {
    return value;
}

/// [2]
/// At this point, we have a list of indices that we can unfold
/// into an initializer list using the `identity_func` above.
template<class T, size_t... Indices>
constexpr std::array<T, sizeof...(Indices)>
make_array_of_impl(const T& value, std::index_sequence<Indices...>) {
    return {identity_func<T, Indices>(value)...};
}

/// [1]
/// This is the user-facing function.
/// The template arguments are swapped compared to the order used
/// for std::array, this way we can let the compiler infer the type
/// from the given value but still define it explicitly if we want to.
template<size_t Size, class T>
constexpr std::array<T, Size> 
make_array_of(const T& value) {
    using Indices = std::make_index_sequence<Size>;
    return make_array_of_impl(value, Indices{});
}

// std::array<int, 4>{42, 42, 42, 42}
constexpr auto test_array = make_array_of<4/*, int*/>(42);
static_assert(test_array[0] == 42);
static_assert(test_array[1] == 42);
static_assert(test_array[2] == 42);
static_assert(test_array[3] == 42);
// static_assert(test_array[4] == 42); out of bounds

당신은 그것을 볼 수 있습니다 직장에서 코드 (Wandbox에서)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top