본문 바로가기
GD's IT Lectures : 기초부터 시리즈/C, C++ 기초부터 ~

[C/C++ 프로그래밍] 9. 배열

by GDNGY 2023. 5. 16.

Chapter 9. 배열

배열의 개념, 선언, 초기화 및 사용법을 배웁니다. 인덱스와 반복문을 사용하여 배열을 효율적으로 처리하는 방법, 다차원 배열, 함수와 배열의 관계, 그리고 문자 및 동적 배열에 대해 배우게 됩니다. 또한, 배열을 사용한 실제 프로그램 예제와 고급 주제인 배열과 포인터, 메모리에 대해 공부합니다. 이 장을 통해 배열의 중요성과 다양한 활용법을 이해하게 됩니다.

 


 

반응형

 


Chapter 9. 배열


9.1. 배열의 개념

9.1.1. 배열이란?

9.1.2. 배열의 필요성

 

9.2. 배열의 선언과 초기화

9.2.1. 배열 선언하기

9.2.2. 배열 초기화하기

 

9.3. 배열의 사용

9.3.1. 인덱스를 이용한 배열 접근

9.3.2. 반복문을 이용한 배열 처리

 

9.4. 다차원 배열

9.4.1. 2차원 배열

9.4.2. 3차원 배열 이상

 

9.5. 배열과 함수

9.5.1. 배열을 인자로 받는 함수

9.5.2. 함수가 배열을 반환하기

 

9.6. 문자 배열

9.6.1. 문자 배열의 선언과 초기화

9.6.2. 문자열 관련 함수

 

9.7. 동적 배열 (C++ only)

9.7.1. new와 delete 연산자

9.7.2. 동적 배열의 사용

 

9.8. 배열을 사용한 프로그램 예제

9.8.1. 성적 계산기 프로그램 작성

9.8.2. 행렬 연산 프로그램 작성

 

9.9. 배열에 대한 고급 주제

9.9.1. 배열과 포인터

9.9.2. 배열과 메모리

 


9.1. 배열의 개념

배열이란 같은 타입의 여러 변수를 한 번에 선언할 수 있는 자료 구조를 의미합니다. 이 섹션에서는 배열의 정의와 그 필요성에 대해 설명합니다.

9.1.1. 배열이란?

배열이란 같은 타입의 여러 변수를 하나의 이름으로 묶어 처리하는 데이터 구조입니다. 배열은 하나의 이름 아래에 연속적으로 저장되며, 각각의 변수는 인덱스 번호로 접근할 수 있습니다.

 

예를 들어, 학생 30명의 성적을 저장하려면 각각 다른 변수를 선언해야 합니다. 그러나 배열을 사용하면 한 번에 30개의 성적을 저장하는 변수를 만들 수 있습니다.

 

C 언어에서 배열 선언의 기본적인 형태는 다음과 같습니다.

 

[예제] : C

int scores[30]; // 30명의 학생 성적을 저장할 수 있는 배열
C++에서도 같은 형식으로 선언할 수 있습니다.

 

[예제] : C++

int scores[30]; // 30명의 학생 성적을 저장할 수 있는 배열

 

9.1.2. 배열의 필요성

배열을 사용하면 같은 타입의 여러 데이터를 하나의 이름으로 쉽게 다룰 수 있습니다. 특히 반복적인 작업을 처리할 때 유용합니다. 예를 들어, 학생들의 성적을 관리하거나 이미지의 픽셀 정보를 처리할 때 배열을 사용하면 훨씬 효율적입니다.

 

배열 없이 학생들의 성적을 관리한다면, 학생 수만큼의 변수를 선언하고 각각 관리해야 합니다. 그러나 배열을 사용하면, 하나의 변수로 학생들의 성적을 관리할 수 있습니다. 그리고 배열의 인덱스를 이용해 특정 학생의 성적에 접근할 수 있습니다.

 

또한, 반복문과 함께 사용하면 배열의 모든 요소를 쉽게 접근하고 조작할 수 있습니다. 아래는 배열과 반복문을 이용해 30명의 학생 성적을 출력하는 예제입니다.

 

[예제] : C

int scores[30]; 
// 배열 초기화 및 값 할당 생략

