[C언어 스터디 - 03] 배열과 포인터 (array and pointer)

2020. 6. 23. 11:0003. Resources/C, C++

728x90
반응형

포인터와 배열 응용하기

참고 문헌 (Ch38) : https://dojang.io/mod/page/view.php?id=316

생각의 시작

크기가 고정된 배열을 사용 => 크기가 변할 수 있는 배열을 어떻게 선언할 수 있는지에 대한 고민에서 출발하는 일!

C언어에서 배열을 선언: 고정 크기의 배열 선언

int numArr[10]
// 10 : 고정크기 => 10개의 요소를 가지는 배열

직관적으로 가변 길이 배열 선언해보기

#define _CRT_SECURE_NO_WARNING
#include <stdio.h>

int main()
{
    int size;

    scanf("%d", &size);  // 배열의 크기를 입력받음

    int numArr[size];    // GCC에서는 사용 가능, Visual Studio 2015에서는 컴파일 에러

    return 0;
}

컴파일러마다 다르지만, VS2015의 경우 컴파일 에러가 발생한다고 한다
=> 동적으로 지정하기 위해서는 포인터를 선언하고, 메모리를 할당한 뒤 메모리를 배열처렁 사용해야한다!


포인터에 할당된 메모리를 배열처럼 사용하기

포인터를 배열처럼 사용하는 방법: 포인터에 malloc 함수로 메모리를 할당하여 사용하기!
malloc: dynamic memory allocation 방법. 메모리를 필요할 때 할당하여 사용, 다 쓴 메모리는 free를 통해 반드시 해제해줘야함!
malloc을 이용하기 위해서는 stdlib을 추가해줘야한다!

할당하는 방법: (자료형) (*포인터이름) = malloc(sizeof(자료형) * 크기);

#include <stdio.h>
#include <stdlib.h>    // malloc, free 함수가 선언된 헤더 파일

int main()
{
    int *numPtr = malloc(sizeof(int) * 10);    // int 10개 크기만큼 동적 메모리 할당

    numPtr[0] = 10;    // 배열처럼 인덱스로 접근하여 값 할당
    numPtr[9] = 20;    // 배열처럼 인덱스로 접근하여 값 할당

    printf("%d\n", numPtr[0]);    // 배열처럼 인덱스로 접근하여 값 출력
    printf("%d\n", numPtr[9]);    // 배열처럼 인덱스로 접근하여 값 출력

    free(numPtr);    // 동적으로 할당한 메모리 해제 => 해제하지 않으면 계속 잡혀있음

    return 0;
}

입력한 크기만큼 메모리를 할당하여 배열처럼 사용하기

#include <stdio.h>
#include <stdlib.h>    // malloc, free 함수가 선언된 헤더 파일

int main()
{
    int size;

    scanf("%d", &size);

    int *numPtr = malloc(sizeof(int) * size);    // (int 크기 * 입력받은 크기)만큼 동적 메모리 할당

    for (int i = 0; i < size; i++)    // 입력받은 크기만큼 반복
    {
        numPtr[i] = i;                // 인덱스로 접근하여 값 할당
    }

    for (int i = 0; i < size; i++)    // 입력받은 크기만큼 반복
    {
        printf("%d\n", numPtr[i]);    // 인덱스로 접근하여 값 출력
    }

    free(numPtr);    // 동적으로 할당한 메모리 해제

    return 0;
}

포인터에 할당된 메모리를 2차원 배열처럼 사용하기

할당하는 방법: (자료형) (*포인터이름) = malloc(sizeof(자료형\) x 세로크기 를 이용하여 행 공간 메모리 할당 -> 행의 크기만큼 반복하면서 ((포인터)[i]) = malloc(sizeof(자료형) x 가로크기) 를 이용하여 열 공간 메모리 할당

해제하는 방법: 행 크기만큼 반복하면서 free(포인터[i]); 와 같이 열 공간 메모리 해제 -> free((포인터)); 로 행 공간 메모리 해제

#include <stdio.h>
#include <stdlib.h>    // malloc, free 함수가 선언된 헤더 파일

int main()
{
    int **m = malloc(sizeof(int *) * 3);   // 이중 포인터에 (int 포인터 크기 * 행 크기)만큼
                                           // 동적 메모리 할당. 배열의 행

    for (int i = 0; i < 3; i++)            // 행 크기만큼 반복
    {
        m[i] = malloc(sizeof(int) * 4);    // (int 크기 * 열 크기)만큼 동적 메모리 할당.
                                           // 배열의 열
    }

    m[0][0] = 1;    // 행 인덱스 0, 열 인덱스 0인 요소에 값 할당
    m[2][0] = 5;    // 행 인덱스 2, 열 인덱스 0인 요소에 값 할당
    m[2][3] = 2;    // 행 인덱스 2, 열 인덱스 3인 요소에 값 할당

    printf("%d\n", m[0][0]);    // 1: 행 인덱스 0, 열 인덱스 0인 요소의 값 출력
    printf("%d\n", m[2][0]);    // 5: 행 인덱스 2, 열 인덱스 0인 요소의 값 출력
    printf("%d\n", m[2][3]);    // 2: 행 인덱스 2, 열 인덱스 3인 요소의 값 출력

    for (int i = 0; i < 3; i++)    // 행 크기만큼 반복
    {
        free(m[i]);                // 2차원 배열의 열 공간 메모리 해제
    }

    free(m);    // 2차원 배열의 행 공간 메모리 해제

    return 0;
}

입력한 크기만큼 메모리를 할당하여 포인터를 2차원 배열처럼 사용하기

#include <stdio.h>
#include <stdlib.h>    // malloc, free 함수가 선언된 헤더 파일

int main()
{
    int row, col;

    scanf("%d %d", &row, &col);

    // 2차원 배열 선언 시작
    int **m = malloc(sizeof(int *) * row);   // 이중 포인터에 (int 포인터 크기 * row)만큼
                                             // 동적 메모리 할당. 배열의 행

    for (int i = 0; i < row; i++)            // 세로 크기만큼 반복
    {
        m[i] = malloc(sizeof(int) * col);    // (int의 크기 * col)만큼 동적 메모리 할당. 배열의 열
    }
    // 2차원 배열 선언 끝

    // 2차원 배열에 값 할당 시작
    for (int i = 0; i < row; i++)    // 행 크기만큼 반복
    {
        for (int j = 0; j < col; j++)    // 열 크기만큼 반복
        {
            m[i][j] = i + j;             // 2차원 배열의 각 요소에 i + j 값을 할당
        }
    }
    // 2차원 배열에 값 할당 끝

    for (int i = 0; i < row; i++)    // 행 크기만큼 반복
    {
        for (int j = 0; j < col; j++)    // 열 크기만큼 반복
        {
            printf("%d ", m[i][j]);      // 2차원 배열의 인덱스에 반복문의 변수 i, j를 지정
        }
        printf("\n");                // 가로 요소를 출력한 뒤 다음 줄로 넘어감
    }

    // 2차원 배열 메모리 해제 시작
    for (int i = 0; i < row; i++)    // 행 크기만큼 반복
    {
        free(m[i]);                  // 2차원 배열의 열 공간 메모리 해제
    }

    free(m);    // 2차원 배열의 행 공간 메모리 해제
    // 2차원 배열 메모리 해제 끝

    return 0;
}
반응형