CAFE

과제게시판

[c++] 3-4장 연습문제 풀이

작성자2201042 장성진|작성시간26.02.02|조회수26 목록 댓글 2

[3장 연습문제]

 

// 1

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class Date {
        int year = 0, month = 0, day = 0;
    public:
        Date(int a, int b, int c);
        Date(std::string a);
        void show();
        int getyear();
        int getmonth();
        int getday();
    };

}
// 3_main.cpp

int main() {
    Date birth(2014, 3, 20);
    Date independenceDay("1945/8/15");
    independenceDay.show();
    cout << birth.getyear() << ',' << birth.getmonth() << ',' << birth.getday() << endl;
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    Date::Date(int a, int b, int c) : year(a), month(b), day(c) {}
    Date::Date(string a) {
        string num = "";
        int part = 0;
        for (char ch : a) {
            if (ch == '/') {
                if (part == 0) year = stoi(num);
                else if (part == 1) month = stoi(num);
                num = ""; part++;
            }
            else num += ch;
        }
        day = stoi(num);
    }
    void Date::show() {
        cout << year << "년" << month << "월" << day << "일" << endl;
    }
    int Date::getyear() { return year; }
    int Date::getmonth() { return month; }
    int Date::getday() { return day; }

}

 

// 2

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class Account {
        std::string name;
        int id, money;
    public:
        Account(std::string a, int b, int c);
        void deposit(int a);
        std::string getoner();
        int widthdrow(int a);
        int inquiry();
    };

}
// 3_main.cpp

int main() {
    Account a("kitae", 1, 5000);
    a.deposit(50000);
    cout << a.getoner() << "의 잔액은 " << a.inquiry() << endl;
    a.widthdrow(20000);
    cout << a.getoner() << "의 잔액은 " << a.inquiry() << endl;
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    Account::Account(string a, int b, int c) : name(a), id(b), money(c) {}
    void Account::deposit(int a) { money += a; }
    string Account::getoner() { return name; }
    int Account::widthdrow(int a) { money -= a; return a; }
    int Account::inquiry() { return money; }

}

 

// 3

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class CoffeeMachine {
        int cof, wat, sug;
    public:
        CoffeeMachine(int a, int b, int c);
        void set(int a, int b, int c);
        void Espresso();
        void Americano();
        void maxim();
        void fill();
        void show();
    };

}
// 3_main.cpp

int main() {
    CoffeeMachine java(5, 10, 3);
    java.Espresso();  java.show();
    java.Americano(); java.show();
    java.maxim();     java.show();
    java.fill();      java.show();
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    CoffeeMachine::CoffeeMachine(int a, int b, int c) { set(a, b, c); }
    void CoffeeMachine::set(int a, int b, int c) { cof = a; wat = b; sug = c; }
    void CoffeeMachine::Espresso() { cof--; wat--; }
    void CoffeeMachine::Americano() { cof--; wat -= 2; }
    void CoffeeMachine::maxim() { cof--; wat -= 2; sug--; }
    void CoffeeMachine::fill() { set(10, 10, 10); }
    void CoffeeMachine::show() {
        cout << "커피머신 상태, 커피:" << cof
            << "\t물: " << wat << "\t설탕:" << sug << endl;
    }

}

 

// 4

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class Random {
    public:
        Random();
        int next();
        int nextinrange(int a, int b);
    };

}
// 3_main.cpp

int main() {
    Random r;
    cout << "--0에서 " << RAND_MAX << "까지의 랜덤 정수 10개--\n";
    for (int i = 0; i < 10; i++) cout << r.next() << ' ';
    cout << "\n\n--2에서 4까지의 랜덤 정수 10개--\n";
    for (int i = 0; i < 10; i++) cout << r.nextinrange(2, 4) << ' ';
    cout << endl;
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    Random::Random() { srand((unsigned)time(0)); }
    int Random::next() { return rand(); }
    int Random::nextinrange(int a, int b) {
        return a + rand() % (b - a + 1);
    }

}

 