for(int i = 0; i < 30; i++) {
    printf("학생 %d의 성적: %d\n", i+1, scores[i]);
}

 

[예제] : C++

int scores[30];
// 배열 초기화 및 값 할당 생략

for(int i = 0; i < 30; i++) {
    std::cout << "학생 " << i+1 << "의 성적: " << scores[i] << std::endl;
}

 

요약하자면, 배열은 같은 타입의 데이터를 효율적으로 관리하고, 코드의 가독성을 높이며, 반복 작업을 간편하게 처리할 수 있게 해주는 중요한 도구입니다.

 


9.2. 배열의 선언과 초기화

배열은 특정한 크기와 타입을 가진 요소의 집합이며, 선언과 동시에 초기화를 진행할 수 있습니다. 이 섹션에서는 배열의 선언 및 초기화 방법에 대해 학습합니다.

9.2.1. 배열 선언하기

배열을 선언하려면 먼저 배열의 타입을 지정한 다음 배열의 이름과 크기를 지정합니다. 배열의 크기는 배열이 저장할 수 있는 요소의 수를 나타냅니다. 다음은 C와 C++에서 배열을 선언하는 방법입니다.

 

[예제]

int arr[5]; // 정수를 저장할 수 있는 크기 5의 배열 선언

 

배열의 이름은 변수 이름과 동일한 규칙을 따릅니다. 배열의 크기는 상수 표현식이어야 하며, 0보다 큰 값이어야 합니다.

 

9.2.2. 배열 초기화하기

배열을 초기화하는 방법은 여러 가지가 있습니다. 첫 번째 방법은 배열을 선언할 때 함께 초기화하는 것입니다. 이 경우, 배열의 크기는 초기화하는 값의 수로 자동 설정됩니다.

[예제]

int arr[] = {1, 2, 3, 4, 5}; // 크기 5의 배열 선언과 동시에 초기화

 

두 번째 방법은 배열을 선언한 후 개별적으로 초기화하는 것입니다. 이 경우, 배열의 각 요소에 값을 할당해야 합니다.

[예제]

int arr[5];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5; // 배열의 각 요소를 개별적으로 초기화

 

이처럼, 배열을 선언하고 초기화하는 방법은 다양하므로, 자신의 코드에 가장 적합한 방법을 선택해 사용하면 됩니다.

 


9.3. 배열의 사용

이 섹션에서는 배열의 사용 방법, 특히 인덱스를 이용한 배열 요소의 접근과 반복문을 이용한 배열 처리 방법에 대해 설명합니다.


9.3.1. 인덱스를 이용한 배열 접근

 

배열의 요소에 접근하려면 인덱스를 사용합니다. 인덱스는 배열 요소의 위치를 나타내며, 0부터 시작합니다. 배열 이름 뒤에 대괄호([]) 안에 인덱스를 넣어 배열 요소에 접근할 수 있습니다.

 

[예제] : C

int arr[5] = {1, 2, 3, 4, 5};
printf("%d\n", arr[0]); // 배열의 첫 번째 요소 출력

 

[예제] : C++

int arr[5] = {1, 2, 3, 4, 5};
std::cout << arr[0] << std::endl; // 배열의 첫 번째 요소 출력

 

배열의 크기를 넘어서는 인덱스를 사용하면 예상치 못한 결과를 가져올 수 있으므로 주의해야 합니다.

 

9.3.2. 반복문을 이용한 배열 처리

배열의 모든 요소에 접근하려면 반복문을 사용하는 것이 효율적입니다. for 또는 while 반복문을 사용하여 인덱스를 증가시키면서 배열의 각 요소에 접근할 수 있습니다.

 

[예제] : C

int arr[5] = {1, 2, 3, 4, 5};
for(int i = 0; i < 5; i++) {
    printf("%d\n", arr[i]); // 배열의 각 요소 출력
}

 

[예제] : C++

int arr[5] = {1, 2, 3, 4, 5};
for(int i = 0; i < 5; i++) {
    std::cout << arr[i] << std::endl; // 배열의 각 요소 출력
}

 

C++에서는 범위 기반 for 반복문을 사용하여 배열의 요소에 접근할 수도 있습니다.

[예제] : C++

int arr[5] = {1, 2, 3, 4, 5};
for(int i : arr) {
    std::cout << i << std::endl; // 배열의 각 요소 출력
}

 

