2010-01-10 3 views
10

나는 선언 할 수배열에 대한 포인터는 언제 유용합니까?

int (*ap)[N];

을 그래서 ap 포인터가 왜 이제까지 유용 크기 N의 배열을 int로 무엇입니까? 함수를 전달하면 배열의 내용에 대한 일반적인 포인터로는 할 수없는 유용한 작업은 무엇입니까?

C 자주 묻는 질문 말 :

2.12

가 : 어떻게 배열에 대한 포인터를 선언 할 수 있습니까?

일반적으로 원하지 않습니다.

+3

INT는 포인터에 대한 포인터는 역시 유용하다. – Toad

+0

나는 C로 프로그래밍해온 25 년이 넘는 기간에 배열에 대한 포인터를 사용하여 코드를 작성할 필요가 없다고 생각합니다. (삼중 포인터 만 사용했습니다. SomeType *** var - 몇 가지 . 시간과는) 곧 내가 할 수있는 그들을 피하기 위해 코드를 변경 –

+1

@reinier : 확실하지만 난 배열에 대한 포인터 아니라 그 – zaharpopov

답변

-3

I을 이 전체 토론에서 결론은 결코다고 생각하십시오. 아무도 여기에서 실제로 뭔가 다른 것이 더 이해하기 쉬운 방식으로 작동하지 않는이 구조에 대한 사용을 시연하지 않았습니다. 코드에 따라

2

정말 유용하지 않습니다. 그러나 때로는 배열에 대한 포인터가 사용됩니다. Microsoft Windows API에서 - 나는이 물건을 많이 보았습니다.

+0

win API에 사용 된 것은 무엇입니까? – zaharpopov

+0

배열 "inurl : msdn.microsoft.com"을 가리키는 포인터를 찾으려면 google을 사용할 수 있습니다. 예 : http://msdn.microsoft.com/en-us/library/ms221359.aspx, http://msdn.microsoft.com/en-us/library/ms714816%28VS.85%29.aspx 등 –

+0

@ adam.wos :이 링크를 보았습니다. C에서 배열에 대한 실제 포인터와 같은 doen'st 모양입니다. 포인터 만 – zaharpopov

6

포인터를 증가 시키면 다음 N 개의 요소 그룹 시작을 가리 킵니다.

이것은 큰 문제가 아니며 개발자의 몫입니다.

+4

어머, 이걸 사용 해본 적이 있니? 사람이 두 사람이 동일하지 않은 것을 알고보고 큰 – bmargulies

+1

=) –

+0

@bmargulies : 나는 각 검사는 16 바이트 MD5 체크섬의 배열을 사용했습니다. –

0

이것은 아마도 그들이 언어로 떨어졌다 때문에 .../주관 논란의 여지가 있지만, 제 생각에는

는, 배열에 대한 포인터는 언어에 속으로 카린됩니다. 선언 가능한 다른 모든 데이터 유형에 대한 포인터가 있으므로 여기도 있습니다. 나는 아무도 자신에게서 정말 유용한 작업을하는 것을 본 적이 없다. 가설 적으로 배열을 요구하는 프로토 타입은 요소에 대한 포인터가 아니지만 ...

+0

...하지만 그들은 (첫 번째 요소에 대한 포인터와 배열에 대한 포인터와 같은) 것입니까? :) –

+0

그들은 같은 위치로 평가되지만 유형은 다르며 유형이 중요합니다. –

-1

배열에 대한 포인터를 작성하는 것은 꽤 쓸모없는 것처럼 보입니다. C에서 배열은 이미 해당 데이터 유형의 블록에 대한 포인터입니다.

int (*ap)[N]; 
int **ipp; 

은 모두 동일한 데이터 유형 (정수에 대한 포인터에 대한 포인터)입니다. 유일한 차이점은 ap에 할당 된 N 개의 정수에 대한 공간이 있다는 것입니다.

이미 포인터이기 때문에 해당 함수 내에서 배열의 내용을 변경하기 위해 함수에 대한 포인터로 배열을 전달할 필요가 없습니다. 일반적으로, 필자는 불필요하다고 말하고, 포인터를 역 참조하여 배열의 데이터를 얻는 추가 필요성을 만듭니다. 하지만, 거기에 합법적 인 사용법을 찾을 수있는 프로그램이나 알고리즘이 있다고 확신합니다.

