CH01,02 c++이해와 입출력 기본

jiyoon·2024년 4월 14일
0

학교 수업 복습을 위해 작성하였습니다! 생능출판사의 '명품 C++ 프로그래밍' 교재를 사용하며, 저자인 황기태 교수님의 강의를 기반으로 합니다.

c++ 객체 지향 특성

  1. 캡슐화 - 클래스와 객체가 중심
  2. 상속성 - 부모 클래스에서 상속받음
  3. 다형성 - 함수 오버로딩(중복), 함수 오버라이딩(재정의)


c++ 제네릭 프로그래밍

  • 제네릭 함수 - 다양한 데이터 타입을 적용할 수 있도록 일반화된 함수
  • 제네릭 클래스 - 다양한 데이터 타입을 적용할 수 있도록 일반화된 클래스
  • template 키워드를 사용하여 선언 - 템플릿 함수/클래스

제네릭 프로그래밍은 제네릭 함수와 제네릭 클래스를 활용하여 프로그램을 작성하는 프로그래밍 패러다임이다.



개발 과정

소스파일 -> 컴파일 -> 목적파일 -> 링킹 -> 실행파일 -> 실행
(hello.cpp) -> (hello.obj) -> (hello.exe)



#include < iostream>

  • 전처리기(c++ Preprocessor)는 컴파일 전에 < iostream> 헤더 파일을 읽어서 소스 파일에 삽입하라는 지시를 받는다.

  • < iostream> 헤더 파일에는 표준 입출력을 위한 클래스와 객체, 변수 등이 선언되어 있다.
    ex) cout, cin, <<, >> 등 연산자 선언

  • cout, cin 객체는 스크린 장치와 연결된 표준 c++ 입출력 스트림 객체이다.

  • <<, >> 연산자는 스트림 삽입﹒추출 연산자이다.
    - << : 삽입. 오른쪽 피연산자 데이터를 왼쪽 스트림 객체에 삽입
    - >> : 추출. 왼쪽 피연산자인 스트림 객체로부터 데이터를 읽어 오른쪽 피연산자에 지정된 변수에 삽입

  • \n과 endl 조작자
    - \n : cout의 스트림 버퍼에 단순 삽입. 버퍼가 꽉 차거나 강제 출력 지시 있을 경우 출력
    - endl : endl()함수를 호출하면 \n을 cout의 스트림 버퍼에 삽입 후 즉시 데이터를 장치에 출력

std::cout << "Hello\n" << endl;
int width, height;
std::cin >> width >> height;


namaspace와 std::

namespace는 개발자가 자신만의 고유한 이름 공간을 만들어 클래스 등의 이름 충돌을 방지한다.
::는 범위 지정 연산자로서 c++ 표준 연산자이다.
std::는 c++ 표준 이름 공간으로, c++ 표준 라이브러리에서 선언된 이름을 사용할 때 붙인다.
using 지시어를 이용하여 std::를 생략할 수 있다.

using std::cout;		//cout에 대해서만 std::생략
using namespace std;	//std 이름 공간에 선언된 모든 이름에 대해 std::생략




문자열 입출력

  • c-string 방식 - '\0' null값으로 끝나는 문자 배열. c언어 방식
  • string 클래스 이용 - < string> 헤더 파일에 선언되어 있음.

공백이 낀 문자열 입력

  • c-string - cin.getline(char buf[ ], int size, char delimitChar)
    • buf에 최대 size-1개의 문자를 입력. 끝에 '\0'를 추가.
    • delimitChar을 만나면 입력을 중단. 기본값은 '\n' (Enter키)
  • string 클래스 - getline(cin, string str)

#include <iostream> 
#include <string>

using namespace std;

int main() {
	cout << "주소를 입력하세요>>";
	char address[100];
	cin.getline(address, 100, '\n'); // 키보드로부터 주소 읽기. 변수 address에 저장, 최대 100글자까지 읽기, '\n'을 만나면 읽기 중단
	cout << "주소는 " << address << "입니다\n" << endl; // 주소 출력

	string address2;
	cout << "주소를 입력하세요>>";
	getline(cin, address2); // 키보드로부터 주소 읽기. 변수 address에 저장
	cout << "주소는 " << address2 << "입니다\n"; // 주소 출력

}




#include < iostream>

전처리기

c/c++ 컴파일러는 컴파일 전에 전처리기(preprocessor)를 실행하여 #include문에 지정된 <헤더파일>의 텍스트 전체를 #include문이 있던 그 자리에 삽입한다. 이를 '헤더 파일의 확장'이라 한다. <헤더파일> 내에 또 다른 include 문이 있으면, 해당 위치에 또 '헤더 파일의 확장'이 발생하고, 모든 확장이 완료되면 전처리기는 종료된다.



#include <헤더 파일>과 #include "헤더 파일"의 차이

  • #include <헤더 파일> : 컴파일러가 설치된 폴더에서 '헤더 파일'을 찾으라는 지시
  • #include "헤더 파일" : 개발자의 프로젝트 폴더나 컴파일 옵션으로 지정한 include 폴더에서 '헤더 파일'을 찾으라는 지시

헤더 파일에는 무엇이 들어있나?

헤더 파일에는 strcpy()함수등의 선언만 들어 있으며, 컴파일할 때 strcpy() 함수를 호출하는 구문이 정확한지 판단하는데 사용된다. 또한, strcpy()함수의 코드는 이미 컴파일된 기계어 형태로 c 라이브러리에 들어있다.

cout과 cin은 어디에 선언되어 있나?

cout이나 cin은 모두 < iostream> 헤더 파일에 선언된 객체들이다.





