지금 포인터 부분 공부하고있는데,

포인트 배열 파트와, 배열 포인트, 이중포인트 이3가지랑 []연산자 관련해서 질문이 있습니다.

사실상 하나의 '개념'이 이해가 안되서 그러는데,

 저는 c언어를 배우면서 []연산자의 포인터에서의 정의가

p[x]=*(p+x) 로 알고있는데, 즉 예를 들면

int array[3]={1,2,3};

int *p=array; 

/*왜 &연산자를 안쓰나면 배열의 이름은 sizeof함수나 주소연산자&와 같이 쓰이지 않을경우 

배열의 첫번째 주소값이라고 해석되므로, 즉 &(array[0])로 해석된다는 소리

따라서*/

printf("%d",array[1]); 

printf("%d",*(array+1));

printf("%d",*p[1]);

printf("%d",*(p+1));

위 4개다 출력값이 2일것입니다.

여기까지는 충분이 이해되는데, 문제는 포인트배열 ,배열포인트,이중포인트 입니다.;;


제가하나 예를 들어 보겠습니다.

#include

int main() {

    int a[10] = { 1,2,3,4,5,6,7,8,9,10 };

    int* p = a;

    int** pp = &p;

    printf("%p\n", p);

    printf("%p\n", &a);

    printf("%p\n", pp);

    printf("%d", pp[0][3]);

    return 0;

#############

여기서 위에 3개의 출력값은 쉽게 예상되지만 밑에 pp[0][3] 을 해석해보자면

pp[0][3]==*(*(pp+0)+3)==*(*(pp)+3)==*(p+3)==p의 주소값에서 3*4 바이트 만큼 옮겨간 주소가 가리키는 값(왜12바이트냐면 p가int형 변수(4바이트)를 참조하고있으므로) 이므로

맨밑의 출력값은 '4'가 출력되야 합니다. 

그리고 그밖에 pp[1][4],pp[3][4]등등은 이상한 주소의 있는 값을 가리키게 되므로 오류가납니다.

(pp[1][4]을 예로들면 pp[1][4]==*(*(pp+1)+4)인데 이건 정말 의미없는 값인게, 

풀어쓰자면 

"pp란 값의 주소에서 (+1)8바이트만큼 주소를 더해서(왜 8바이트냐면 pp가 *int형인 p를 참조하고 있으므로 64비트 cpu라 가정하면 주소의 크기는 8바이트이므로)그주소가 가리키는 값에다가 (+4)4바이트만큼 더한(마찬가지로 p가 int형을 참조하므로 4바이트)주소가 가리키는 값"인데, 이건 그냥 개소리 가 됩니다.

############


이제 질문 들어가겠습니다.

1.위에 ##########사이에 설명한 내용이 정확한지? 

2. 만약 위에 말이 참이라면,(저가 잘 이해한 것이라면)

#include 

int main()
{    int numArr[3][4] = {    // 세로 3, 가로 4 크기의 int형 2차원 배열 선언        { 11, 22, 33, 44 },        { 55, 66, 77, 88 },        { 99, 110, 121, 132 }    };
    int (*numPtr)[4] = numArr;
    printf("%p\n", *numPtr); // 002BFE5C: 2차원 배열 포인터를 역참조하면 세로 첫 번째의 주소가 나옴                             // 컴퓨터마다, 실행할 때마다 달라짐
    printf("%p\n", *numArr); // 002BFE5C: 2차원 배열을 역참조하면 세로 첫 번째의 주소가 나옴                             // 컴퓨터마다, 실행할 때마다 달라짐
    printf("%d\n", numPtr[2][1]);    // 110: 2차원 배열 포인터는 인덱스로 접근할 수 있음
    printf("%d\n", sizeof(numArr));  // 48: sizeof로 2차원 배열의 크기를 구하면 배열이 메모리에                                      // 차지하는 공간이 출력됨
    printf("%d\n", sizeof(numPtr));  // 4 : sizeof로 2차원 배열 포인터의 크기를                                      // 구하면 포인터의 크기가 출력됨(64비트라면 8)
    return 0;
}

여기서  numPtr[2][1]이걸 1.과 같이 똑같이 해석하자면

numPtr[2][1]==*(*(numPtr+2)+1)인데 이렇게 보기보다는 잘라서보면

numPtr[2][1]==*(numPtr[2]+1)인데 여기서 2차원배열에서, numPtr[2]==&numPtr[2][0]이므로 

numPtr[2][1]==*(numPtr[2]+1)==*(&numPtr[2][0]+1)==numPtr[2][0] 즉,(99)에서 4바이트 다음에있는(110)이 출력된다. 이설명이 맞을까요?


3. 이제 포인트 배열에서

#include
 
int main() {
    int i, j;
    int a[5] = { 1,2,3,4,5 };
    int b[6] = { 10,20,30,40,50,60 };
    int c[7] = { 100,200,300,400,500,600,700 };
    int *pArr[3] = { a,b,c };
   
    printf("%d ", pArr[1][3]);
       
    }
     
}

여기서  pArr[1][3] =*( pArr[1] +3)인데 여기서 pArr[1]은 배열b의 첫번쨰 주소이므로,

pArr[1][3]==*( pArr[1] +3)== b의 주소에서 12바이트만큼이동한 주소의 값을 출력해라 이므로

40이 출력된다.  이 설명이 맞나요?