+1

아니요, 이들은 동일한 데이터 유형이 아닙니다. 그래서 당신은'ipp = ap;'와'ap = ipp;'(포인터가 유용한 곳을 가리키고 있다고 가정)을 할 수 있다고 말하는 것입니까? –

+1

그들은 동일하지 않습니다. '++ ap'와'++ ipp'를 시도해보고 당신이 얻는 것을보십시오. –

+2

배열 **은 ** 포인터가 아닙니다. 배열 * 표현식 *은 대부분의 컨텍스트에서 암시 적으로 포인터 유형으로 변환 될 수 있지만 그 것은 동일하지 않습니다. 당신의 예제에서'ap'와'ipp'는 호환 가능한 타입이 아닙니다; 당신은'ap'의 값을'ipp'에 할당 할 수 없으며 (적어도 명시 적 캐스트가 없으면) 그 반대도 마찬가지입니다. –

2

프로그램간에 메모리 위치를 전달하려는 경우가 있습니다. 예를 들어, Windows API는 데이터 구조 나 배열에 대한 포인터를 다른 언어로 프로그래밍 할 때 (예 : C#) 포인터를 전달할 것으로 기대할 수 있습니다. Windows API는 대상 언어가 배열 API를 처리하는 방법에 신경을 쓰지 않습니다. Windows API의 경우 메모리의 바이트 스트림이며 채워서 다시 보내줍니다. 어떤 경우에는 교차 언어 타입의 missmatch를 피하기 위해 암시 적 배열 이름 대신 포인터를 포인터로 사용합니다. 암묵적인 배열 이름이 긴 포인터라는 것을 보장하지는 않지만, 일부 컴파일러는 그것을 세그먼트로 상대적인 값으로 최적화 할 수 있습니다. 배열에 대한 포인터는 그것이 기계 레지스터 크기의 순서임을 보장하며 사용 가능한 RAM의 어느 위치로든 가리킬 수 있습니다.

+0

이 코드 예제를 사용할 수 있습니까? – zaharpopov

13

배열에 대한 포인터를 사용하여 N-1 차원을 알고있는 다차원 배열 N을 동적으로 할당 할 수 있습니다. 아래는 Nx3 배열을 만듭니다.

int (*ap)[3]; 
ap = malloc(N * sizeof(*ap)); 
/* can now access ap[0][0] - ap[N-1][2] */ 

@Adam E/Cruachan, 이것은 포인터를 가리키는 포인터와 같지 않습니다. ap는 세 개의 연속 된 정수를 포함하는 메모리 블록에 대한 단일 포인터입니다. ap ++는 포인터 주소를 세 정수의 다음 블록으로 올립니다. int **pp;의 경우 pp는 정수 포인터를 가리키며 각 포인터는 메모리의 어느 위치에있는 정수를 가리킬 수 있습니다. 에 대한 그

void foo(int (*a)[N], size_t count) 
{ 
    size_t i; 
    for (i = 0; i < count; i++) 
     a[i][j] = ...; 
    ... 
} 

void bar(void) 
{ 
    int arr[M][N]; 
    foo(arr, M); 
} 

참고 : 일반적으로

  +-----+    +------+ +-----+ 
ap ---> | int | vs. pp ---> | int* | -> | int | 
     | int |    +------+ +-----+ 
     | int |  pp+1 -> | int* | -\ 
     +-----+    +------+ \ +-----+ 
ap+1 -> | int |     : :  -> | int | 
     | int |        +-----+ 
     | int | 
     +-----+ 
      : : 
+0

하지만 아마도 ap는 단지 2 차원 배열입니다. – Pod

+2

예, "int ap [4] [3];"과 동일하지 않습니다. 2 차 차원을 동적으로 할당 할 수 있습니다. –

+0

아, 내가 그럴 경우 내 실수를 인정하고 내 대답을 철회합니다. – Cruachan

2

, 당신은 배열 (T (*a)[N])에 대한 포인터를 볼 수있는 유일한 시간은 2 차원 배열로 의미 a 함수 매개 변수로입니다 함수 매개 변수 선언, int a[][N]int (*a)[N]에 해당하지만,이 기능의 매개 변수 선언에 대한 사실이다 :

void foo (int a[][N], size_t count) {...} 

배열에 대한 포인터는 일반적으로 포인터를 올바르게 선언하기 위해 배열 크기를 알아야하기 때문에 일반적으로 기본 유형에 대한 포인터만큼 유용하지는 않습니다 (int의 10 요소 배열에 대한 포인터는 int의 20 요소 배열에 대한 포인터). 개인적으로, 저는 프로그래밍에 20 년이 넘는 세월 동안 많은 것을 사용하지 못했습니다.

대부분의 컨텍스트에서 배열 식 (예 : arr)은 "N 요소 배열 T"에서 "T 포인터"로 암시 적으로 변환됩니다 (배열식이 피연산자 인 경우 제외). sizeof 또는 &이거나 배열은 선언의 초기화 프로그램으로 사용되는 문자열 리터럴입니다. 이 경우 foo를 호출 할 때 arr의 형식이 암시 적으로 "N 요소 배열의 M 요소 배열"에서 "N 요소 배열의 포인터"로 암시 적으로 변환됩니다.

주어진 선언 T a[M][N] 다음식이 모두 동일한 위치 (배열의 첫 번째 요소의 주소)로 평가되지만, 다음과 같이 종류가 다른 것 :

 
Expression   Type    Implicitly converted to 
----------   ----    ----------------------- 
     a   T [M][N]   T (*)[N] 
     a[0]   T [N]    T * 
     &a   T (*)[M][N]   
    &a[0]   T (*)[N] 
    &a[0][0]   T * 
-1

내 기사의 일부입니다 : C C++에서 포인터와 배열을

당신은 코드가 보여 다음 http://pointersandarrays.blogspot.com/

포인터 및 2D 배열

@를 확인하실 수 있습니다 2D 배열을 선언하고 액세스하는 방법. 2D Array 아래에는 단일 차원 배열이 있습니다. 다음 코드를 사용하여 연주 한 후에이 사실을 확신 할 수 있습니다.

코드 조각 # 4


#include<iostream&rt; 
    using namespace std; 

    int main() 
    { 
    cout<< "Understanding Pointers and 2 D Arrays"<<endl; 
    cout<< "----------------------\n"<<endl; 

    //Declaration of a 2D Array. 
    int tab[3][5]; 
    //Total space required : 3*5 * sizeof(int) = 15 * sizeof(int) 
    //Funda : Since the amount of required space is known by compiler, contiguous 15 memory cells are allocated here.  
    //Hence the case is similar to a 1 D Array of size 15. Lets try this out! 

    //Array initialization using array name 
    for(int i=0; i<3;i++) 
    for(int j=0; j<5;j++) 
     tab[i][j]=i+2*j; 

    //Print array using array name 
    cout << "\nPrint array using array name ..."<<endl;  
    for(int i=0; i<3;i++) 
    { 
     for(int j=0; j<5;j++) 
     printf("%2d ",tab[i][j]); 
     printf("\n"); 
    } 

    //Print array using a pointer. Proof of 1 D array being allocated 
    cout << "\nPrint array using a pointer. Proof of 1 D array being allocated ..." << endl;  
    int *tptr; 
    tptr = &tab[0][0]; // pointer tptr points at first element of the array. 

    for(int i=0; i<15;i++) 
    printf("%d ",*(tptr+i)); 
    tptr = &tab[0][0]; 
    cout << "\nNotice that array is printed row by row in a linear fashion."<<endl; 
    return 0; 
    } 

출력 # 4 :

Understanding Pointers and 2D Arrays 

Print array using array name ... 
0 2 4 6 8 
1 3 5 7 9 
2 4 6 8 10 

Print array using a pointer. Proof of 1 D array being allocated ... 
0 2 4 6 8 1 3 5 7 9 2 4 6 8 10 
Notice that array is printed row by row in a linear fashion. 

관련 문제