어레이의 모든 멤버를 동일한 값으로 초기화하려면 어떻게 해야 합니까?
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++
initializer가 지정되지 않은 경우 정적 스토리지 기간이 있는 개체가 0으로 초기화됩니다.
static int myArray[10]; // all elements 0
그리고 "0"은 반드시 "모든 비트 제로"를 의미하는 것은 아니기 때문에 위의 것을 사용하는 것이 memset()보다 더 좋고 휴대성이 좋습니다.(부동소수점 값은 +0으로 초기화되며 null 값으로 포인터 등이 됩니다.)
컴파일러가 GCC인 경우 다음 "GNU 확장" 구문을 사용할 수 있습니다.
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) };
매크로명은 네고시에이트 가능합니다.
다음 구문을 사용하는 코드를 발견했습니다.
char* array[] =
{
[0] = "Hello",
[1] = "World"
};
인덱스로 enum을 사용하는 배열을 만드는 경우 특히 유용합니다.
enum
{
ERR_OK,
ERR_FAIL,
ERR_MEMORY
};
#define _ITEM(x) [x] = #x
char* array[] =
{
_ITEM(ERR_OK),
_ITEM(ERR_FAIL),
_ITEM(ERR_MEMORY)
};
이렇게 하면 일부 열거값을 잘못 쓴 경우에도 순서가 유지됩니다.
이 기술에 대한 자세한 내용은 여기와 여기를 참조하십시오.
원래 질문에서 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).
int array [ ]= { [ 0 ...1023] = 5}; 위의 작업은 정상적으로 수행되지만 ...개의 점 사이에 공백이 없어야 합니다.
- 어레이가 정적 또는 전역으로 선언된 경우 어레이의 모든 요소는 이미 기본값 0을 가집니다.
- 일부 컴파일러는 디버깅모드에서 어레이 기본값을 0으로 설정합니다.
- 기본값을 0: int array[10] = {0}으로 설정하는 것은 쉽습니다.
- 단, 다른 값에서는 memset() 또는 loop을 사용합니다.
예: int array [ 10 ]; memset(array,-1, 10 *sizeof(int));
약간 빈정거리는 대답; 진술서를 써라.
array = initial_value
마음에 드는 어레이 대응 언어(저는 Fortran이지만, 그 외 많은 언어)로 C 코드에 링크합니다.외부 기능으로 마무리하는 것이 좋습니다.
0으로 초기화하려면 -
char arr[1000] = { 0 };
0 이외의 초기화에 대해서는, 통상의 「for loop」을 사용하는 것이 좋습니다.
char arr[1000];
for(int i=0; i<arr.size(); i++){
arr[i] = 'A';
}
배열의 모든 멤버가 명시적으로 초기화되도록 하려면 선언에서 차원을 생략하십시오.
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} };
그렇지 않습니다.
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...
어레이의 크기가 변경될 수 있습니다.
는 그 .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;
어레이의 크기를 미리 알고 있는 경우 Boost 프리프로세서 C_ARRAY_INITIALIZE 매크로를 사용하여 지저분한 작업을 수행할 수 있습니다.
#include <boost/preprocessor/repetition/enum.hpp>
#define C_ARRAY_ELEMENT(z, index, name) name[index]
#define C_ARRAY_EXPAND(name,size) BOOST_PP_ENUM(size,C_ARRAY_ELEMENT,name)
#define C_ARRAY_VALUE(z, index, value) value
#define C_ARRAY_INITIALIZE(value,size) BOOST_PP_ENUM(size,C_ARRAY_VALUE,value)
또 다른 방법은 다음과 같습니다.
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 내선번호를 사용할 수 있습니까?
위의 코드 샘플은 임베디드 시스템에 포함되어 있어 다른 컴파일러에서 빛을 볼 수 없습니다.
모든 유형의 배열을 지정된 값으로 빠르게 초기화할 수 있습니다.대규모 어레이에서 매우 잘 작동합니다.알고리즘은 다음과 같습니다.
- 배열의 첫 번째 요소를 초기화합니다(반복 방식).
- 설정되지 않은 부분으로 설정된 복사 부품, 다음 복사 작업을 수행할 때마다 크기가 두 배로 증가합니다.
위해서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;
}
int 배열과 같은 '일반' 데이터 유형을 초기화하는 경우 괄호 표기법을 사용할 수 있지만 배열에 공간이 남아 있으면 마지막 뒤에 값이 0이 됩니다.
// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};
어레이가 int 사이즈 또는 mem-pattern 사이즈를 가진 int 또는 그 어떤 것이 우연히 int에 정확한 시간(즉, 모두 0 또는 0xA5)을 가진 경우A5A5A5)의 가장 좋은 방법은 memset()을 사용하는 것입니다.
그렇지 않으면 인덱스를 이동하는 루프에서 memcpy()를 호출합니다.
위에서 설명한 바와 같이 정적 이니셜라이저 전체를 수행할 수 있지만 어레이 크기가 변경되면 매우 곤란해질 수 있습니다(어레이가 확장되면 적절한 이니셜라이저를 추가하지 않으면 가비지가 됩니다).
memset은 작업을 수행하기 위한 런타임 히트를 제공하지만 올바르게 수행된 코드 크기는 어레이 크기 변경에 영향을 받지 않습니다.어레이가 수십 개의 요소보다 큰 경우에는 거의 모든 경우에 이 솔루션을 사용합니다.
어레이를 정적으로 선언하는 것이 정말 중요한 경우 프로그램을 작성하여 빌드 프로세스의 일부로 만들 수 있습니다.
아무도 초기화된 배열의 요소에 액세스하기 위한 인덱스 순서를 언급하지 않았습니다.나의 예 코드는 그것에 대한 예시를 줄 것이다.
#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;
추가 보너스: 코드를 실제로 읽을 수 있습니다. : )
#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 ......가 됩니다.
질문에는 요건이 없습니다.따라서 해결책은 범용성이 있어야 합니다.즉, 초기 멤버 값을 가진 미지정 가능한 구조 요소에서 구축되는 미지정 가능한 다차원 배열의 초기화입니다.
#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
옛날에는 (좋은 생각이 아니라고 말하는 것은 아니지만) 첫 번째 요소를 설정하고 나서 다음 작업을 수행했습니다.
memcpy (&element [1], &element [0], sizeof (element)-sizeof (element [0]);
(memcpy의 실장에 따라 달라지는) 더 이상 동작할 수 있을지 확신할 수 없지만, 초기 요소를 다음 요소에 반복적으로 복사함으로써 동작합니다.구조 어레이에서도 동작합니다.
방법 1:
int a[5] = {3,3,3,3,3};
정식 초기화 기법.
방법 2:.
int a[100] = {0};
하지만 주의할 필요가 있다
int a[10] = {1};
모든 값이 1로 초기화되지 않음
이 초기화 방법은 0 전용입니다.
그냥 하면
int a[100];
일부 컴파일러는 가비지 값을 취득하는 경향이 있기 때문에 항상 다음과 같이 하는 것이 좋습니다.
int a[1000] = {0};
클레멘스 실라프의 대답의 후속편입니다.이 버전에는 C++17이 필요합니다.
template <size_t Cnt, typename T>
std::array<T, Cnt> make_array_of(const T& v)
{
return []<size_t... Idx>(std::index_sequence<Idx...>, const auto& v)
{
auto identity = [](const auto& v, size_t) { return v; };
return std::array{identity(v, Idx)...};
}
(std::make_index_sequence<Cnt>{}, v);
}
여기서 볼 수 있습니다.
언급URL : https://stackoverflow.com/questions/201101/how-to-initialize-all-members-of-an-array-to-the-same-value
'programing' 카테고리의 다른 글
변수를 전달하여 Vuex 상태 데이터 가져오기 (0) | 2022.07.05 |
---|---|
내보내기 Const에서 Vue 인스턴스 액세스 (0) | 2022.07.05 |
Vue-CLI로 만든 앱으로 404 페이지 제공 (0) | 2022.07.03 |
atoi : 0과 에러의 차이를 식별하는 방법 (0) | 2022.07.03 |
사용자를 다른 페이지로 보내는 것을 중지하려면 어떻게 해야 합니까? (0) | 2022.07.03 |