(C++) 스마트팩토리 - 17일

내 이름 안찬찬·2023년 2월 8일
0
post-thumbnail

구조체

  • 프로그래밍을 하다 보면 변수 하나로 표현하기 힘든 것이 있다.
•ex) 학생을 표현 하려한다면 이름, 나이, 학교, 학년, 학번, 전공 등
등의 다양한 특징에 대한 변수가 필요함.

•ex) 위치를 표현하려면, x좌표, y좌표 등에 대한 변수가 필요함.

  • 구조체 문법
//기본 문법
struct Position {
	int x = 0; 
	int y = 0;
};
Position p; 
	p.x = 3;
	p.y = 5;
//구조체 사용 예시
#include <iostream>
using namespace std;

struct Position {
	int x;
	int y;
};

int main() {
	Position p; // 구조체 변수 지정
	p.x = 3; // 할당
	p.y = 4; // 할당

	Position p1; // 여러번 변수 지정 가능
	p1.x = 5; // p의 x와 다름
	p1.y = 7;

	Position p2;

	//구조체 변수 지정과 할당을 한번에 하는 방법
	//Position p = { 3, 4 };




	//cout << p << endl; //안됩니다!
	cout << p.x << " " << p.y << endl;
	cout << p1.x << " " << p1.y << endl;
	cout << p2.x << " " << p2.y << endl;
}

구조체 실습 1

(1) Rectangle 구조체 만들기, 사각형의 가로 세로 길이를 저장하는 구조체
(2) 변수 width, height
(3) 구조체를 이용하여 변수를 생성하고, width와 height 값을 콘솔로 입력 받음
(4) width와 height 값을 이용해 넓이를 계산하여 출력

struct Rectangle {
	double width;
	double height;
};

int main() {
	Rectangle R;
	R.width;
	R.height;

	cout << "가로의 길이를 입력하세요: ";
	cin >> R.width;
	cout << "세로의 길이를 입력하세요: ";
	cin >> R.height;

	cout << "사각형의 넓이는: "<< R.width*R.height ;
}


클래스

클래스를 배우기 전에 알아 볼 것

  • 절차지향 프로그래밍
  • 객체
  • 객체지향 프로그래밍

객체

  • 실생활에서 우리가 인식할 수 있는 사물

  • 객체(object)는 상태와 동작을 가지고 있다.
    - 객체의 상태는 객체의 특징 값(속성)
    - 객체의 동작은 객체가 취할 수 있는 동작

  • 예시

고양이를 표현한다고 가정

- 속성(property)
	- 이름: 나비
    - 나이: 1살
    - 종: 페르시안
    
- 행동(method)
	-mew(): 울다
    -eat(): 먹는다

절차지향 프로그래밍

  • 순차적인 처리가 중요시 되며 프로그램 전체가 유기적으로 연결되도록 만드는 프로그래밍 기법

  • 장점
    - 컴퓨터의 처리구조와 유사해 실행속도가 빠름

  • 단점
    - 유지보수가 어려움
    - 실행 순서가 정해져 있으므로 코드의 순서가 바뀌면 동일한 결과를 보장하기 어려움


객체지향 프로그래밍

  • 필요한 데이터와 코드를 묶어 하나의 객체로 만들고 이 객체들 간에 상호작용을 하도록 프로그램을 만드는 방식

  • 실제 세계를 모델링하여 소프트웨어를 개발하는 방법

  • 장점
    - 유지보수 용이
    - 코드 재사용에 용이

  • 단점
    - 처리속도가 느림 -> but, 사람이 인지할 정도의 속도가 아님
    - 설계가 복잡함


정리

절차지향 프로그래밍

기계 자체가 절차지향적으로 처리하려 하기 때문에 기계와 가깝고
그로인해 기계가 빠르게 처리함

컴퓨터 속도가 빨라지면서 기계가 빠르게 처리하는 것에 의미가 없어지기 시작하며,
개발자(사람)가 이해하기 쉬운 객체지향 프로그램이 나오기 시작

객체지향 프로그래밍

속도에 중요성이 미약해지고 유지보수가 쉬운게 중요해지면서
객체지향 프로그램 언어들이 나타나기 시작

클래스란?

  • 객체 지향 프로그래밍을 실현하기 위해 나온 개념
예를들어 사람이라는 객체를 표현한다면,
이름, 성별, 나이, 상황에 따른 행동 등 정의할 수 있는 것들이 필요함

클래스의 구조

•필드(변수) : 클래스 내에서 값을 저장하는 변수

•메소드 : 클래스 내에 선언된 함수

•생성자 : 객체가 생성될 때 자동으로 호출되는 메소드

class Position {
	int x = 0; // 필드
	int y = 0;
public : // 접근 제어자
	Position() { } // 생성자
	void printXY() { // 메소드
		std::cout << x << " " << y;
	}
};

