문제

이 예제는 잘 작동합니다.

static char *daytab[] = {
    "hello",
    "world"
};

이것은 다음과 같습니다.

static char *daytab[] = {
    {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}
};

내가 보는 방식은 첫 번째 예제가 두 개의 문자열 리터럴 (배열)에 포인터로 채워진 배열을 만듭니다. 두 번째 예제 인 IMO는 동일해야합니다. 배열을 만들고 두 숯 배열로 포인터로 채 웁니다.

누군가 나에게 두 번째 예가 왜 잘못되었는지 설명 할 수 있습니까?

추신 : 아마도 이것처럼 쓸 수있을 것입니다 (테스트하지 않았습니다).

static char a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static char b[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static char *daytab[] = {
    a,
    b
};

그러나 그것은 너무 많은 일처럼 보인다 :).

도움이 되었습니까?

해결책

이것:

{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

배열 이니셜 라이저 일뿐입니다. 자체가 배열을 만들지 않습니다. 첫 번째 예, 문자열 리터럴을 포인터에 할당했을 때 정적 저장소에 문자열을 만들었고 (숨겨진) 포인터를 할당했습니다.

따라서 기본적으로 배열 이니셜 라이저로 Char*를 초기화 할 방법이 없습니다. 실제 배열을 만들고 해당 숫자를 할당해야합니다. 당신은 다음과 같은 일을해야합니다.

char a[][] = { {32, 30, 0}, {34, 32, 33, 0} }; // illegal

그러나 그것은 불법입니다.

배열을 별도로 빌드하고 마지막 예제와 같은 배열에 할당해야합니다.

다른 팁

노력하다:

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}
};

그것들은 char*의 것이 아닙니다. 그들은 또한 문자가 아닙니다. 당신은 아마 원할 것입니다 :

static int daytab[][13] ...

글쎄,이 스레드는 이미 조금 낡았지만 같은 문제를 다루고 있었고 다음과 같이 배열로 다양한 포인터를 초기화하는 방법을 찾았습니다.

#include <iostream>
using namespace std;

int *a[] = {
  (int[]) { 0 } ,
  (int[]) { 1 , 2 } ,
  (int[]) { 3 , 4 , 5 } ,
  (int[]) { 6 , 7 , 8 , 9 }
};

main()
{
  cout
  << a[0][0] << endl
  << a[1][0] << " " << a[1][1] << endl
  << a[2][0] << " " << a[2][1] << " " << a[2][2] << endl
  << a[3][0] << " " << a[3][1] << " " << a[3][2] << " " << a[3][3] << endl;
}

그리고 GNU G ++로 컴파일하는 출력을 얻습니다.

0
1 2
3 4 5
6 7 8 9

및 Intel ICPC로 컴파일

0
1 1
40896 32767 -961756724
0 32767 4198878 0

따라서 구문은 원칙적으로 올바른 것 같습니다. 인텔 컴파일러는 아마도이 스타일의 일반적인 사용이 없기 때문에 그것을 지원하지 않습니다.


--- 편집하다 ---

다음은 C 버전도 있습니다 (요구대로).

#include <stdio.h>

int *a[] = { 
  (int[]) { 0 } , 
  (int[]) { 1 , 2 } , 
  (int[]) { 3 , 4 , 5 } , 
  (int[]) { 6 , 7 , 8 , 9 } 
};

int main()
{
  printf( "%d\n" , a[0][0] );
  printf( "%d %d\n" , a[1][0] , a[1][1] );
  printf( "%d %d %d\n" , a[2][0] , a[2][1] , a[2][2] );
  printf( "%d %d %d %d\n" , a[3][0] , a[3][1] , a[3][2] , a[3][3] );
}

GCC와 Clang으로 테스트했으며 올바른 결과를 인쇄했습니다. BTW. 인텔 컴파일러의 잘못된 출력은 컴파일러 버그였습니다.

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

두 번째 예제의 구문은 다차원 배열 리터럴의 구문입니다.

다차원 배열은 배열에 대한 다양한 포인터가 아닙니다.

한 가지에 대한 구문이 선언 된 유형에 따라 다른 것에 대한 구문이라면 놀랍습니다.

첫 번째 예에서, 문자열 문자가 배열 값이 아닌 포인터로 평가되기 때문에 값은 포인터의 배열로 평가됩니다. 배열 문자가 포인터가 아닌 배열 값으로 평가되기 때문에 두 번째 예제는 다차원 배열입니다. 요소가 배열 값인 배열이 아닌 배열은 배열 값에 대한 배열이 아닙니다.

다음 코드는 다차원 배열, 배열 포인터, 포인터 배열 및 포인터의 포인터 조합을 보여줍니다. 이 세 가지 중 포인터에 대한 포인터와 포인터만이 서로 호환됩니다.

void multi_array (int x[][4], size_t len) // multidimensional array
{
    for (size_t i = 0; i < len; ++i)
        for (size_t j = 0; j < 4; ++j)
            putchar( 'a' + x[i][j] );
    putchar('\n');
}

void ptr_array (int (*x)[4], size_t len) // pointer to an array
{ ... as multi_array  }

void array_ptr (int *x[], size_t len) // array of pointers
{ ... as multi_array  }

void ptr_ptr (int **x, size_t len) // pointer to pointer
{ ... as multi_array  }

int main() {
    int a[][4] = { { 1,2,3,4 } };
    int b[] = { 1,2,3,4 };
    int* c[] = { b };

    multi_array( a, 1 );
    multi_array( (int[][4]) { { 1,2,3,4} }, 1 ); // literal syntax as value
    ptr_array( &b, 1 );
    array_ptr( c, 1 );
    ptr_ptr( c, 1 ); // only last two are the same

    return 0;
}

첫 번째 예제도 작동하지 않습니다. 그것은 다음과 같아야합니다.

static const char *daytab[] = {
    "hello",
    "world"
};

참고 Const.

편집 : 그리고 "작동하지 않는다"에 의해, 나는 나쁜 연습과 오류가 발생하기 쉬운 것을 의미합니다.

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