// 5

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class Random2 {
    public:
        Random2();
        int next();
        int nextinrange(int a, int b);
    };

}
// 3_main.cpp

int main() {
    Random2 r;
    cout << "--0에서 " << RAND_MAX << "까지의 랜덤 정수 10개--\n";
    for (int i = 0; i < 10; i++) cout << r.next() << ' ';
    cout << "\n\n--2에서 10까지의 랜덤 정수 10개--\n";
    for (int i = 0; i < 10; i++) cout << r.nextinrange(2, 10) << ' ';
    cout << endl;
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    Random2::Random2() { srand((unsigned)time(0)); }
    int Random2::next() { return (rand() / 2) * 2; }
    int Random2::nextinrange(int a, int b) {
        return ((a + rand() % (b - a + 1)) / 2) * 2;
    }

}

 

// 6

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class Random3 {
    public:
        Random3();
        int next();
        int next(int parity);
    };

}
// 3_main.cpp

int main() {
    Random r;
    cout << "--0에서 " << RAND_MAX << "까지의 짝수 랜덤 정수 10개--\n";
    for (int i = 0; i < 10; i++) cout << r.next() << ' ';
    cout << endl;
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    Random3::Random3() { srand((unsigned)time(0)); }
    int Random3::next() { return (rand() / 2) * 2; }
    int Random3::next(int parity) {
        int r = (rand() / 2) * 2;
        return (parity == 0) ? r : r + 1;
    }

}

 

// 7

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class Integer {
        int i;
    public:
        Integer(int a);
        int get();
        void set(int a);
        bool isEven();
    };

}
// 3_main.cpp

int main() {
    Integer n(30);
    cout << n.get() << ' ';
    n.set(50);
    cout << n.get() << ' ';
    Integer m(300);
    cout << m.get() << ' ';
    cout << m.isEven() << endl;
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    Integer::Integer(int a) { set(a); }
    int Integer::get() { return i; }
    void Integer::set(int a) { i = a; }
    bool Integer::isEven() { return i % 2 == 0; }

}

 

// 8

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class Oval {
        int height, width;
    public:
        Oval();
        Oval(int w, int h);
        int geth();
        int getw();
        void set(int w, int h);
        void show();
        ~Oval();
    };

}
// 3_main.cpp

int main() {
    Oval a, b(3, 4);
    a.set(10, 20);
    a.show();
    cout << b.getw() << "," << b.geth() << endl;
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    Oval::Oval() : Oval(1, 1) {}
    Oval::Oval(int w, int h) { set(w, h); }
    int Oval::geth() { return height; }
    int Oval::getw() { return width; }
    void Oval::set(int w, int h) { width = w; height = h; }
    void Oval::show() {
        cout << "width = " << width << ", height = " << height << endl;
    }
    Oval::~Oval() { cout << "Oval 소멸\n"; }

}

 

// 9

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class Box {
        int width, height;
        char fill;
    public:
        Box(int w, int h);
        void setfill(char f);
        void setsize(int w, int h);
        void drow();
    };

}
// 3_main.cpp

int main() {
    Box b(10, 2);
    b.drow();
    cout << endl;
    b.setsize(7, 4);
    b.setfill('^');
    b.drow();
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    Box::Box(int w, int h) : fill('*') { setsize(w, h); }
    void Box::setfill(char f) { fill = f; }
    void Box::setsize(int w, int h) { width = w; height = h; }
    void Box::drow() {
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) cout << fill;
            cout << endl;
        }
    }

}

 

// 10

// 3.h

#ifndef HEADER_3_H
#define HEADER_3_H
#include <string>
namespace header_3 {

    class Ram {
        char mem[100 * 1024];
        int size;
    public:
        Ram();
        ~Ram();
        char read(int address);
        void write(int address, char value);
    };

}
// 3_main.cpp