이처럼, 배열을 사용하면 여러 데이터를 효율적으로 관리하고 반복 작업을 간단하게 처리할 수 있습니다.

 


9.4. 다차원 배열

다차원 배열은 행과 열로 구성된 2차원 배열, 또는 그 이상의 차원을 가진 배열을 의미합니다. 여기에서는 다차원 배열의 선언과 사용에 대해 학습합니다.

9.4.1. 2차원 배열

2차원 배열은 행과 열로 구성되어 있습니다. 2차원 배열을 선언할 때는 배열 이름 뒤에 대괄호([])를 두 번 사용하며, 첫 번째 대괄호는 행의 수를, 두 번째 대괄호는 열의 수를 나타냅니다.

 

[예제] : C

int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
printf("%d\n", arr[0][0]); // 첫 번째 행의 첫 번째 열 요소 출력

 

[예제] : C++

int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
std::cout << arr[0][0] << std::endl; // 첫 번째 행의 첫 번째 열 요소 출력

 

2차원 배열의 모든 요소에 접근하려면 중첩 for문을 사용할 수 있습니다.

 

9.4.2. 3차원 배열 이상

3차원 이상의 배열도 선언할 수 있습니다. 3차원 배열을 선언할 때는 배열 이름 뒤에 대괄호([])를 세 번 사용하며, 첫 번째 대괄호는 깊이를, 두 번째 대괄호는 행의 수를, 세 번째 대괄호는 열의 수를 나타냅니다.

[예제] : C

int arr[2][2][3] = {{{1, 2, 3}, {4, 5, 6}}, {{7, 8, 9}, {10, 11, 12}}};
printf("%d\n", arr[0][0][0]); // 첫 번째 깊이의 첫 번째 행의 첫 번째 열 요소 출력

 

[예제] : C++

int arr[2][2][3] = {{{1, 2, 3}, {4, 5, 6}}, {{7, 8, 9}, {10, 11, 12}}};
std::cout << arr[0][0][0] << std::endl; // 첫 번째 깊이의 첫 번째 행의 첫 번째 열 요소 출력

 

3차원 배열의 모든 요소에 접근하려면 중첩 for문을 세 번 사용할 수 있습니다.

 

다차원 배열은 복잡한 데이터 구조를 나타내는 데 유용하지만, 복잡도가 높아질수록 코드의 가독성을 해칠 수 있으므로 적절히 사용해야 합니다.

 


9.5. 배열과 함수

배열은 함수의 매개변수로 전달될 수 있으며, 함수는 배열을 반환할 수 있습니다. 이 섹션에서는 이러한 내용을 다룹니다.

9.5.1. 배열을 인자로 받는 함수

함수는 배열을 매개변수로 받을 수 있습니다. 배열을 함수에 전달할 때는 배열의 이름과 원하는 요소의 타입을 명시해야 합니다. 이것은 배열의 첫 번째 요소를 가리키는 포인터를 전달하는 것과 동일하다고 할 수 있습니다.

 

[예제]

#include <stdio.h>