접근 제어자란?

  • 클래스의 멤버(변수, 메소드)들의 접근 권한을 지정
  • public, protected, private 세가지로 나뉨

Private: 해당 클래스 내에서만 접근 가능

Public: 어디서나 접근 가능

Protected: 해당 클래스 & 하위 클래스 내에서만 접근 가능
=> 이 접근 제어자는 "상속"의 개념을 배우고 자세히 알아볼 예정

class Cat { //Class 사물과 사물이 행동하는 모든 것을 정의한 틀
// 클래스는 기본적으로 정보 은닉(보안)
// 정보은닉을 풀어주는 public
public:
	string name;
	string breed;
	int age = 0;


	//생성자: class로 객체(변수)를 만들 때 바로 실행
	//퍼블릭이 없고 생성자를 변경하지 않았을 때는 defualt값으로 실행
	//생성자를 수정하고 싶을 땐 퍼블릭 안에 있어야 함
	Cat(string name, string breed) {
		this->name = name;
		this->breed = breed;
	}

	//class안에 있는 함수 = 메소드
	void mew() {
		cout << "우는 소리: 야옹" << endl;
	}
	void eat() {
		cout << "좋아하는 음식: 츄르 냠냠!" << endl;
	}
};



int main() {
	// Cat이라는 클래스의 인스턴스를 만듦
	// c는 객체
	// c는 Cat의 인스턴스다.
	//Cat c;
	Cat c("진평이", "먼치킨"); //생성자는 이 순간에 바로 실행이 된다.
	//Cat c = Cat("진평이");

	// public을 사용하여 정보은닉을 품, 이후 구조체와 같은 방법으로 변수 설정
	c.age = 3;

	cout << c.age<<"살 " << c.name << " " << c.breed;
	cout << endl;


	//클래스 내에 있는 함수 호출
	c.mew();
	c.eat();
}

클래스와 구조체의 차이

  • 개념이 파생되게 된 계기가 다름
    - 구조체 : 하나의 변수만으로 표현하기 어려운 것들을 표현하기 위해
    - 클래스 : 객체지향 프로그래밍을 실현하기 위해

  • 정보 은닉의 중요성에 따라 접근 제어자의 기본값이 private
    - 클래스와 구조체의 가장 큰 차이점(정보 은닉)

  • 문법 상으론 거의 없음.

struct Position { // 사실 구조체 내에서도 변수만 선언할 수 있는 것은 아님.
	int x = 0; 
	int y = 0;
    
	Position() { } // 생성자
    
	void printXY() { // 메소드
    
		std::cout << x << " " << y;
	}
};


getter & setter

getter & setter란?

  • 클래스 외부에서 private 변수에 접근할 수 있도록 도와주는 메소드
    - getter: 변수를 반환해주는 메소드
    - setter: 변수를 초기화해주는 메소드
//getter: 변수를 반환해주는 메소드
//setter: 변수를 변경시켜주는 메소드
class Cat { 
	string name;
	string breed;
	int age = 0;

public:

	//getter
	string get_name() {
		return name;
	}
	string get_breed() {
		return breed;
	}
	int get_age() {
		return age;
	}

	//setter 
	//세팅만 하고 끝내면 되기 때문에 반환 필요없어서 void
	void set_name(string name) {
		this->name = name;
	}
	void set_breed(string breed) {
		this->breed = breed;
	}
	void set_age(int age) {
		this->age = age;
	}
};



int main() {

	Cat c; 
	//c.age = 3;
	c.set_age(3);
	c.set_name("안진평");
	c.set_breed("먼치킨");

	//string name = c.name;
	string name = c.get_name();

	//cout << c.name << " " << c.breed << endl;
	cout<< c.get_age()<< " " << c.get_name() << " " << c.get_breed() ;
   	cout << "\n";
}


실습

클래스 실습 1

(1) Rectangle 클래스 만들기 (사각형의 넓이를 구하는 클래스)

(2) 필드(변수): width, height (private으로 설정)

(3) 생성자: width와 height 설정할 2개의 숫자를 매개변수로 받기.

(4) 메소드: width와 height를 이용하여 사각형의 넓이를 반환하는 area 메소드 만들기

(5) 객체 생성 시에 width와 height을 사용자에게 입력 받아 생성자로 넘겨주기

#include <iostream>
using namespace std;

// Rectangle 클래스 정의
class Rectangle {
private:
    // 필드: width, height (private 접근제한)
    double width, height;

public:
    // 생성자: width, height 설정
    Rectangle(double w, double h) : width(w), height(h) {}

    // 메소드: 사각형의 넓이 계산
    double area() {
        return width * height;
    }
};

int main() {
    double w, h;
    // 사용자로부터 width, height 입력 받음
    cout << "밑변 길이: ";
    cin >> w ;
    cout << "높이 길이: ";
    cin >> h;

    // 객체 생성
    Rectangle rect(w, h);
    // 사각형의 넓이 출력
    cout << "사각형의 넓이: " << rect.area() << endl;

    return 0;
}