int main() {
    Ram ram;
    ram.write(100, 20);
    ram.write(101, 30);
    char res = ram.read(100) + ram.read(101);
    ram.write(102, res);
    cout << "102번지의 값 = " << (int)ram.read(102) << endl;
}
// 3_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "3.h"
using namespace std;
namespace header_3 {

    Ram::Ram() : mem{ 0 }, size(100 * 1024) {}
    Ram::~Ram() { cout << "메모리 제거됨\n"; }
    char Ram::read(int address) { return mem[address]; }
    void Ram::write(int address, char value) { mem[address] = value; }

}

 

// [3장 정리문제]
// 1) 클래스와 객체를 설명하시오
// 클래스는 객체를 생성하기 위한 설계도로, 객체가 가질 데이터와 함수를 함께 정의한 사용자 정의 자료형이다. 
// 클래스 자체는 메모리를 차지하지 않으며, 객체가 생성될 때 그 정의에 따라 실제 메모리가 할당된다.
// 객체는 클래스를 기반으로 생성된 실체로서, 클래스에 정의된 변수과 함수을 실제로 가지며 메모리 공간을 차지한다. 
// 동일한 클래스로부터 여러 개의 객체를 생성할 수 있고, 이 객체들은 같은 구조를 가지지만 서로 독립적인 상태를 가진다.
// 즉, 클래스는 객체의 구조와 행위를 정의하는 개념적인 요소이고, 객체는 그 클래스를 바탕으로 생성된 실제 존재이다. 

// 2) 객체가 생성될때 메모리에 할당되는 것들을 설명하시오
객체가 생성될 때 객체가 생성되는 위치에 따라 스택, 힙, 또는 전역 영역에 해당 객체가 가지는 멤버 변수를 저장하기 위한 
공간이 할당되며, 각 객체는 자신만의 독립적인 데이터 영역을 가진다.
또한 객체가 생성될 때 생성자가 호출되어, 할당된 메모리를 초기화한다. 이때 생성자의 매개변수나 지역 변수는 별도의 메모리 공간을 사용하며, 객체 자체의 메모리에는 포함되지 않는다.
그러나 멤버 함수는 객체마다 따로 메모리가 할당되지 않으며 멤버 함수의 코드 영역은 프로그램 전체에서 하나만 존재한다.
객체는 해당 함수를 호출할 수 있는 정보를 공유한다. 
따라서 객체가 생성될 때 메모리에 할당되는 것은 객체의 멤버 변수에 해당하는 데이터이고, 생성자를 통한 초기화 과정이
수행되며, 멤버 함수의 코드는 별도로 생성되지 않는다.

// 3) 생성자와 소멸자가 왜 필요한지 설명하시오
생성자는 객체가 생성될 때 자동으로 호출되어, 객체의 멤버 변수(메모리 안)를 올바른 초기 상태로 설정하고, 객체가 사용되기 전에 필요한 자원 할당을 수행한다. 이를 통해 객체가 미초기화된 상태로 사용되는 것을 방지할 수 있다.
소멸자는 객체가 소멸될 때 자동으로 호출되어, 객체가 사용하면서 확보했던 자원을 해제하는 역할을 한다. 
예를 들어 동적 메모리, 파일, 네트워크 연결과 같은 외부 자원을 정리함으로써 자원 누수를 방지하고 프로그램의 안정성을
유지한다. 따라서 객체의 생성부터 소멸까지의 과정이 자동으로 관리되어, 객체의 상태 일관성을 보장하고 자원 관리의 책임을 객체 내부로 캡슐화할 수 있어 안전성과 신뢰성 있는 객체 사용을 위한 필수적인 요소이다.

// 4) 생성자와 소멸자를 메인함수에서 직접 호출하면 어떻게 되는지 설명하시오
생성자는 객체 생성 시에만 자동 호출되고, 이미 생성된 객체에 대해 생성자를 다시 호출하는 것은 허용되지 않는다.
따라서 객체 생성과는 무관한 의미 없는 호출이 된다.
또한, 소멸자는 문법상 호출은 가능하지만 직접 호출 시 소멸자를 명시적으로 호출할 경우 객체가 사용하던 자원이 즉시
해제되어 해당 객체가 정상소멸될 때 소멸자가 다시 자동으로 호출된다.
이때 중복 소멸로 인한 정의되지 않은 동작이 발생할 수 있어 프로그램의 안정성을 해칠 수 있다.