// 배열을 매개변수로 받는 함수
void print_array(int arr[], int size) {
    for(int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    print_array(arr, 5);
    return 0;
}

 

위의 코드에서 'print_array' 함수는 배열과 그 크기를 매개변수로 받아, 배열의 요소를 모두 출력하는 함수입니다. 함수를 호출할 때 배열 이름 'arr'과 배열의 크기를 전달합니다.

 

9.5.2. 함수가 배열을 반환하기

C++에서는 함수가 배열을 직접 반환할 수는 없습니다. 대신 함수가 배열의 첫 번째 요소를 가리키는 포인터를 반환하거나, 동적 메모리 할당을 사용하여 배열을 반환하는 방법이 일반적입니다.

[예제]

#include <iostream>

// 동적 할당을 사용하여 배열을 반환하는 함수
int* create_array(int size) {
    int* arr = new int[size];
    for(int i = 0; i < size; i++) {
        arr[i] = i;
    }
    return arr;
}

int main() {
    int* arr = create_array(5);
    for(int i = 0; i < 5; i++) {
        std::cout << arr[i] << " ";
    }
    delete[] arr; // 동적 할당을 사용했으므로 메모리 해제 필요
    return 0;
}


위의 코드에서 'create_array' 함수는 동적 메모리 할당을 사용하여 배열을 생성하고, 그 배열의 주소를 반환하는 함수입니다. 함수를 호출한 후에는 반환된 배열을 사용한 뒤 반드시 delete[] 연산자를 사용하여 메모리를 해제해야 합니다.

 


9.6. 문자 배열

문자 배열은 문자들의 집합을 저장하는 배열입니다. C/C++에서 문자열은 문자 배열로 처리됩니다. 이 섹션에서는 문자 배열의 사용과 문자열 관련 함수에 대해 설명합니다.

9.6.1. 문자 배열의 선언과 초기화

C/C++에서 문자열은 문자형(char) 배열로 표현됩니다. 문자 배열은 다른 타입의 배열과 비슷하게 선언되고 초기화됩니다. 문자열의 끝은 NULL 문자('\0')로 표시됩니다.

 


[예제]

#include <stdio.h>

int main() {
    char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    printf("%s\n", str); // Hello 출력
    return 0;
}


위의 코드에서 "Hello" 문자열은 'H', 'e', 'l', 'l', 'o', '\0' 문자들로 이루어진 배열로 표현됩니다. printf 함수의 "%s" 형식 지정자는 문자열을 출력하기 위해 사용됩니다.

 

9.6.2. 문자열 관련 함수

C 언어에서는 문자열 처리를 위한 다양한 함수를 제공합니다. 이들 함수는 string.h 라이브러리에 포함되어 있습니다. 예를 들어, strlen 함수는 문자열의 길이를 반환하고, strcpy 함수는 문자열을 복사합니다.


[예제]

#include <stdio.h>
#include <string.h>

int main() {
    char str1[10] = "Hello";
    char str2[10];
    
    printf("Length of str1: %lu\n", strlen(str1)); // Length of str1: 5 출력

    strcpy(str2, str1); // str1의 내용을 str2에 복사
    printf("str2: %s\n", str2); // str2: Hello 출력

    return 0;
}

 

위의 코드에서 strlen 함수는 "Hello" 문자열의 길이를, strcpy 함수는 str1 문자열을 str2로 복사하는 작업을 수행합니다.


9.7. 동적 배열 (C++ only)

동적 배열은 실행 시간에 그 크기가 결정되는 배열을 의미합니다. 이 섹션에서는 C++의 new와 delete 연산자를 이용한 동적 배열의 사용 방법에 대해 설명합니다.

9.7.1. new와 delete 연산자

C++에서는 동적 메모리 할당을 위해 'new'와 'delete' 연산자를 제공합니다. 'new' 연산자는 메모리를 할당하고, 'delete' 연산자는 할당된 메모리를 해제합니다.

 

[예제]

#include <iostream>

int main() {
    int* ptr = new int; // 동적 메모리 할당
    *ptr = 5;
    std::cout << *ptr << std::endl; // 5 출력

    delete ptr; // 메모리 해제
    return 0;
}

 

위 코드에서 'new' 연산자는 int형 변수에 대한 메모리를 동적으로 할당하고, 그 메모리의 주소를 ptr에 할당합니다. 'delete' 연산자는 ptr이 가리키는 메모리를 해제합니다.

 

9.7.2. 동적 배열의 사용

C++에서는 'new'와 'delete'를 사용해 동적 배열을 생성하고 관리할 수 있습니다. 배열의 크기는 실행 시간에 결정될 수 있습니다.

 

[예제]

#include <iostream>

int main() {
    int size = 5;
    int* arr = new int[size]; // 동적 배열 생성

    for(int i = 0; i < size; i++) {
        arr[i] = i;
    }

    for(int i = 0; i < size; i++) {
        std::cout << arr[i] << " "; // 0 1 2 3 4 출력
    }

    delete[] arr; // 동적 배열 해제
    return 0;
}

 

위 코드에서 'new' 연산자는 int형 변수 5개에 대한 메모리를 동적으로 할당하여 배열을 생성하고, 'delete[]' 연산자는 배열에 할당된 메모리를 해제합니다.

 


9.8. 배열을 사용한 프로그램 예제

이 섹션에서는 배열을 활용한 실제 프로그램 예제를 통해 배열의 활용 방법을 실습합니다.

9.8.1. 성적 계산기 프로그램 작성

학생들의 성적을 입력받아 평균 점수를 계산하는 프로그램을 만들어 봅시다. 배열을 사용하여 여러 학생의 점수를 저장하고, 반복문을 사용하여 점수를 합산하고 평균을 계산합니다.

 

[예제]

#include <iostream>

int main() {
    const int SIZE = 5;
    int scores[SIZE];
    int total = 0;

    for(int i = 0; i < SIZE; i++) {
        std::cout << i+1 << "번 학생의 점수: ";
        std::cin >> scores[i];
        total += scores[i];
    }

    double average = static_cast<double>(total) / SIZE;
    std::cout << "평균 점수: " << average << std::endl;

    return 0;
}

이 프로그램은 5명의 학생의 점수를 입력받아 배열에 저장하고, 모든 점수를 합산하여 평균 점수를 출력합니다.

 

9.8.2. 행렬 연산 프로그램 작성

행렬 연산을 수행하는 프로그램을 작성해 봅시다. 2차원 배열을 사용하여 행렬을 표현하고, 행렬 덧셈을 수행하는 함수를 만들어 보겠습니다.

 

[예제]

#include <iostream>

void addMatrix(int A[2][2], int B[2][2], int C[2][2]) {
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 2; j++) {
            C[i][j] = A[i][j] + B[i][j];
        }
    }
}

