본문 바로가기

C++

[TIL 4장] 반복문(feat. break, continue), 난수, time(), typedef

오늘의 TIL 목차 (22.07.28)

 

  • 반복문 (while, do while)
  • 난수 (rand(), srand(a))
  • time()

반복문


1. while문               2. do while문

[ While문 ]

: 조건식이 참이면 while문 안의 코드 블럭을 반복 실행한다.

 

while(조건식) //조건식이 참이면 실행
{
코드 블럭
}

 

■ '어떤 기능' / '언제' 사용 용도

- while문은 주로 '조건'에 따라 반복할 때 사용

- 무한 루프나 특정 조건에 만족할 때까지 반복해야하는 경우

- 주로 파일을 읽고 쓰기에 많이 사용 

■ 예시

int iCount = 3;

	while (5) // 5번 실행이 아닌 값 자체로 인식하여 '참'으로 간주
	{
		if (0 == iCount)
			break; // 반복문을 빠져나가는 명령문

		cout << 1 << endl;
		--iCount; // iCount = 3이므로 3번 실행, 4번째 때 break;
	}

출력결과:
1
1
1
int iCount = 0;
while (true)
	{
		if (3 <= iCount) // iCount가 3보다 크거나 같다면 반복문 종료
			break;

		++iCount; // iCount 1 증가
		cout << iCount << "번째 rand()" << endl << "=======" << endl;
		cout << rand() << endl;
		cout << rand() << endl;
		cout << endl;
	}
    
출력 결과:
1번째 rand()
==========
32423
45

2번째 rand()
==========
235
2

,, 총 2번 출력

 

[ do while문 ]

: 무조건 1번 실행한 뒤 조건식을 판별하여 참일 경우 do while문 안의 코드 블럭을 반복 실행한다.

 

do{
코드블럭
}while(조건식);

 

■ '어떤 기능' / '언제' 사용 용도

- 무조건 수행문을 한 번 실행한 후 while문을 동작시키고 싶을 때

■ 예시

int iCountDo = 3;

do
	{
		cout << 1 << endl;
	} while (--iCountDo); //전위 연산이라 즉시 2로 조건 판별, 후위 연산일 경우 3으로 판별 후 감소

출력결과:
1 // 무조건 한 번 실행
1 // iCountDo가 2 - 참
1 // iCountDo가 1 - 참

 

[ 반복문 특이사항 ]

  • 조건식에 대입식이 들어가도 0이 아니라면 '참'으로 인지
  • OR 연산 시 하나만 참이어도 되기 때문에 앞 순서에 참이 있다면 뒤 조건은 보지 않고 명령문 실행
  • 해당 조건식이 OR일 경우 참일 때 해당 조건(대입)이 맨 처음 참이라면 대입 적용,
    처음 참 값이 아니라면 뒤 조건을 보지 않기 때문에 대입 적용되지 않고 명령문 실행
int iTest(0), iA(10), iB(20);

	if ((iA < iB) && (iB = 5)) // iB = 5도 값이므로 참으로 인식(0 제외 참), 참 실행 시 대입 적용
		cout << iB << endl; // 출력값: 5

	if ((iA < iB) || (iB = 0)) // iB는 5인 상태 즉, 10 < 5 거짓 || iB = 0은 0으로 거짓
		cout << iB << endl; // 조건 거짓으로 실행 안됨

	if ((iA > iB) || (iB = 100)) // iB는 현재 0, iA > iB 참 || iB = 100도 참
		cout << iB << endl;  // 출력값 : 0

	/*OR 연산자는 하나만 참이어도 코드블럭을 실행하기 때문에
	앞의 iA > iB 가 참이므로 뒤 조건을 읽지 않고 명령문 실행
	즉, iB = 100은 대입되지 않은 원래의 0으로 출력*/

	if ((iB = 100) || (iA = 50)) //둘 다 참이지만 OR이라 가장 맨 처음의 참값만 적용됨
		cout << iB << "\t" << iA << endl; // 출력값 : 100	10, 
        
출력결과:
5
0
100	10

[ break문 ]

: 이스케이프문으로 반복문과 switch문 안에서'만' 사용 가능한 한 탈출 명령문

// 반복문
반복문{
break;
}

// switch문
switch(a)
{
case 1:
	break;
case 2:
	break;
}

 

■ '어떤 기능' / '언제' 사용 용도

- 반복문 안에서의 break;는 반복문을 탈출하는 역할

-  switch의 case 안에서의 break;는 해당 case의 코드블럭을 break;를 만날 때까지 실행 (멈춤 역할)

- if문 단독으로 사용할 수 없고 반복문과 같이 사용되어 반복문을 벗어나도록 할 때 쓰인다.

■ 예시

bool bCheck = true;

while(true)
{
	cout << "First while()" << endl;
    while(true)
    {
    	cout << "Second while()" << endl;
        break; //해당 second while()의 while문만 벗어남
    }
}

출력결과:
First while()
Second while()
First while()
First while()
,, 무한루프

 

[ continue ]

: 반복문(for, while, do-while) 안에서만 사용하며 바로 for문 - 증감식, while문 - 조건식으로 이동시키는 명령문

 

■ '어떤 기능' / '언제' 사용 용도