// 5) 콜론 초기화를 이용하면 장점이 무엇인가
콜론 초기화를 사용하면 객체의 멤버 변수를 생성 시점에 직접 초기화할 수 있다는 장점이 있다. 일반적인 대입 방식은 객체가
먼저 기본 생성된 후 생성자 본문에서 값이 대입되지만, 콜론 초기화를 사용하면 멤버 변수가 불필요한 기본 생성 과정을 거치지 않고 바로 원하는 값으로 초기화되어 성능이 향상되고 코드의 효율성이 높아진다. 
특히 const 멤버 변수나 참조 멤버 변수는 생성 이후에 값을 변경할 수 없기 때문에, 반드시 콜론 초기화를 통해서만 초기화가
가능하다. 또한 상속 관계에서 부모 클래스의 생성자 역시 콜론 초기화를 통해 명시적으로 호출할 수 있어, 객체의 초기화 순서를 명확하게 제어할 수 있다.

// 6) 인라인 함수를 선언하는 위치는 어디가 가장 적당한가
C++에서 인라인 함수의 가장 적절한 정의 위치는 헤더 파일이다. 이는 컴파일러가 함수 호출부를 실제 코드로 치환하기 위해,
각 .cpp 파일을 컴파일하는 시점에 함수의 본체를 직접 읽을 수 있어야 하기 때문이다.
만약 정의를 .cpp 파일에 두면 다른 번역 단위에서는 해당 로직을 볼 수 없어 인라인화가 불가능하거나 링킹 에러가 발생할 수
있다.

이때 inline 키워드는 동일한 함수 정의가 여러 번 나타나도 링커 단계에서 에러를 내지 않고 하나로 병합하도록 보장하므로, 헤더 파일에 중복 포함되어도 안전하다.

따라서 설계상 가독성이 중요하다면 헤더 하단에 별도로 구현부를 배치하더라도, 결국 전처리기에 의해 헤더 안으로 합쳐지도록 설계하는 것이 인라인 최적화를 달성하는 정석적인 방법이다.

// 7) 인라인 함수의 선언과 정의를 헤더파일과 소스파일로 분리하여 작성하면 어떻게 되는가
인라인 함수의 선언은 헤더 파일에, 정의는 소스 파일에 분리하여 작성하면 링킹 에러가 발생하거나, 인라인 최적화가 무시된 채 일반 함수로 처리될 가능성이 높다.
컴파일러는 각 .cpp 파일을 독립적으로 컴파일하므로 main.cpp를 컴파일할 때 인라인 함수의 호출부를 만나면 본체 코드를
복사해 넣어야 하는데, 정의가 외부에 있으면 컴파일러는 인라인 치환을 포기한다.
inline 키워드가 붙은 함수는 컴파일러가 "이 함수는 다른 곳에도 정의가 있을 테니 외부 심볼로 만들지 않겠다"고 판단하여
오브젝트 파일에 공개적인 심볼을 남기지 않는 경우가 많다. 
따라서 링커는 메인함수 파일에서 요구하는 함수 주소를 정의 파일에서 찾지 못해 에러를 발생시킨다.
반드시 분리해야 하는 경우 현대 컴파일러의 LTO 기능을 활성화시켜 링킹 단계에서 인라인화를 시도할 수는 있으나 표준적인
방식이 아니며 빌드 효율을 떨어뜨린다.
컴파일러 또한 컴파일 이진 파일으로 변환하는 것이 아닌 중간 단계인 IR 표현을 사용해 변환하는 컴파일러여야 한다.

