본문 바로가기
  • 문과생의 백엔드 개발자 성장기
|Developer_Study/정보처리기사

[정보처리기사] C언어 포인터, 배열포인터, 포인터 배열

by 케리's 2023. 2. 28.

1. 포인터란?

메모리의 위치를 표현한 기호

즉, 메모리 주소를 저장하는 변수 

int *a; // a는 정수형 변수의 주소를 가리킬 수 있다.
*a = 10;
// a의 주소가 100번지라고할때
print("%d", a); 
print("%d", *a);
// 100
// 10

 

 

2. 배열포인터 란?

  • 배열의 시작 주소값을 저장할 수 있는 포인터
  • 배열을 가리키는 포인터
  • 그냥 하나의 포인터일 뿐이다.
  • 2차원 이상의 배열을 가리킬때 포인터를 통해 배열과 같은 인데싱을 할 수 있기 때문에 유용하게 사용
  •  문법 : int (*pa)[3] 라고 선언하면 pa는 3개의 정수형 원소를 가진 배열의 주소를 가리킬 수 있다.

 

1) 1차원 배열포인터

(1) 예제 1

// (1) 정수형 배열의 크기와 포인터 배열의 크기가 같을 경우 - 주소는 100부터 시작한다고 가정한다.

int arr[3] = {1, 2, 3}; //정수형 배열 선언
int (*pa)[3]; // 정수형 배열을 가리키는 포인터 선언 = '배열포인터'
pa = &arr; // arr 배열의 메모리 주소로 초기화된다. pa = arr로 넣어도됨.

printf("%d\n", arr); // arr의 대표 주소번지(= 첫번째 요소의 메모리 주소) 100 출력
printf("%d\n", pa); // pa에 있는 주소값 100 출력
printf("%d\n", *pa); //pa의 값은 pa의 대표주소인 100을 출력
printf("%d\n", **pa); // pa의 값의 값은 1을 출력
printf("%d\n", *(*pa+1)); // *pa에 + 1은 101, 101의 값은 2 출력
printf("%d\n", *pa[0]); // pa가 가리키는 배열의 첫 번째 원소에 대한 참조 연산자! 즉, arr[0]과 같습니다. 따라서 이 문장은 1을 출력
printf("%d\n", *pa[1]); // 가비지값 출력 
// 이유 :  *pa[1] 는 pa가 가리키는 배열의 두 번째 원소에 대한 참조 연산자가 아니라 
//         pa가 가리키는 배열의 주소에 3를 더한 곳에 대한 참조 연산자이다. 
//         즉, arr + 4와 같다. 그런데 arr + 3는 arr의 범위를 벗어난 곳이므로 가비지 값이 나온다.
// 따라서 포인터에서 인덱싱을 하기 위해 아래와 같이 (*pa)처럼 괄호 처리를 해서 사용해야한다.
printf("%d\n", (*pa)[0]); // pa가 가리키는 배열 arr의 첫번째 원소 1출력
printf("%d\n", (*pa)[1]); // pa가 가리키는 배열 arr의 두번째 원소 2출력

(2) 예제 2

// (1) 정수형 배열의 크기와 포인터 배열의 크기가 같을 경우 - 주소는 100부터 시작한다고 가정한다.

int arr[3] = {1, 2, 3}; //정수형 배열 선언
int (*pa)[2]; // 정수형 배열을 가리키는 포인터 선언 = '배열포인터'
			  // 포인터 배열을 논리적으로 2로 쪼개라
pa = &arr; // arr 배열의 메모리 주소로 초기화된다. pa = arr로 넣어도됨.


printf("%d\n", *pa[0]); // pa가 가리키는 배열의 첫 번째 원소에 대한 참조 연산자! 즉, arr[0]과 같다. 따라서 이 문장은 1을 출력
printf("%d\n", *pa[1]); // 3 출력
// 이유 :  *pa[1] 는 pa가 가리키는 배열의 두 번째 원소에 대한 참조 연산자가 아니라 
//         pa가 가리키는 배열의 주소에 2를 더한 곳에 대한 참조 연산자이다. 
//         즉, arr + 2와 같다. arr 두번째의 대표 값인 3 출력
// 따라서 포인터에서 인덱싱을 하기 위해 아래와 같이 (*pa)처럼 괄호 처리를 해서 사용해야한다.
printf("%d\n", (*pa)[0]); // pa가 가리키는 배열 arr의 첫번째 원소 1출력
printf("%d\n", (*pa)[1]); // pa가 가리키는 배열 arr의 두번째 원소 2출력
printf("%d\n", (*pa)[2]); // pa가 가리키는 배열 arr의 두번째 원소 3출력
printf("%d\n", *(*pa+1)); // *pa에 + 1은 101, 101의 값은 2 출력
printf("%d\n", **(pa+1)); // pa는 pa[0]과 같음 거기에 + 1은 pa[1], pa[1] 값은 3 출력

 

 

2) 2차원 배열포인터

// (2)  주소는 100부터 시작한다고 가정한다.

int arr[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; //정수형 3행4열 배열 선언
int (*pa)[4]; // 정수형 배열을 가리키는 포인터 선언 = '배열포인터'
			  // 포인터 배열을 논리적으로 4로 쪼개라
pa = &arr; // arr 배열의 메모리 주소로 초기화된다. pa = arr로 넣어도됨.

printf("%d\n", pa); //100값 출력
printf("%d\n", *pa); //100값 출력
printf("%d\n", **pa); //1출력
printf("%d\n", *pa[1]); //5출력
printf("%d\n", *pa[2]); //9출력
printf("%d\n", pa[0][0]); //1출력
printf("%d\n", pa[1][2]); //7출력
printf("%d\n", pa[2][3]); //12출력

 

3. 포인터배열이란?

  • 배열의 요소가 포인터(메모리주소)로 이루어진 것
  • 포인터 변수를 저장할 수 있는 배열
  •  문법 : char *arr[5]라고 선언하면 5개의 char형 포인터를 저장할 수 있는 배열이 된다. 각각 arr[i]는 문자열의 주소를 가르킨다.

#include <stdio.h>

int main()
{
    static char *c[] = {"a","b","c"};
    printf("%s", *(c+1)); // b 출력
    return 0;
}

(1) 예제 1

#include <stdio.h>

int main()
{
    char *arr1[2] = {"Good morning", "C language"};
    printf("%s\n", arr1[0]); // Good morning
    printf("%s\n", arr1[0]+5); // morning
    printf("%c\n", *(arr1[1])); // C
    printf("%c\n", *(arr1[1]+6)); // u
}

댓글