[자료구조] 배열과 클래스 (Array & Class)
IT/Data Structure

[자료구조] 배열과 클래스 (Array & Class)

728x90
반응형

배열 (Array)

배열(Array)은 같은 자료형의 변수가 연속적인 형태로 구성된 구조이다.

각각의 원소에는 순서대로 index가 붙으며, 원소들이 연속적으로 배치되어 있기에 임의의 index에 접근(access)하는데 걸리는 시간복잡도는 O(1)이다.

따라서 배열은 임의 접근(Random Access)가 가능하다.

 

배열 ADT

객체

- 인덱스와 값 <index, value>의 쌍으로 구성된 집합.

연산

- create(n) : n개의 요소를 가지는 배열 생성

- retrive(A, i) : A배열에서 i번째 index를 가지는 값 반환

- store(A, i, v) : A배열에 <i, v> 쌍을 삽입

 

C++에서의 배열

// 만약 배열이 없는 경우
int score1;
int score2;
...
int score10;

// 배열 선언
int scoreArr[10];    // static array
int* scoreArr = new int[10];    // dynamic array
// 1차원 배열
int arr1[5] = {1, 2, 3, 4, 5};

// 2차원 배열
int arr2[2][3] = {{1, 2, 3},
                  {4, 5, 6}};

// 배열의 크기
cout << sizeof(arr1)/sizeof(arr1[0]) << endl;    // 5
cout << sizeof(arr2)/sizeof(int) << endl;        // 6

 

배열의 주소

배열의 주소는 배열의 첫번째 index의 주소를 뜻한다.

당연하게도 다음 index의 주소를 찾기 위해서는 배열의 자료형 크기를 더하면 된다.

 

함수의 매개변수로서의 배열 (Call by Value vs Call by Reference)

#include <iostream>
using namespace std;

void callByVal(int a, int b){
    a = 1;
    b = 1;
}

void callByRef(int a[], int *b){
    a[0] = 1;
    *b = 1;
}

int main(int argc, const char * argv[]) {
    
    int arrA[] = {0, 0};
    int arrB[] = {0, 0};
    
    callByVal(arrA[0], arrB[0]);
    cout << "arrA[0] : " << arrA[0] << ", arrB[0] : " << arrB[0] << endl;
    
    callByRef(arrA, arrB);
    cout << "arrA[0] : " << arrA[0] << ", arrB[0] : " << arrB[0] << endl;
    
    return 0;
}

예제에서 알 수 있듯이 배열을 전달하는 것은 배열의 첫 번째 index의 주소값을 전달하는 것과 같다.

 

매개변수 전달 시 유의점

#include <iostream>
using namespace std;

// 1차원 배열
void printArr1(char arr[], int len){
    cout << "===== printArr1 =====" << endl;
    for(int i=0; i<len; i++){
        cout << arr[i];
    }
}

// 2차원 배열
void printArr2(char arr[][5], int col, int row){
    cout << "\n===== printArr2 =====" << endl;
    for(int i=0; i<row; i++){
        for(int j=0; j<col; j++){
            cout << arr[i][j];
        }
        cout << endl;
    }
}

int main(int argc, const char * argv[]) {
    
    char arr1[5] = {'H','E','L','L','O'};
    char arr2[2][5] = {{'h','e','l','l','o'},
                       {'w','o','r','l','d'}};
    
    // 1차원 배열
    int len = sizeof(arr1)/sizeof(arr1[0]);
    printArr1(arr1, len);    // 배열의 길이를 함께 전달해야함.
    
    // 2차원 배열
    int col = sizeof(arr2[0])/sizeof(arr2[0][0]);
    int row = sizeof(arr2)/sizeof(arr2[0]);
    printArr2(arr2, col, row);    // 배열의 가로, 세로 크기를 전달해야함.
    
    return 0;
}

 

구조체 (Struct)

구조체란 하나 이상의 변수를 묶어서 새로운 자료형을 정의하는 것이다.

객체를 표현하기 위해 하나 이상의 변수가 필요한 경우 구조체를 활용할 수 있다.

 