// 8) 3.9 절의 소스파일과 헤더파일을 나누는 기준을 설명하시오.
C++에서 파일을 나누는 가장 큰 기준은 선언과 로직을 분리하는 것이다. 헤더 파일은 일종의 설계도로, 다른 파일들이 이 기능을 쓰기 위해 알아야 할 이름이나 사용법(선언)만 적어 둔다. 
반면, 소스 파일은 구체적으로 어떻게 동작하는지 정확한 로직을 이곳에 숨겨둡으로써 코드를 수정했을 때 전체 프로젝트를 다시 빌드할 필요 없이, 바뀐 그 파일 하나만 빠르게 다시 만들 수 있다.
그러나, 인라인 함수는 컴파일러가 이름표만 보고 치환하는 게 아닌, 그 자리에서 즉시 레시피를 보고 코드를 복사해 넣어야 하기 때문에 컴파일러가 언제든 레시피를 바로 읽을 수 있도록 헤더에 정의를 포함한다.


[4장 연습문제]

 

// 1

// 4.h

X

// 4_main.cpp

int main() {
while (1) {
srand((unsigned)time(0));
string str;
cout << "아래에 한 줄을 입력하세요.(exit를 입력하면 종료합니다.)\n";
getline(cin, str);
if (str == "exit") break;
int point = rand() % str.length();
char x = (char)('a' + (rand() % 26));
str[point] = x;
cout << str << endl;
}
}

// 4_func.cpp

X

 

// 2

// 4.h

X

// 4_main.cpp

int main() {
while (1) {
srand((unsigned)time(0));
string str;
cout << "아래에 한 줄을 입력하세요.(exit를 입력하면 종료합니다.)\n";
getline(cin, str);
if (str == "exit") break;
for (int i = str.length(); i >= 0; i--) {
cout << str[i];
}
cout << endl;
}
}

// 4_func.cpp

X

 

// 3

// 4.h

X

// 4_main.cpp

int main() {
int cnt = 0;
for (int i = 0; i < 3; i++) {
Circle circle;
int r;
cout << "원 " << i + 1 << "의 반지름 >> ";
cin >> r;
circle.setr(r);
if (circle.getarea() > 100) cnt++;
}
cout << "면적이 100보다 큰 원은 " << cnt << "개 입니다.";
}

// 4_func.cpp

X

 

// 4

// 4.h

#ifndef HEADER_4_H
#define HEADER_4_H
#include <string>
namespace header_4 {

    class Circle {
        int r;
    public:
        void setr(int r);
        double getarea();
    };

}

// 4_main.cpp

int main() {
int cnt = 0, n;
cout << "원의 개수 >> ";
cin >> n;
Circle* circle = new Circle[n];
for (int i = 0; i < n; i++) {
int r;
cout << "원 " << i + 1 << "의 반지름 >> ";
cin >> r;
circle[i].setr(r);
if (circle[i].getarea() > 100) cnt++;
}
cout << "면적이 100보다 큰 원은 " << cnt << "개 입니다.";
}

// 4_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "4.h"
using namespace std;
namespace header_4 {

    void Circle::setr(int r) { this->r = r; }
    double Circle::getarea() { return this->r * this->r * 3.14; }

}

 

// 5

// 4.h

#ifndef HEADER_4_H
#define HEADER_4_H
#include <string>
namespace header_4 {

    class Person {
        std::string name, tel;
    public:
        Person() {}
        std::string getname();
        std::string gettel();
        void set(std::string name, std::string tel);
    };

}

// 4_main.cpp

int main() {
Person person[3];
cout << "이름과 전화번호를 입력해주세요\n";
for (int i = 0; i < 3; i++) {
string name, tel;
cout << "사람 " << i + 1 << ">> ";
cin >> name >> tel;
person[i].set(name, tel);
}
cout << "모든 사람의 이름은 ";
for (int i = 0; i < 3; i++) {
cout << person[i].getname() << ' ';
}
cout << endl << "전화번호 검색합니다. 이름을 입력하세요>>";
string name;
cin >> name;
for (int i = 0; i < 3; i++) {
if (person[i].getname() == name)
cout << "전화번호는 " << person[i].gettel();
}
}

