programing

int 배열에 대한 포인터에 대한 스칼라 이니셜라이저의 초과 요소

telecom 2023. 10. 7. 09:25
반응형

int 배열에 대한 포인터에 대한 스칼라 이니셜라이저의 초과 요소

K&R(예: 5-9)에서 연습을 하고 있는데 원래 프로그램의 2D 배열을 변환하려고 했습니다.

static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

13개의 int 배열에 포인터를 사용하는 것처럼.

static char (*daytab)[13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

그러나 컴파일러는 경고: 스칼라 이니셜라이저초과 요소를 인쇄합니다.

구글링은 도움이 되지 않았고 심지어 K&R이 배열을 함수에 전달할 때 쓰기도 했습니다.

myFunction(int daytab[2][13]) {...}

와 같음

myFunction(int (*daytab)[13]) {...}

그 둘은 단지 부분적으로 동치입니다.차이점은 다음과 같습니다.

static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

을 선언합니다. 여기에는 배열을 위한 공간을 확보하고 다음을 보장하는 것이 포함됩니다.daytab그 기억을 참조합니다.단,

static char (*daytab)[13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

...포인터만 선언합니다.따라서 배열 초기화기로 포인터를 초기화하려고 하지만 예상대로 작동하지 않습니다.배열이 없습니다. 배열에 별도로 저장된 메모리가 없습니다.대신 이니셜라이저의 첫 번째 번호가 포인터에 할당됩니다.daytab, 컴파일러는 경고를 생성하여 방금 폐기된 수많은 추가 값을 지정했음을 알려줍니다.이니셜라이저의 첫 번째 숫자는0, 당신은 그냥 설정하고 있습니다.daytab로.NULL장황하게

따라서 이러한 초기화를 수행하려면 첫 번째 버전을 사용합니다. 두 번째 버전에서 명시적으로 선언한 것과 동일한 포인터 유형으로 손상되므로 동일한 방식으로 사용할 수 있습니다.배열 포인터를 사용하는 두 번째 버전은 배열을 동적으로 할당하거나 이미 존재하는 다른 배열에 대한 참조를 가져올 때 필요합니다.

따라서 다음을 수행할 수 있습니다.

static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;

ptr = arr;

...그리고 나서 사용ptr그리고.arr번갈아 가며또는 이것:

static char (*ptr)[3] = NULL;

ptr = malloc(2 * sizeof(*ptr));

...다이나믹하게 할당된 2차원 배열을 얻을 수 있습니다(1D 배열에 대한 포인터 배열이 아니라 실제 2D 배열).물론 그런 경우에는 초기화되어 있지 않습니다.

두 변형의 "동등성"은 2D 배열이 첫 번째 요소의 포인터로 붕괴될 때 두 번째 변형에서 선언된 포인터의 유형으로 붕괴된다는 것을 의미합니다.포인터 버전이 실제로 배열을 가리키면 이 둘은 동등합니다.그러나 2D 배열 버전은 배열에 대한 메모리를 설정합니다. 여기서 포인터 선언은...포인터에 2D 배열 변수가 지정할 수 없는 새 값(다른 배열을 가리킴)을 할당할 수 있습니다.

C99에서는 이를 수행할 수 있지만 그렇지 않을 경우static적어도):

char (*daytab)[13] = (char [][13]){
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

@Dmitri가 잘 설명해주었지만, 저는 그것을 덧붙이고 싶었습니다.

static char (*daytab)[13] = { ... };

13개의 배열을 가리키는 하나의 포인터입니다.char요소들.컴파일러는 당신이 두 개의 배열로 통과했기 때문에 당신에게 경고를 줍니다.하나의 포인터에 두 개의 주소를 할당하려는 것과 같습니다.char *p = {a, b}. 당신의 선언에 필요 이상의 요소들이 있습니다.배열 포인터가 실제로 무엇을 의미하는지에 대한 Geekforgeek의 설명을 참조하십시오.

K&R 연습에 대한 답변은 다음을 고려합니다.

옵션 1:

static char *daytab[2] = { 
    (char []) {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    (char []) {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };} 

또는 옵션 2:

static char (*daytab)[13] = (char [][13]) { 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };} 

두 개의 1 입니다 2 의 입니다.char지시 사항들

옵션 2는 배열 포인터 하나입니다.13개의 배열을 가리키고 있습니다.char요소들.당신이 a를 증가시킬 수 있는 것처럼char이 시켜 13다의 수 .chars.

제가 K&R에서 이 문제를 해결했기 때문에 이미 제시된 정말 좋은 답변을 추가할 수 있을 것 같습니다.이것은 2-D 배열을 사용하는 것에서 벗어나 포인터 배열을 사용하는 데 좋은 연습입니다.현하십시오에 .malloc한 은 월 다음 을 설정하는 따라서 한 가지 방법은 월 어레이를 미리 설정한 다음 해당 어레이에 대한 포인터 배열을 설정하는 것입니다.

char y0[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
char y1[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
char *daytab[] = {y0, y1};

배열의 이름은 첫번째 요소를 가리키는 포인터임을 기억합니다.이제 당신은 정말로 두 개의 13개의 배열을 가리키는 포인터들의 배열을 가지고 있습니다.ints.

언급URL : https://stackoverflow.com/questions/8108416/excess-elements-of-scalar-initializer-for-pointer-to-array-of-ints

반응형