C++ 구조체 정의

구조체(struct)는 사용자 정의 자료형이므로, 사용 전 구조체의 형태를 컴파일러에게 미리 알려주어야 한다.

struct 예약어를 사용하여 정의하고 반드시 ;(세미콜론)을 붙여주어야 한다.

struct Person{
    char name[20];
    int age;
    char sex;
    double weight;
    double height;
};

// typedef 활용 (위 code와 동일)
typedef struct Person_t{
    char name[20];
    int age;
    bool sex;
    double weight;
    double height;
}Person;

 

C++ 구조체 선언 및 사용

구조체 내부의 멤버변수에 접근하기 위해서는 .을 이용한다.

#include <iostream>
#include <string>
using namespace std;

struct Person{
    string name;
    int age;
    char sex;
    double height;
};

void printer(Person p){
    cout << "이름 : " << p.name << endl;
    cout << "나이 : " << p.age << endl;
    cout << "성별 : " << (p.sex == 'M' ? "남자" : "여자") << endl;
}

int main(int argc, const char * argv[]) {

    // Person 구조체 선언 및 초기화
    Person p1;
    p1.name = "우수연";
    p1.age = 25;
    p1.sex = 'M';
    p1.height = 184.2;
    
    Person p2;
    p2.name = "아이유";
    p2.age = 28;
    p2.sex = 'F';
    p2.height = 161.7;

    // 키큰사람 출력
    if(p1.height > p2.height){
        printer(p1);
    }else{
        printer(p2);
    }
    
    return 0;
}

 

클래스 (Class)

클래스(class)는 객체지향 프로그래밍(OOP)에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀이다.

C++에서는 기본 접근 제어자가 다른 것 말고는 구조체와 클래스가 동일하다.

둘 다 변수, 함수, 생성자, 소멸자를 내부에서 선언할 수 있고, 상속구조를 사용할 수 있다.

하지만 구조체의 경우 기본 접근 제어자가 public으로 선언되고, 클래스의 경우 기본 접근 제어자가 private으로 선언된다.

 

객체지향 프로그래밍 (Object-Oriented Programming)

객체지향에 대해 이야기하려면 끝이 없지만 간단하게 설명하자면... 말 그대로 객체라는 기본 단위로 프로그래밍을 하는 개념이다.

즉, 객체지향 프로그램은 수 많은 객체(Object)로 이루어져 있으며, 이 객체들의 상호작용으로 프로그램이 처리된다.

객체지향 프로그래밍의 특징

  • 추상화(Abstraction)
    • 속성이나 연산의 중요한 핵심을 추상적 개념으로 다루는 것
  • 캡슐화(Encapsulation)
    • 속성과 연산을 하나로 묶는 것을 의미하며, 캡슐화 된 객체는 재사용이 용이함
  • 상속(Inheritance)
    • 이미 정의된 부모 클래스의 모든 속성과 연산을 자식 클래스가 물려받는 것
  • 다형성(Polymorphism)
    • 서로 다른 클래스 객체가 같은 메시지를 받았을 때 각자의 방식으로 동작하는 것을 의미

 

C++ 클래스 정의 및 선언

#include <iostream>
using namespace std;

class Point {
private:
    int x;
    int y;
public:
    Point(){}
    ~Point(){}
    Point(int a, int b){
        x = a;
        y = b;
    }
    
    void addPoint(int a, int b);
    void showPoint();
};

void Point::addPoint(int a, int b){
    x += a;
    y += b;
}
void Point::showPoint(){
    cout << "x : " << x << ", y : " << y << endl;
}

int main(){
    Point p1(2, 4);
    Point p2;
    
    p1.addPoint(10, 10);
    p2.addPoint(10, 10);
    
    p1.showPoint();
    p2.showPoint();
    
    return 0;
}

 

접근 지정자

  • public : 모든 접근을 허용
  • protected : 상속받은 클래스 또는 같은 패키지에서만 접근
  • private : 외부에서 접근이 불가능 (즉, 같은 클래스 내에서만 접근이 가능)

 

 

728x90
반응형