// 4_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "4.h"
using namespace std;
namespace header_4 {

    string Person::getname() { return name; }
    string Person::gettel() { return tel; }
    void Person::set(string name, string tel) {
        this->name = name; this->tel = tel;
    }

}

 

// 6

// 4.h

#ifndef HEADER_4_H
#define HEADER_4_H
#include <string>
namespace header_4 {

    class Person2 {
        std::string name;
    public:
        Person2(std::string name);
        void setname(std::string name);
        std::string getname();
    };
    class Family {
        std::string familyname;
        Person2* p;
        int size;
    public:
        Family(std::string name, int size);
        void setname(int index, std::string name);
        void show();
    };

}

// 4_main.cpp

int main() {
Family* sim = new Family("sim", 3);
sim->setname(0, "sim1");
sim->setname(1, "sim2");
sim->setname(2, "sim3");
sim->show();
delete sim;
}

// 4_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "4.h"
using namespace std;
namespace header_4 {

    Person2::Person2(string name = "") { this->name = name; }
    void Person2::setname(string name) { this->name = name; }
    string Person2::getname() { return name; }
    Family::Family(string name, int size) {
        familyname = name;
        this->p = new Person2[size];
        this->size = size;
    }
    void Family::setname(int index, string name) {
        p[index].setname(name);
    }
    void Family::show() {
        cout << familyname << "가족은 다음과 같이 " << size << "명입니다." << endl;
        for (int i = 0; i < size; i++) {
            cout << p[i].getname() << "\t";
        }
    }

}

 

// 7

// 4.h

#ifndef HEADER_4_H
#define HEADER_4_H
#include <string>
namespace header_4 {

    class Cont {
        int size;
    public:
        Cont();
        void fill();
        void consume();
        int getsize();
    };
    class CoffeeMachine {
        Cont t[3];
        void fill();
        void Espresso();
        void Americano();
        void Maxim();
        void show();
    public:
        void run();
    };

}

// 4_main.cpp

int main() {
CoffeeMachine machine;
machine.run();
}

// 4_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "4.h"
using namespace std;
namespace header_4 {

    Cont::Cont() { fill(); }
    void Cont::fill() { size = 10; }
    void Cont::consume() {
        if (size > 0) size--;
        else cout << "원료가 부족합니다.\n";
    }
    int Cont::getsize() { return size; }

    void CoffeeMachine::fill() {
        for (int i = 0; i < 3; i++) t[i].fill();
    }
    void CoffeeMachine::Espresso() {
        t[0].consume(); t[1].consume();
    }
    void CoffeeMachine::Americano() {
        Espresso(); t[1].consume();
    }
    void CoffeeMachine::Maxim() {
        Americano(); t[2].consume();
    }
    void CoffeeMachine::show() {
        cout << "커피 " << t[0].getsize()
            << ", 물 " << t[1].getsize()
            << ", 설탕 " << t[2].getsize() << endl;
    }
    void CoffeeMachine::run() {
        string* res = new string[6]{ "", "에스프레소", "아메리카노", "맥심", "잔량보기", "원료채우기" };
        void (CoffeeMachine:: * actions[6])() = {
            nullptr, &CoffeeMachine::Espresso, &CoffeeMachine::Americano,
            &CoffeeMachine::Maxim, &CoffeeMachine::show, &CoffeeMachine::fill };
        int choice;
        cout << "커피 머신 작동 시작\n";
        while (true) {
            cout << "\n===== 메뉴 =====\n";
            for (int i = 1; i <= 5; i++) {
                cout << i << ". " << res[i] << "\n";
            }
            cin >> choice;
            if (choice >= 1 && choice <= 5) {
                (this->*actions[choice])();
                cout << res[choice];
            }
            else {
                cout << "잘못된 선택입니다.\n";
            }
        }
    }

}

 

// 8

// 4.h