int main() {
    int A[2][2] = {{1, 2}, {3, 4}};
    int B[2][2] = {{5, 6}, {7, 8}};
    int C[2][2];

    addMatrix(A, B, C);

    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 2; j++) {
            std::cout << C[i][j] << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

이 프로그램은 두 개의 2x2 행렬을 더하는 행렬 연산을 수행합니다.


9.9. 배열에 대한 고급 주제

배열과 관련된 고급 주제로는 배열과 포인터의 관계, 배열과 메모리 등이 있습니다. 이 섹션에서는 이러한 고급 주제를 설명하고, 배열을 더 깊이 있게 이해하는 데 도움을 줍니다.

9.9.1. 배열과 포인터

배열과 포인터는 밀접한 관계가 있습니다. 배열의 이름은 배열의 첫 번째 원소를 가리키는 포인터로 생각할 수 있습니다. 이를 이해하면 포인터를 이용해 배열에 접근하는 다양한 방법을 알 수 있습니다.

 

[예제]

#include <iostream>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int* ptr = arr;

    for(int i = 0; i < 5; i++) {
        std::cout << *(ptr + i) << " ";
    }

    return 0;
}

 

위 예제에서는 포인터를 사용해 배열의 원소에 접근하고 있습니다. 배열의 이름 'arr'은 배열의 첫 번째 원소의 주소를 가리키므로 포인터에 할당할 수 있습니다.

 

9.9.2. 배열과 메모리

배열은 메모리에 연속적으로 할당됩니다. 이러한 특성 때문에 배열 인덱스를 사용해 특정 원소에 빠르게 접근할 수 있습니다. 또한, 포인터 연산을 이용해 배열의 원소에 접근할 수도 있습니다.

 

[예제]

#include <iostream>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};

    std::cout << "arr의 주소: " << arr << std::endl;
    std::cout << "arr[1]의 주소: " << &arr[1] << std::endl;

    return 0;
}

 

위 예제에서 'arr'과 '&arr[1]'의 주소값을 출력하면, 이 둘의 주소가 연속적임을 확인할 수 있습니다. 이는 배열의 원소들이 메모리에 연속적으로 할당되어 있음을 보여줍니다.

 

 

 

2023.05.16 - [GD's IT Lectures : 기초부터 시리즈/C, C++ 기초부터 ~] - [C/C++ 프로그래밍] 8. 함수

 

[C/C++ 프로그래밍] 8. 함수

Chapter 8. 함수 프로그래밍에서 가장 핵심적인 요소 중 하나인 '함수'에 대해 다룹니다. 함수는 프로그램의 특정 기능을 수행하는 코드 블록으로, 특정한 일을 수행하도록 설계됩니다. 이 챕터에

gdngy.tistory.com

 

 

 

 

반응형

댓글