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다의 수 .char
s.
제가 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개의 배열을 가리키는 포인터들의 배열을 가지고 있습니다.int
s.
언급URL : https://stackoverflow.com/questions/8108416/excess-elements-of-scalar-initializer-for-pointer-to-array-of-ints
'programing' 카테고리의 다른 글
Oracle SQL에서 정규식과 일치하는 문자열의 일부를 가져오는 방법 (0) | 2023.10.07 |
---|---|
안드로이드 9.0(파이)에서 야간 모드가 활성화되어 있는 경우에도 애플리케이션에서 야간 모드를 비활성화하는 방법은 무엇입니까? (0) | 2023.10.07 |
WSO2 ESB5.0.0에서 데이터베이스 및 레지스트리 인덱싱과 관련된 WARN 가져오기 (0) | 2023.10.07 |
div 클릭 시 fireing focus 이벤트 방지 (0) | 2023.10.07 |
NSUserDefaults에 값을 저장하는 데 제한이 있습니까? (0) | 2023.10.07 |