#ifndef HEADER_4_H
#define HEADER_4_H
#include <string>
namespace header_4 {

    class Circle2 {
        int r = 0;
        std::string name;
    public:
        Circle2(std::string name);
        void setc(std::string name, int r);
        double getarea();
        std::string getname();
    };

    class Circlemanager {
        Circle2* p;
        int size;
    public:
        Circlemanager(int size);
        void searchname(std::string name);
        void searcharea(int a);
    };

}

// 4_main.cpp

int main() {
int n = 0;
string name;
int area;
cout << "원의 개수>>";
cin >> n;
Circlemanager c(n);
cout << "검색할 원의 이름 >> ";
cin >> name;
c.searchname(name);
cout << "최소면적을 입력하세요 >> ";
cin >> area;
c.searcharea(area);
}

// 4_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "4.h"
using namespace std;
namespace header_4 {

    Circle2::Circle2(string name = "") { this->name = name; }
    void Circle2::setc(string name, int r) {
        this->name = name; this->r = r;
    }
    double Circle2::getarea() { return r * r * 3.14; }
    string Circle2::getname() { return name; }
    Circlemanager::Circlemanager(int size) {
        p = new Circle2[size];  this->size = size;
        for (int i = 0; i < size; i++) {
            string name; int r;
            cout << "원 " << i + 1 << "의 이름과 반지름 >> ";
            cin >> name >> r;
            p[i].setc(name, r);
        }

    }
    void Circlemanager::searchname(string name) {
        for (int i = 0; i < size; i++) {
            if (p[i].getname() == name) {
                cout << name << "의 면적은 " << p[i].getarea() << endl;
            }
        }
    }
    void Circlemanager::searcharea(int a) {
        for (int i = 0; i < size; i++) {
            if (a < p[i].getarea()) {
                cout << p[i].getname() << "의 면적은 " << p[i].getarea() << ",";
            }
        }
    }

}

 

// 9

// 4.h

#ifndef HEADER_4_H
#define HEADER_4_H
#include <string>
namespace header_4 {

    class Histogrm {
        std::string str;
    public:
        Histogrm(std::string str);
        void put(std::string str);
        void putc(char a);
        void print();
    };

}

// 4_main.cpp

int main() {
Histogrm his("wise men say, only fools rush in But I can't help, ");
his.put("falling in love with you");
his.putc(' - ');
his.put("Elvis Presley");
his.print();
}

// 4_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "4.h"
using namespace std;
namespace header_4 {

    Histogrm::Histogrm(string str = "") { this->str = str; }
    void Histogrm::put(string str) { this->str += str; }
    void Histogrm::putc(char a) { this->str += a; }
    void Histogrm::print() {
        int cnt = 0;
        int histogram[26] = { 0 };
        for (int i = 0; i < str.length(); i++) {
            char c = tolower((unsigned char)str[i]);
            if (c >= 'a' && c <= 'z') { histogram[c - 'a']++; cnt++; }
        }
        cout << str << "\n\n" << "총 알파벳 수 " << cnt << "\n\n";
        for (int j = 0; j < 26; j++) {
            cout << char('a' + j) << " (" << histogram[j] << ")\t: ";
            for (int k = 0; k < histogram[j]; k++) cout << '*';
            cout << endl;
        }
    }

}

 

// 10

// 4.h

#ifndef HEADER_4_H
#define HEADER_4_H
#include <string>
namespace header_4 {

    class Gamebling {
        std::string p[2];
    public:
        Gamebling();
        void run();
    };

}

// 4_main.cpp

int main() {
Gamebling game;
game.run();
}

// 4_func.cpp

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "4.h"
using namespace std;
namespace header_4 {