Open Challenge - 가위 바위 보 게임

#include <iostream>
#include <cstring> //cstring과 string은 어떻게 다른가? cstring은 char 배열을 다루는 함수들이고, string은 문자열을 다루는 함수들이다.

using namespace std;

//if(s == "가위") 라고 하면 틀린다. 왜? s는 char 배열이기 때문에, s는 배열의 주소값이고, "가위"도 배열의 주소값이기 때문에, 둘의 주소는 같을 수 없다.


void decideWinner(char name1[], char s[], char name2[], char t[]) {
    if (strcmp(s, "가위") == 0 && strcmp(t, "바위") == 0)
        cout << name2 << "이 이겼습니다." << endl;
    else if (strcmp(s, "가위") == 0 && strcmp(t, "보") == 0)
        cout << name1 << "이 이겼습니다." << endl;
    else if (strcmp(s, "바위") == 0 && strcmp(t, "가위") == 0)
        cout << name1 << "이 이겼습니다." << endl;
    else if (strcmp(s, "바위") == 0 && strcmp(t, "보") == 0)
        cout << name2 << "이 이겼습니다." << endl;
    else if (strcmp(s, "보") == 0 && strcmp(t, "가위") == 0)
        cout << name2 << "이 이겼습니다." << endl;
    else if (strcmp(s, "보") == 0 && strcmp(t, "바위") == 0)
        cout << name1 << "이 이겼습니다." << endl;
    else
        cout << "비겼습니다." << endl;
}

int main() {
    cout << "가위 바위 보 게임을 합니다..." << endl;

    //이름을 입력 받는다.
    char name1[10];
    char name2[10];
    cout << "첫 번째 선수 이름 >> ";
    cin >> name1;
    cout << "두 번째 선수 이름 >> ";
    cin >> name2;

    //입력을 받는다. -> 주석으로 알고리즘을 미리 짜두면 좋다.

    while (true) {              //1이라고 하면 안 되고, true라고 해야 한다.
        cout << name1 << " >> ";
        char s[10];
        cin >> s;

        cout << name2 << " >> ";
        char t[10];
        cin >> t;


        //승자를 결정한다.
        decideWinner(name1, s, name2, t);

        cout << "계속(yes)? ";
        char res[10];
        cin >> res;
        if (strcmp(res, "yes") != 0)
            break;
    }
}

실습 13번 중식당 프로그램

내 코드교수님 코드
메모리 사용 최적화string 배열 menuName을 사용함으로써 메모리 추가 사용switch문을 사용하여 추가적인 메모리 사용 없이 동일한 결과 달성
코드 흐름의 명확성 (유효성 검사)각 메뉴 번호를 개별적으로 검사하는 방식은 유지 보수 시 오류 발생유효성 검사하는 조건이 더 명확•간결 코드의 가독성 향상 및 오류 발생 가능성 축소
프로그램 종료 처리break는 루프만 종료. 프로그램의 나머지 부분이 계속 실행될 여지를 남겨, 추가 코드가 있을 경우 문제 야기 가능성return 0;으로 main함수의 종료를 명확하게 나타냄

내 코드

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

bool checkInputError() {
	if (cin.fail()) { // 정수대신 문자열이 입력되어 오류가 발생하는 경우 대처. 부록 C의 예제 C-1참고
		cin.clear();
		cin.ignore(100, '\n');
		cout << "입력 오류" << endl;
		return true; // 오류 있음
	}
	else    return false; // 오류 없음
}

int main() {
    int menu, num;
    string menuName[] = {"짬뽕", "짜장", "군만두"};

    cout << "***** 승리장에 오신 것을 환영합니다. *****" << endl;
    while(true){
        cout << "짬뽕:1, 짜장:2, 군만두:3, 종료:4 >> ";
        cin >> menu;
        if(checkInputError()) continue;

        if(menu == 4) {
            cout << "오늘 영업은 끝났습니다." << endl;
            break; 
        }
        else if (menu != 1 && menu != 2 && menu !=3){
            cout << "다시 주문하세요!!" << endl;
            continue;
        }

        //입력이 정상적으로 이루어졌다면
        cout << "몇인분? ";
        cin >> num;
        if(checkInputError()) continue;
        cout << menuName[menu-1] << " " << num << "인분 나왔습니다" << endl;
    }
}


교수님 코드

int main() {
	int menu; // 1~4
	int num; // 몇인분

	cout << "***** 승리장에 오신 것을 환영합니다. *****" << endl;
	while (true) {
		cout << "짬뽕:1, 짜장:2, 군만두:3, 종료:4>>  ";
		cin >> menu;
		if (checkInputError()) continue; // menu에 정수 외 다른 입력하였는지 검사

		if (menu < 1 || menu > 4) {
			cout << "다시 주문하세요!!" << endl;
			continue;
		}
		else if (menu == 4) {
			cout << "오늘 영업은 끝났습니다." << endl;
			return 0;
		}

		// 입력이 정상적으로 이루어졌다면
		cout << "몇인분?";
		cin >> num;
		if (checkInputError()) continue; // num에 정수 외 다른 입력하였는지 검사
		if (num < 1) {
			cout << "다시 주문하세요!!" << endl;
			continue;
		}
		switch (menu) {
			case 1:
				cout << "짬뽕 " << num << "인분 나왔습니다" << endl;
				break;
			case 2:
				cout << "짜장 " << num << "인분 나왔습니다" << endl;
				break;
			case 3:
				cout << "군만두 " << num << "인분 나왔습니다" << endl;
				break;
		}
	}
}
profile
주니어 개발자

0개의 댓글