728x90
728x90
2차원 배열 이름의 포인터 타입

 

1차원 배열 이름의 포인터 타입 결정 포인트

포인터가 가리키는 요소의 자료형**
포인터 연산 시 증가하는 바이트의 크기
- 한 번 읽어들일 때 읽어들일 크기..

 

1차원 배열 이름

배열 이름이 가리키는 요소의 자료형이 일치한다면 포인터연산 시 증가하는 값의 크기도 일치
그래서 1차원배열 이름의 경우 가리키는 요소만 참조했다

 

다차원배열의 포인터 타입 결정 포인트

-2차원배열이라고 생각해서 이해해보자
포인터가 가리키는 요소의 자료형**
포인터 연산 시 증가하는 바이트의 크기

 

2차원 배열 이름

포인터가 가리키는 요소의 자료형이 일치해도 포인터연산 시 증가하는 값의 크기가 불일치
포인터 연산 결과도 생각해야 한다

 

2차원배열의 이름 특성 이해
#include <stdio.h>

int main()
{
    int a[3][2]={1,2,3,4,5,6};
    
    printf("a[0] : %d\n", a[0]);
    printf("a[1] : %d\n", a[1]); // 8바이트 증가
    printf("a[2] : %d\n", a[2]);
    printf("a    : %d\n", a); // a[0]주소값과 같다
    
    return 0;
}

 

 

배열의 이름으로 포인터연산을 해보면 역시 행 단위로 건너뜀을 알 수 있다.

#include <stdio.h>

int main()
{
    int a[3][2]={1,2,3,4,5,6};
    
    printf("a    : %d\n", a); 
    printf("a+1  : %d\n", a+1); 
    printf("a+2  : %d\n", a+2); 
    
    return 0;
}

 

 

결론 1 : 2차원 배열 이름의 특성
a[i] == *(a+i)
// 배열의 이름이든 포인터든
// 몇차원 배열이든 언제나 성립하는 공식

 

a[i] == *(a+i) 
// a+i와 *(a+i) 가 가리키는 영역은 같으나
// 어디까지 가르키는지에 따라 sizeof 연산을 하면 다르다
// a[i]과 *(a+i)는 같은 거 맞다

 

 

** 아래 실행 결과가 강의랑 다름. 확인 필요

#include <stdio.h>

int main()
{
    int a[3][2]={1,2,3,4,5,6};
    
    printf("a    : %d\n", a); 
    printf("a+1  : %d\n", a+1); 
    printf("a+1  : %d\n", sizeof(a+1)); 
    printf("a+1  : %d\n", sizeof(a[1])); 
    printf("a+2  : %d\n", a+2); 
    
    printf("a    : %d\n", *(a+0));
    printf("a+1  : %d\n", *(a+1)); 
    printf("a+1  : %d\n", sizeof(*(a+1))); 
    printf("a+2  : %d\n", *(a+2)); 
    
    return 0;
}

 

결론 2 : 2차원 배열 이름의 특성

2차원배열 이상의 포인터 타입 구성

- 가리키는 대상의 자료형
- 포인터 연산 시 증가하는 바이트의 크기

#include <stdio.h>

int main()
{
    int arr1[3][2];
	
    int arr2[2][3];
    //int (*p)[3]; 포인터를 선언한다면
    
    printf("arr1    : %d\n", arr1); 
    printf("arr1+1  : %d\n", arr1+1);
    printf("arr1+2  : %d\n", arr1+2); 
    
    printf("arr2    : %d\n", arr2); 
    printf("arr2+1  : %d\n", arr2+1);
    printf("arr2+2  : %d\n", arr2+2); 
    
    return 0;
}

 

2차원 배열 이름에 일치하는 포인터 선언
int arr[2][4];
// arr의 포인터타입을 적용해 만든 변수
int(*pArr)[4]; //4블럭 건너뛴다
//포인터 타입은 가리키는 요소가 int형 데이터이고
//포인터 연산 시 증가하는 값의 크기(4), 즉 16바이트에 해당이된다

가리키는 정보 왼쪽, 증가하는 데이터 오른쪽

예제

#include <stdio.h>

void show_data(int (*ptr)[4], int a);

int main()
{
    // 4칸씩 건너뛴다
    int arr1[2][4]={1,2,3,4,5,6,7,8};
    int arr2[3][4]={{1}, {2}, {3}};
    
    show_data(arr1, 2);
    show_data(arr2, 3); 
    
    return 0;
}

void show_data(int (*ptr)[4], int a)
{
    int i, j;
    
    printf("---start print---\n");
    
    for(i=0; i<a; i++) {
        
        for(j=0; j<4; j++) {
            printf("%d", ptr[i][j]);
        }
        
        printf("\n");
    }
    
}

 

매개변수로 선언되는 포인터의 또 다른 표현

매개변수로 선언되었을 때만 두 표현이 같아진다.
가독성 좋으라고 허용하는 표현이다.

// 같은 표현
void show_data(int (*ptr)[4], int a);
void show_data(int ptr[][4], int a);
int arr1[2][4]={1,2,3,4,5,6,7,8};
int (*ptr1)[4]=arr1; //ㅇㅋ
int ptr2[][4]=arr1; //에러 (매개변수가 아닌 지역변수로 선언, 값을 빼먹었다고 생각)

 

int* pArr[4]  vs  int (*pArr)[4] 의 차이점

형태는 괄호에 차이가 있다. 

int* pArr[4]  : pArr은 배열인데 int형 싱글포인터를 요소로 지니는 길이가 4인 배열 (포인터배열)
int (*pArr)[4] : int형 요소를 가리키고 포인터 연산 시 4칸씩 건너뛰는 포인터 (배열포인터)

 

각각 16바이트, 4바이트 할당

 

 

다양한 형태의 배열 요소 접근 방법
#include <stdio.h>

int main()
{
    int a[3][2]={{1,2},{3,4},{5,6}};
    
    printf("a[0]   : %d\n", a[0]);
    printf("*(a+0) : %d\n", *(a+0)); 
    
    printf("a[1]   : %d\n", a[1]); 
    printf("*(a+1) : %d\n", *(a+1)); 
    
    printf("a[2]   : %d\n", a[2]);
    printf("*(a+2) : %d\n", *(a+2)); 
    
    printf("%d, %d\n", a[1][0], (*(a+1))[0]);
    printf("%d, %d\n", a[1][0], *(a[1]+2));
    printf("%d, %d\n", a[1][0], *(*(a+2)+1));
    
    return 0;
}


a[i] == *(a+i)
a[1][0] == (*(a+1))[0]

a[1][2] == *(a[1] + 2)
A = a[1]
A[2] == *(A+2)

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,

v