    Gamebling::Gamebling() {
        cout << "***** 게임 시작 *****\n";
        cout << "첫번째 선수 이름 >> ";
        cin >> p[0];
        cout << "두번째 선수 이름 >> ";
        cin >> p[1];
    }
    void Gamebling::run() {
        srand((unsigned)time(0));
        cin.ignore();
        bool num = false;
        while (1) {
            int x = rand() % 3, y = rand() % 3, z = rand() % 3;
            cout << p[num] << ":";
            cin.get();
            cout << "\t\t" << x << "\t" << y << "\t" << z << "\t\t";
            if (x == y && y == z) { cout << p[num] << "님 승리!!"; break; }
            else { cout << "아쉽군요!\n"; num = !num; }
        }
    }

}

 

//[4장 정리문제]
// 1) 동적할당과 정적할당의 차이와 장단점을 설명하시오
// 정적 할당은 메모리 크기가 확실할 때 속도와 안전성을 위해 사용하고 스택 영역에 할당된다. 동적 할당은 실행 중에 데이터
양이 얼마나 들어올지 알 수 없을 때 유연성을 위해 사용하고, 힙 영역에 할당된다.

그러나 동적 할당은 개발자가 직접 반납하지 않으면 시스템 자원을 낭비할 위험이 있으므로 반드시 사용이 끝나면 메모리를
할당 해제해야 한다.

// 2) 메모리 누수가 왜 발생하는지 설명하시오
메모리 누수는 동적 할당된 메모리의 주소를 저장한 포인터를 다른 값으로 덮어씌우거나, 해당 포인터가 함수가 종료되어
소멸할 때 또는 명시적으로 해제하지 않을 때 발생한다. 

// 3) 메모리 누수가 발생하면 어떻게 되는가
메모리 누수가 발생하면 시스템의 사용 가능한 메모리가 점진적으로 고갈된다. 이로 인해 초기에는 과도한 보조기억 장치의
활용으로 인한 빈번한 페이징 작업이 일어나 성능 저하가 일어나며, 최종적으로는 메모리 할당 실패로 인해 프로그램이

강제 종료된다.

// 4) C++ 에서 문자열 처리시 char 배열 대신에 string 클래스를 사용하면 어떤 장점이 있는지 설명하시오
string 클래스는 동적 할당 기법을 사용하여 메모리 할당과 해제를 자동으로 관리하므로 버퍼 오버플로우나 메모리 누수 같은
위험으로부터 안전하고, 다양한 연산자 오버로딩을 통해 문자열 조작을 훨씬 직관적이고 편리하게 만들어준다.

 

 

다음검색
현재 게시글 추가 기능 열기
  • 북마크
  • 신고 센터로 신고

댓글

댓글 리스트
  • 작성자Sungryul Lee | 작성시간 26.02.02 #pragma once 무언인가요? 표준문법인가요 아니라면 표준문법코드로 고치세요
    문제별로 코드를 분리해서 작성할것, 다시말하면 문제별로 필요한 완전한 코드를 첨부할것
    분리하라니까 헤더파일에 왜 하나로 합쳐놨나요 3장 마지막부분에 분리하는 법나와 있으니 시키는대로 하세요 니멋대로 하지 말고 제발요
    정리문제 푼거는 어디있나요?
    선언부에 함수를 정의하는거과 구현부에 정의하는것의 차이는 무엇인가요 본인은 왜 저렇게 했는지 이유를 설명할것
  • 답댓글 작성자2201042 장성진 작성자 본인 여부 작성자 | 작성시간 26.02.02 #pragma once는 컴파일러 확장으로 대부분의 컴파일러에서 쓰이지만 표준문법은 아닙니다. 수정하겠습니다.
    선언부에 함수의 정의를 작성하면 컴파일러가 자동 인라인 함수로 판단하여 함수의 정의를 그대로 복사, 붙여넣기하여 함수의 호출과 선언이 이루어지지 않아 성능에 이점이 있지만 실행 파일의 크기가 증가합니다.
    정리문제는 진도를 다 나간 후에 한번에 하라고 하신 줄 알고 첨부하지 않았습니다. 장별로 작성해서 게시물에 첨부하겠습니다.
댓글 전체보기
맨위로

카페 검색

카페 검색어 입력폼