![article thumbnail image](https://blog.kakaocdn.net/dn/bCR1os/btqDEZxovww/8ik6OtkgCeaGImqQFm9E5k/img.png)
제어 흐름 개요 Control flow
CPU가 해야 할 일을 조금 더 복잡하게 만들어 줄 수 있음, 흐름을 제어할 수 있음
순서도(Flow Chart)
1. 중단(Halt)
2. 점프(Jump): goto, break, continue
3. 조건 분기(Conditional branches): if, switch
4. 반복(루프)(Loops): while, do-while, for
5. 예외 처리(Exceptions): try, catch, throw
#include <iostream>
#include <cstdlib> // exit
int main()
{
using namespace std;
cout << "I love you " << endl;
exit(0); // 코드 어디에 있든 긴급하게 종료 가능
return 0; // return 타입에 맞춰서 return해 줘야 함
cout << "I love you, too" << endl;
return 0;
}
조건문 if
#include <iostream>
int min(int x, int y)
{
//if (x > y) return y;
//else return x;
return (x > y) ? y : x;
}
int main()
{
using namespace std;
int x;
cin >> x;
if (x > 10)
{
cout << x << " is greater than 10" << endl;
cout << "Test 1" << endl;
}
else
cout << x << " is not greater than 10" << endl;
cout << "Test 1" << endl; // else문 밖임! block 필요!
if (1) // 0이 아니면 true임!! 주의
int x = 5; // if문 block을 벗어나는 순간 사라짐에 주의!!
else
int x = 6;
cout << x << endl;
if (x > 10)
cout << "x is greater than 10" << endl;
else if (x < 10)
cout << "x is less than 10" << endl;
else // if (x == 10)
cout << "x is 10" << endl;
if (x >= 10)
{
if (x >= 20)
cout << "x is between 10 and 20" << endl;
else
cout << "..." << endl;
}
int y;
cin >> y;
if (x > 0 && y > 0) // 둘 다 양수
cout << "both numbers are positive" << endl;
else if (x > 0 || y > 0) // 둘 중에 하나만 양수
cout << "one of the numbers is positive" << endl;
else
cout << "Neither number is positive" << endl;
if (x > 10)
cout << "A" << endl;
else if (x == -1)
return 0; // 프로그램을 중단시키는 것도 가능
else if (x < 0)
cout << "B " << endl;
// null statement 조심!
if (x > 10);
{
x = 1;
}
// x = 0; if(x)
if (x = 0) // if (x == 0) 주의!
cout << x << endl;
return 0;
}
switch-case
특별한 경우 간결하고 깔끔하게 코딩을 할 수 있음
#include <iostream>
using namespace std;
enum class Colors
{
BLACK,
WHITE,
RED,
GREEN,
BLUE
};
void printColorName(Colors color)
{
/*if (color == Colors::BLACK)
cout << "Black" << endl;
else if (color == Colors::WHITE)
cout << "White" << endl;*/
switch (static_cast<int>(color))
{
case 0:
cout << "Black" << endl;
break;
case 1:
cout << "White" << endl;
break;
case 2:
cout << "Red" << endl;
break;
case 3:
cout << "Green" << endl;
break;
case 4:
cout << "Blue" << endl;
break;
default:
break;
}
}
int main()
{
printColorName(Colors::BLACK);
int x;
cin >> x;
{
int y1 = 0; // 차라리 이쪽에 선언하는 것이 좋고(1)
switch (x)
{
int a;
//int b = 5; 초기화 불가능! error C2360: initialization of 'b' is skipped by 'case' label
case 0:
int y; // case문 안에 선언해도 위에 int a처럼 똑같이 작동함
break; // switch를 빠져나감
case 1:
y = 5;
cout << y << endl;
break;
case 2:
{
// 또는 case문 전체를 블록으로 싸서 사용하자(2)
int y = 0;
cout << y << endl;
break;
}
default:
cout << "Undefined input " << x << endl;
break; // 없어도 됨
}
}
cout << endl;
return 0;
}
goto
CPU가 일을 하다가 goto문을 만나면 가라는 곳으로 감
무엇을 할지 생각하고 반복하는 방향으로 코딩을 하기 때문에 goto문은 거의 사용하지 않음
#include <iostream>
#include <cmath> //sqrt
int main()
{
using namespace std;
double x;
tryAgain : //label
cout << "Enter a non-negative number" << endl;
cin >> x;
if (x < 0.0)
goto tryAgain;
cout << sqrt(x) << endl;
return 0;
}
#include <iostream>
int main()
{
using namespace std;
// error! transfer of control bypasses initialization of: variable "x"
//goto skip;
int x = 5;
skip:
x += 3;
return 0;
}
반복문 while
정확하다, 반복을 지루해하지 않는다
#include <iostream>
int main()
{
using namespace std;
//cout << 1 << endl;
//cout << 2 << endl;
// ...
//cout << 9 << endl;
cout << "While-loop test" << endl;
int count = 0; // 몇 번 돌릴 건지
while (1) // 괄호가 true(0이 아님)인 경우 반복
{
//int count = 0; // 여기에 선언해서 출력하면 계속 0만 출력됨, static 붙이면 OK
cout << count << endl;
++count;
if (count >= 10) break;
}
// unsigned int를 사용하면 문제가 생길 수 있다! 10 9 ... 1 0 4294967295
// unsigned가 signed보다 빠른 것 같기 때문에 꼭! 사용하지 말라는 것은 아니다
unsigned int count_u = 10;
/*
while (count_u >= 0)
{
if (count_u == 0) cout << "Zero";
else cout << count_u << " ";
count_u--;
}
*/
count = 1;
while (count < 100)
{
if (count % 5 == 0) cout << "Hello " << count << endl;
count++;
}
int outer_count = 1;
while (outer_count <= 5)
{
int inner_count = 1;
while (inner_count <= outer_count)
{
cout << inner_count++ << " ";
}
cout << endl;
++outer_count;
}
return 0;
}
#include <iostream>
int main()
{
using namespace std;
// while문을 goto문으로 바꿔 보기
int count = 0;
replay:
cout << count;
if (++count <= 10)
{
cout << "\tgoto" << endl;
goto replay;
}
return 0;
}
반복문 do-while
#include <iostream>
int main()
{
using namespace std;
int selection; // must be declared outside do/while loop!!
do
{
cout << "1. add" << endl;
cout << "2. sub" << endl;
cout << "3. mult" << endl;
cout << "4. div" << endl;
cin >> selection;
} while (selection <= 0 || selection >= 5);
// do-while 끝에 semicolon 필수!!
cout << "You selected " << selection << endl;
return 0;
}
반복문 for
#include <iostream>
int pow(int base, int exponent)
{
int result = 1;
//for (int count = 1; count <= exponent; count++) 가능
for (int count = 0; count < exponent; count++)
result *= base;
return result;
}
int main()
{
using namespace std;
/*
1. int count = 0;
2. count < 10 == true ~> 블럭 실행
3. ++count
4. count < 10 == true ~> 블럭 실행
false ~> for문 종료
*/
//int count = 0;
//for(; count < 10; ++count) 가능
for (int count = 0; count < 10; ++count) // iteration
{
cout << count << endl;
}
//while (true)
//for(;;++count) == for(; true; ++count)
cout << pow(2, 4) << endl;
cout << pow(3, 5) << endl;
for (int count = 9; count >= 0; count -= 2)
{
cout << count << endl;
}
for (int i = 0, j = 0; (i+j) < 10; i++, j += 2)
{
cout << i << " " << j << endl;
}
for (int j = 0; j < 9; j++)
{
for (int i = 0; i < 9; i++)
{
cout << i << " " << j << endl;
}
}
/* while문 예제와 마찬가지로 문제가 있는 코드!!
for (unsigned int i = 9; i >= 0; i--)
{
cout << i << endl;
}
*/
return 0;
}
#include <iostream>
using namespace std;
int getNumber()
{
int tmp;
while (true)
{
cin >> tmp;
if (std::cin.fail()) // 실패했을 경우 return true
{
std::cin.clear();
std::cin.ignore(32767, '\n'); // 버퍼 비우기, 32767=적당히 큰 숫자
cout << "유효하지 않은 숫자입니다. 다시 입력해 주세요." << endl;
}
else
{
std::cin.ignore(32767, '\n');
return tmp;
}
}
}
int main(void)
{
cout << "1. 구구단 출력" << endl;
cout << "시작할 단을 입력해 주세요: ";
int start = getNumber();
cout << "끝낼 단을 입력해 주세요: ";
int end = getNumber();
cout << endl;
for (int i = start; i <= end; i++)
{
for (int j = 1; j <= 9; j++)
{
cout << i << " * " << j << " = " << i * j << "\t";
if (j % 3 == 0) cout << endl;
}
cout << endl;
}
cout << endl;
cout << "2. 1부터 20까지 짝수만 출력하기" << endl;
for (int i = 1; i <= 20; i++)
{
if (i % 2 == 0) cout << i << "\t";
if (i % 10 == 0) cout << endl;
}
cout << endl;
cout << "3. 0부터 10까지 더하기" << endl;
int result = 0;
for (int i = 1; i <= 10; i++)
{
result += i;
if (i == 1) cout << i;
else cout << " + " << i;
if (i == 10) cout << " = " << result << endl;
}
return 0;
}
break, continue
#include <iostream>
using namespace std;
void breakOrReturn()
{
while (true)
{
char ch;
cin >> ch;
if (ch == 'b')
break;
if (ch == 'r')
return;
}
// break는 Hello 출력 / return은 함수 탈출
cout << "Hello" << endl;
}
int main()
{
int count = 0;
while (true)
{
cout << count << endl;
if (count == 2) break; // 현재 블럭에서 빠져나감
count++;
}
breakOrReturn();
for (int i = 0; i < 10; i++)
{
//if (i % 2 == 1) cout << i << endl;
// continue는 아랫부분을 실행하지 않고 for문의 i++ 실행
if (i % 2 == 0) continue;
cout << i << endl;
}
int count2(0);
do
{
if (count2 == 5)
continue;
cout << count2 << endl;
} while (++count2 < 10);
/*
이렇게 코딩하면 count2==5인 경우, continue로 인해 count2++이 진행 X(무한루프)
while문이나 do-while문은 for문보다 조금 까다로울 수 있음
do
{
if (count2 == 5)
continue;
cout << count2 << endl;
count2++;
} while (count2 < 10);
*/
// break가 조건보다 편한 경우
// flag 사용
int count3(0);
bool escape_flag = false;
while (!escape_flag)
{
// 사용자 정의 변수 등을 사용하면 느려질 수 있음, 밖으로 빼는 게 좋음
char ch;
cin >> ch;
cout << ch << " " << count3++ << endl;
if (ch == 'x')
escape_flag = true;
}
int count4(0);
// break 사용
while (true)
{
char ch;
cin >> ch;
cout << ch << " " << count4++ << endl;
if (ch == 'x')
break;
}
return 0;
}
난수 만들기 random numbers
#include <iostream>
#include <cstdlib> // std::radn(), std::srand()
#include <ctime> // std::time()
#include <random>
unsigned int PRNG() // Pseudo Random Number Generator
{
static unsigned int seed = 5523; // seed number: 시작하는 숫자
seed = 8253729 * seed + 2396403; // overflow를 이용
return seed % 32768;
}
int getRandomNumber(int min, int max)
{
// RAND_MAX: 랜덤으로 나올 수 있는 가장 큰 숫자
// 나누기가 느리기 때문에 결과를 저장해서 사용
static const double fraction = 1.0 / (RAND_MAX + 1.0);
return min + static_cast<int>((max - min + 1)*(std::rand()*fraction));
}
int main()
{
using namespace std;
cout << "PRNG()" << endl;
for (int count = 1; count <= 20; count++)
{
cout << PRNG() << "\t";
if (count % 5 == 0) cout << endl;
}
cout << endl;
cout << "srand()" << endl;
//std::srand(5323); // seed 설정
// seed number가 고정되어 있으면 다른 숫자를 출력할 수 없음, 디버깅 시에는 숫자 고정
std::srand(static_cast<unsigned int>(std::time(0)));
for (int count = 1; count <= 20; count++)
{
cout << std::rand() << "\t";
if (count % 5 == 0) cout << endl;
}
cout << endl;
cout << "getRandomNumber(int,int)" << endl;
for (int count = 1; count <= 20; count++)
{
cout << getRandomNumber(5,8) << "\t";
if (count % 5 == 0) cout << endl;
}
cout << endl;
cout << "rand() 5~8 출력" << endl;
for (int count = 1; count <= 20; count++)
{
// 단, 범위가 크면 특정 숫자로 몰리는 현상이 발생할 수 있음
cout << rand() % 4 + 5 << "\t";
if (count % 5 == 0) cout << endl;
}
cout << endl;
// C++ 11부터 추가됨!!
std::random_device rd;
// create a mesenne twister
// mt19937: 알고리즘 관련, mt19937_64는 64비트 난수
std::mt19937 mersenne(rd());
// 1 ~ 6 중 선택되는데, 확률은 전부 동일함
std::uniform_int_distribution<> dice(1, 6);
cout << "random_device" << endl;
for (int count = 1; count <= 20; count++)
{
cout << dice(mersenne);
if (count % 5 == 0) cout << endl;
}
return 0;
}
std::cin 더 잘 쓰기
cin에 의도하지 않은 입력이 들어왔을 때, 어떻게 대응해야 할지?
#include <iostream>
using namespace std;
int getInt()
{
while(true){
cout << "Enter an integer number : ";
int x;
cin >> x;
if (std::cin.fail()) // 실패했을 경우 return true
{
std::cin.clear();
std::cin.ignore(32767, '\n'); // 버퍼 비우기, 32767=적당히 큰 숫자
cout << "Invalid number, please try again" << endl;
}
else
{
std::cin.ignore(32767, '\n');
return x;
}
}
}
char getOperator()
{
while (true)
{
cout << "Enter an operator (+, -) : "; // TODO: more operators *, / etc.
char op;
cin >> op;
std::cin.ignore(32767, '\n');
if (op == '+' || op == '-')
return op;
else
cout << "Invalid operator, please try again" << endl;
}
}
void printResult(int x, char op, int y)
{
// TODO: change this to switch-case
if (op == '+') cout << x + y << endl;
else if (op == '-') cout << x - y << endl;
else
{
cout << "Invalid operator" << endl;
}
}
int main()
{
int x = getInt();
char op = getOperator();
int y = getInt();
printResult(x, op, y);
return 0;
}
#include <iostream>
using namespace std;
int getInt()
{
int x;
while (true) {
cout << "Enter an integer number : ";
cin >> x;
if (std::cin.fail())
{
std::cin.clear();
std::cin.ignore(32767, '\n');
cout << "Invalid number, please try again" << endl;
}
else
{
std::cin.ignore(32767, '\n');
return x;
}
}
}
char getOperator()
{
char op;
while (true)
{
cout << "Enter an operator (+, -, *, /) : ";
cin >> op;
std::cin.ignore(32767, '\n');
if (op == '+' || op == '-' || op == '*' || op == '/')
return op;
else
cout << "Invalid operator, please try again" << endl;
}
}
void printResult(int x, char op, int y)
{
double result = 0;
switch (op)
{
case '+':
result = x + y;
break;
case '-':
result = x - y;
break;
case '*':
result = x * y;
break;
case '/':
result = static_cast<double>(x) / y;
break;
default:
cout << "Invalid operator" << endl;
return;
}
cout << result << endl;
}
int main()
{
int x = getInt();
char op = getOperator();
int y = getInt();
printResult(x, op, y);
return 0;
}
해당 포스트는 '홍정모의 따라하며 배우는 C++' 강의를 수강하며 개인 백업용으로 메모하였습니다.
인프런: https://www.inflearn.com/course/following-c-plus
홍정모의 따라하며 배우는 C++ - 인프런
만약 C++를 쉽게 배울 수 있다면 배우지 않을 이유가 있을까요? 성공한 프로그래머로써의 경력을 꿈꾸지만 지금은 당장 하루하루 마음이 초조할 뿐인 입문자 분들을 돕기 위해 친절하고 자세하게 설명해드리는 강의입니다. 초보로 시작하더라도 중급을 넘어 고급 프로그래머로 가는 길목에 들어서고 싶으시다면 최고의 디딤돌이 되어드리겠습니다. 여러분의 꿈을 응원합니다! 초급 프로그래밍 언어 C++ 온라인 강의 C++
www.inflearn.com