2009-03-03 5 views
3

이 예에 대한 포인터들의 어레이를 초기화 잘 작동 :포인터

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

I 볼때 첫 번째 예는 충전 배열을 생성하는 것이다 두 개의 문자열 리터럴 (자체는 배열)에 대한 포인터가 있습니다. 두 번째 예인 IMO는 동일해야합니다. 배열을 만들고 두 char 배열에 대한 포인터로 채 웁니다.

누군가 두 번째 예제가 잘못된 이유를 설명해 줄 수 있습니까?

P. 아마도 다음과 같이 작성할 수 있습니다 (테스트하지 않았습니다) :

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

답변이 4 개 뿐이니까요? 어째서? – Ree

+0

작성자가 삭제했습니다. –

+0

나는 다른 날에 그런 일이 일어났습니다. 그래서 삭제 된 답변을 완전히 설명하는 데 시간이 걸리는 것으로 보입니다. 그것은 "곧"올바른 수를 정착합니다. – RBerteig

답변

3

이를 :

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

그냥 배열 이니셜 라이저입니다. 자체적으로 배열을 생성하지는 않습니다. 첫 번째 예는 포인터에 문자열 리터럴을 할당하면 DID가 정적 저장소 (사용자에게 숨김)에 해당 문자열을 만든 다음 해당 포인터를 할당 한 것입니다.

기본적으로 배열 초기 자로 char *를 초기화 할 수있는 방법이 없습니다. 실제 배열을 만들어 그 배열에 할당해야합니다. 다음과 같이해야합니다 :

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

하지만 그건 불법입니다.

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

+0

Nope. 두 번째 차원을 지정하면 첫 번째는 []로 남을 수 있으므로 example/char a [] [12] = { "hello", "world"}; /는 합법적입니다. –

+0

첫 번째 예제는 완벽하게 합법적입니다. 문자열에 대한 명시적인 포인터를 만들 필요가 없습니다. 그러나 문제는 두 번째 예제입니다. – Ree

+0

첫 번째 예에서는 두 항목을 모두 비워 둘 수 있지만 두 번째 예에서는 비워 두지 않는 이유는 무엇입니까? 문자열 리터럴은 배열이며 두 번째 예제에서도 배열이 있습니까? – Ree

3

시도 :

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] ... 
+0

글쎄, 그것은 주 크기가 13 인 각 요소를 만들 것입니다. 다른 크기의 배열에 대한 포인터를 갖고 싶다면 어떻게해야합니까? 작은 정수 값에는 char - char을 사용할 수 있으므로 여기서는 문제가되지 않습니다. – Ree

+0

두 번째 차원을 지정하면 첫 번째 차원이 이니셜 라이저 목록을 통해 정의됩니다. –

+0

죄송합니다. 귀하의 답변은 저의 초기 의견과 관련이 없습니다. 내가하는 말을하면, "그것은 주 크기 13의 각 요소를 만들 것입니다." 내가 쓴 것은 다른 크기의 배열에 대한 포인터 배열을 초기화하는 것입니다. – Ree

0

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

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

한 가지 구문이 선언 된 형식에 따라 다른 구문을 사용하면 놀랍습니다.

첫 번째 예에서 문자열 리터럴은 배열 값이 아니라 포인터로 평가되므로 값은 포인터의 배열로 평가됩니다. 배열 리터럴은 포인터가 아닌 배열 값으로 평가되기 때문에 두 번째 예제는 다차원 배열입니다. 요소는 배열 값을 가리키는 포인터가 아닌 배열 값이 아닌 배열입니다.

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

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

첫 번째 예제는 작동하지 않습니다. 그것은 할 필요가 :

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

참고 CONST.

편집 : "작동하지 않는다"는 것은 나쁜 습관과 오류가 발생하기 쉽다는 것을 의미합니다.

3

음,이 스레드는 그러나 나는이 같은 문제를 처리하고, 이미 조금 오래되어이 같은 배열에 대한 포인터의 배열을 초기화 할 수있는 방법을 발견 :

#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 

0 
1 1 
40896 32767 -961756724 
0 32767 4198878 0 

그래서 인텔 ICPC 컴파일, 구문의 컴파일 원칙적으로 올바른 것일뿐입니다. 인텔 컴파일러는이 스타일을 일반적으로 사용하지 못하기 때문에이를 지원하지 않습니다. 여기


--- 편집 ---

는 (요구로) 또한 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와 연타와 함께 테스트는 올바른 결과를 출력합니다. Btw. 인텔 컴파일러의 잘못된 출력은 컴파일러 버그였습니다.

+0

좋습니다.하지만 질문은 엄격하게 C와 관련되어 있으므로 (태그 참조), 예제에 C++ 코드가 포함되어 있지 않은 경우 더 좋았을 것입니다. – Ree

+0

정확히 동일하지도 않습니다. 나는 같은 문제를 찾고 있었지만 배열 이름이 필요합니다. –

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