클래스 실습 번외

게임 캐릭터 생성하고 develop 시키는 프로그램

(1) Character 라는 클래스 작성

(2) Character 클래스는 캐릭터 이름, level, item 수를 속성으로 가지고 있어야 함.

(3) 사용자에게 콘솔로 캐릭터 이름 입력받고, 캐릭터 생성하기. (이름은 입력받은 값으로, level, item 수는 0으로 초기화) => 생성자 사용

(4) 사용자에게 게임 캐릭터 어떻게 조작할지 입력하게 하기. ( 0: 종료. 0을 입력할 때까지 계속 물어보고 입력한 번호에 해당하는 작업을 계속 하면 됨. )

1을 입력하면, 이름 변경하도록
2를 입력하면, level up ( level 이 1씩 올라가게 )
3을 입력하면, item 줍줍 ( item 갯수가 1씩 증가 )
4를 입력하면, item 사용 ( item 갯수가 1씩 감소 )
5를 입력하면, 이름, level, item 을 콘솔로 출력
0를 입력하면, 게임 종료.

(5) 위 기능은 모두 Character 의 메소드로 만들어져 있어야 함.

// Character 클래스 선언
class Character {
	// 레벨, 이름, 아이템 개수 멤버 변수
	int level;
	string name;
	int item;

public:
	// 생성자
	Character(string name) {
		// this 포인터를 사용해 name 멤버 변수에 인자로 받은 name 값 할당
		this->name = name;
		level = 0; // 레벨 초기값 0
		item = 0; // 아이템 개수 초기값 0
	}

	// 캐릭터 이름 변경 메서드
	void name_change(string name) {
		// this 포인터를 사용해 name 멤버 변수에 인자로 받은 name 값 할당
		this->name = name;
	}

	// 레벨 업 메서드
	void level_up() {
		++level; // 레벨 1 증가
		cout << "레벨 업!!\n" << "현재 레벨: " << level << "\n";
	}

	// 아이템 획득 메서드
	void get_item() {
		item++; // 아이템 개수 1 증가
		cout << "아이템 줍줍! \n" << "현재 item 갯수: " << item << "\n";
	}

	// 아이템 사용 메서드
	void set_item() {
		if (item <= 0) { // 아이템의 개수가 음수가 되지 않게
			cout << "아이템이 없습니다. \n";
		}
		else {
			--item; // 아이템 개수 1 감소
			cout << "아이템 사용! \n" << "현재 item 갯수: " << item << "\n";
		}
	}


	// 캐릭터 정보 출력 메서드
	void char_status() {
		cout << "접속중인 캐릭터: " << name << "\n캐릭터 레벨: " << level << "\n보유 아이템 갯수: " << item << "\n";
	}
};

// 게임 캐릭터 생성 및 조작
int main() {
    // 캐릭터 명을 저장할 변수
	string name;
	// 캐릭터 조작에 필요한 변수
	int cnt;
	
    // 접속할 캐릭터 명 입력
	cout << "접속 또는 생성할 캐릭터 명 입력: ";
	cin >> name;
	
    // 캐릭터 객체 생성
	Character game(name);
	
	// 게임 루프
	while(1) {
        // 조작 키 입력
		cout << "조작 키 입력: ";
		cin >> cnt;

        // 조작 키에 따른 분기
		switch (cnt)
		{
            // 게임 종료
		case 0:
			return -1;

            // 캐릭터 명 변경
		case 1:
			cout << "캐릭터 명 변경: ";
			cin >> name;
			game.name_change(name);
			break;

            // 캐릭터 레벨 업
		case 2:
			game.level_up();
			break;

            // 아이템 획득
		case 3:
			game.get_item();
			break;

            // 아이템 사용
		case 4:
			game.set_item();
			break;

            // 캐릭터 정보 출력
		case 5:
			game.char_status();
			break;
		}
	}
}


마무리~~

객체지향 언어와 절차지향 언어에 대해 저번에도 다뤘지만,
이번에야 말로 명확하게 이해할 수 있어서 좋았다.

명확하게 이해했다는 건 언제 어떤 언어를 사용하느냐를 알게 된 것과
객체지향 언어가 나타나게 된 계기와 절차지향 언어와의 차이점?

그리고 클래스와 구조체에 대한 것도 알아봤는데,
객체지향 언어의 꽃(?)이라고 생각하게 해준 클래스를 아직은 찍먹(?)한 느낌

앞으로도 공부할게 산더미 처럼 많고 벽을 넘어야 할 일이 많다는 것을 느꼈다.

한 번 개발자가 되기로 마음 먹은 이상 포기하지 않고 배워나갈 것이다!

아자아자~~~!!

profile
스마트팩토리 개발자가 되기 위한 □□ !!

0개의 댓글