C에 큰 배열이 있습니다 ( 차이가있는 경우 C ++ 이 아님 ). 동일한 값의 모든 멤버를 초기화하고 싶습니다.
나는 이것을 한 번 간단한 방법으로 알고 있다고 맹세 할 수 있었다. memset()
내 경우에는 사용할 수 있지만 C 구문에 내장 된이 작업을 수행 할 수있는 방법이 없습니까?
답변
해당 값이 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”이 반드시 “all-bits-zero”를 의미하는 것은 아니므로, 위를 사용하는 것이 memset ()보다 더 우수하고 이식성이 뛰어납니다. (부동 소수점 값은 +0으로 초기화되고 널값에 대한 포인터 등)
답변
컴파일러가 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...
배열의 크기가 변경되는 경우
답변
위에서 설명한 것처럼 전체 정적 이니셜 라이저를 수행 할 수는 있지만 배열 크기가 변경되면 배열이 커질 때 적절한 초기화 프로그램을 추가하지 않으면 쓰레기가 생길 수 있습니다.
memset은 작업 수행에 대한 런타임 적중을 제공하지만 코드 크기 적중은 배열 크기 변경에 영향을받지 않습니다. 배열이 수십 개의 요소보다 클 때 거의 모든 경우 에이 솔루션을 사용합니다.
배열을 정적으로 선언하는 것이 정말로 중요하다면 프로그램을 작성하여 빌드 프로세스의 일부로 만드는 프로그램을 작성했습니다.