학교 수업 복습을 위해 작성하였습니다! 생능출판사의 '명품 C++ 프로그래밍' 교재를 사용하며, 저자인 황기태 교수님의 강의를 기반으로 합니다.
제네릭 프로그래밍은 제네릭 함수와 제네릭 클래스를 활용하여 프로그램을 작성하는 프로그래밍 패러다임이다.
소스파일 -> 컴파일 -> 목적파일 -> 링킹 -> 실행파일 -> 실행
(hello.cpp) -> (hello.obj) -> (hello.exe)
전처리기(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;
std::
namespace는 개발자가 자신만의 고유한 이름 공간을 만들어 클래스 등의 이름 충돌을 방지한다.
::
는 범위 지정 연산자로서 c++ 표준 연산자이다.
std::
는 c++ 표준 이름 공간으로, c++ 표준 라이브러리에서 선언된 이름을 사용할 때 붙인다.
using 지시어를 이용하여 std::를 생략할 수 있다.
using std::cout; //cout에 대해서만 std::생략
using namespace std; //std 이름 공간에 선언된 모든 이름에 대해 std::생략
cin.getline(char buf[ ], int size, char delimitChar)
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"; // 주소 출력
}
c/c++ 컴파일러는 컴파일 전에 전처리기(preprocessor)를 실행하여 #include문에 지정된 <헤더파일>의 텍스트 전체를 #include문이 있던 그 자리에 삽입한다. 이를 '헤더 파일의 확장'이라 한다. <헤더파일> 내에 또 다른 include 문이 있으면, 해당 위치에 또 '헤더 파일의 확장'이 발생하고, 모든 확장이 완료되면 전처리기는 종료된다.
헤더 파일에는 strcpy()함수등의 선언만 들어 있으며, 컴파일할 때 strcpy() 함수를 호출하는 구문이 정확한지 판단하는데 사용된다. 또한, strcpy()함수의 코드는 이미 컴파일된 기계어 형태로 c 라이브러리에 들어있다.
cout이나 cin은 모두 < iostream> 헤더 파일에 선언된 객체들이다.
#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;
}
}
내 코드 | 교수님 코드 | |
---|---|---|
메모리 사용 최적화 | 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;
}
}
}