- for문 안에서 continue;를 만나면 아래 내용을 수행하지 않고 증감식으로 이동

- while문, do-while문 안에서 continue;를 만나면 아래 내용을 수행하지 않고 조건식으로 이동

 

■ 예시

if(int i = 0; i< = 10; i++)
{
	if(i % 2 != 0) // 2로 나눈 나머지가 0이 아닐 경우(홀수인 경우)
    	continue; // 아래 내용을 수행하지 않고 바로 for의 증감식으로 이동
    cout << i << " ";
}

출력결과:
1 3 5 7 9

 

난수


난수 : 순서나 규칙이 없는 무작위 수

1. rand() 함수           2. srand(a) 함수

[ rand() ]

: 0 ~ 32767 사이 값을 무작위로 추출하는 함수 (signed short의 양수 표현 범위)

 

rand();  // 랜덤 시드값 x의 난수표에 있는 무작위 수를 순서대로 출력

■ 원리

- for문 안에서 continue;를 만나면 아래 내용을 수행하지 않고 증감식으로 이동

- while문, do-while문 안에서 continue;를 만나면 아래 내용을 수행하지 않고 조건식으로 이동

■ 예시

iCount = 0;
	while (true)
	{
		if (2 <= iCount) // iCount가 3보다 크거나 같다면 반복문 종료
			break;
            
		++iCount;
		cout << iCount << "번째 rand() : " << endl;
		cout << rand() << endl;
		cout << rand() << endl;
		cout << endl;
	}
 
첫번째 출력결과: // 무작위 시드값이 3이었다면
1번째 rand():
79
843

2번째 rand();
765
17
----------------
두번째 출력결과: // 재컴파일 시 동일한 값 출력
1번째 rand():
234
43

2번째 rand():
5432
98

※ 재컴파일해도 한 번 추출한 값은 동일한 시드값의 난수표에서 순서대로 추출하기 때문에 계속 동일한 값이 나옴

→ 이를 해결하기 위해 rand()의 시드값 (난수표 번호)를 바꿔주는 srand(시드값) 사용

 

[ srand() ]

:  () 안에 seed 값을 넣어서 난수표를 바꿔주는 함수

 

srand(5); // 5번 난수표로 바꿔줌
srand(unsigned(time(NULL))); // 계속 변하는 수(시간sec)에 해당하는 seed 값으로 바꿔줌

■  예시

 

iCount = 0;
	while (true)
	{
		if (2 <= iCount) // iCount가 3보다 크거나 같다면 반복문 종료
			break;

		// 반복문으로 다시 실행될 때, 5번 난수표의 첫번째부터 다시 추출
		srand(5); // 5번 난수표로 시드값을 바꿔줌
		++iCount;
		cout << iCount << "번째 rand() : " << endl;
		cout << rand() << endl;
		cout << rand() << endl;
		cout << endl;
	}
    
첫번째 출력결과:
1번째 rand() :
54
28693
 
2번째 rand() :
54
28693
-------------
두번째 출력결과:
1번째 rand() :
54
28693
 
2번째 rand() :
54
28693

※ srand(5)처럼 시드값을 지정한 경우, 반복문 시 반복될 때 5번 난수표의 첫번째 값부터 다시 출력됨

※ 시드값을 바꿔도 바뀐 시드값의 난수표가 추출되면서 고정되기 때문에 동일한 값이 나옴

→ 이를 해결하기 위해 '실시간으로 변하는 수'인 시간 time() 함수를 이용

 

[ time() ]

: 1970년 1월 1일 0시 0분부터 경과된 시간을 초단위로 추출하는 함수

 

#include <time.h> // <ctime>, 헤더파일 포함해줘야 time 사용 가능

time(NULL); // time은 포인터라 0 대신 NULL로 표기하기로 약속

 

■ 예시

/* typedef 는 자료형(int, bool, char, -)을 사용자가 지정한 이름으로 대체 사용할 수 있게 정의하는 것
컴터가 정의한 typedef
typedef long long _64bit;
typedef _64bit time_t;
*/
time_t tTemp = 0;

cout << time(&tTemp) << endl; // time은 포인터기에 주소값(&)을 받아야 함

출력결과:
2305802385 (경과 시간을 초로 반환한 값)

 

< srand(unsigned(time(NULL))); 적용 예시 >

- 이 코드에서 time()은 '실시간으로 변하는 수'로 인식

- 컴파일 할 때마다 time()이 바뀌어 시드값이 바뀌었으므로 출력값 다름

iCount = 0;

	while (true)
	{
		if (2 <= iCount) // iCount가 3보다 크거나 같다면 반복문 종료
			break;

		srand(unsigned(time(NULL))); // time(NULL)이 범위 초과할 수 있으니 unsigned
		++iCount;

		cout << iCount << "번째 rand() : " << endl;
		cout << rand() << endl;
		cout << rand() << endl;
		Sleep(1000);
		cout << endl;
}

첫번째 출력결과:
1번째 rand():
23424
89

2번째 rand():
324
5
---------------------------------
두번째 출력결과: //재컴파일 시 시간이 변해 시드값이 변했기 떄문에 다른 난수표의 rand()값이 출력됨
1번째 rand():
32565
78

2번째 rand():
238
87