조건문과 반복문

Dingool95·2021년 8월 11일
0

C언어

목록 보기
4/5

기본 중의 기본인데, 헷갈리는 것들만 정리해보겠다.

생략가능

  • if, for, while 전부 다 실행문이 한 줄이면 중괄호를 생략해도 된다.
  • while은 일반적으로 변화식이 루프 본체에 포함되므로 생략할 일이 거의 없다.
  • 제어문 내부에 제어문이 존재할 때, 내부의 제어문이 생략가능하면 그것을 감싸고 있는
    제어문 역시 중괄호를 생략할 수 있다. -> 좋은 형태는 아닌듯하다.
  • if는 한 줄, else는 여러 줄일 때 if만 중괄호 생략 가능하다.




선택문

  • if : (만족되는 조건이 하나뿐일 때 사용)
  • if - else : (조건이 2개로 구분될 때 사용)
  • if - else if - else : (조건 3개 이상)
  • switch-case



삼항 연산자

값을 할당할 때 사용한다. if-else 문으로 완벽하게 바꿀 수 있다. if-else 문보다 코드의 길이를 획기적으로 줄일 수 있지만, 가독성이 좋지 않다는 단점이 있다. 잘 쓰이는 것 같지는 않다.

조건식이 참이면 값1, 거짓이면 값2가 결과값이다.


예시 1

#include <stdio.h>

int main(void)
{
	for (int i = 0; i < 10; ++i)
		printf("%d%c", i, (i < 9) ? ',' : '\n');
	
    return 0;
}
출력
0,1,2,3,4,5,6,7,8,9

그나마 가장 유용하게 사용한 예시이다. 반복문으로 출력할 때, 삼항 연산자를 활용해서 마지막 인덱스에서 자연스러운 출력을 가능하게 한다.


예시 2

#include <stdio.h>

int main(void)
{
	int num;
	scanf("%d", &num);
	printf("%d is a %s number\n", num, 
		(num > 0) ? "positive" : (num == 0) ? "zero" : "negative")	
	
	return 0;
}
입력
1

출력
1 is a positive number

이렇게 2단계로 작성가능하다. 앞에서부터 검사한다. 가장 앞의 num > 0 조건이 거짓일 경우에 뒤에 있는 삼항 연산자로 한 번 더 검사한다. 한 번만 써도 가독성이 떨어지는데 이건 너무하다. 혼자만 알아볼 수 있는 이런 방식으로 코드를 짜지 말자.



switch - case 문

조건식의 괄호에는 정수식만 가능하다. if-else 문보다 조건 검사 횟수가 적기 때문에 속도가 더 빠르다. 따라서 조건식이 정수식이라면 가능한 switch 분기문으로 바꿔주는 것이 좋다.

예시 1

#include <stdio.h>

int main(void)
{
	int score;
	scanf("%d", &score);
	
	char grade;
	switch (score / 10) {
	case 10:
	case 9:
		grade = 'A';
		break;		
	case 8:
		grade = 'B';
		break;		
	case 7:
		grade = 'C';	
		break;
	case 6:
		grade = 'D';	
		break;
	default:
		grade = 'F';	
	}
	printf("score: %d -- grade: %c\n", score, grade);
	return 0;
}

대표적인 예시다. 각 case마다 break를 걸어준다. 조건식의 결과값에 해당하는 case로 점프되고 그 지점부터 실행이 계속된다. 따라서 break를 걸어주지 않으면 그 case만 실행되는 것이 아니기 때문에 원치않는 결과가 나타날 수 있다. default는 if-else 문의 else와 같은 역할을 하는데, 어떤 case에도 해당되지 않으면 default로 넘어온다. default는 마지막에 있기 때문에 굳이 break를 걸지 않아도 된다. 써주기도 하던데 어떤 차이가 있는지 잘 모르겠다.


예시 2

#include <stdio.h>

int main(void)
{
	int num;
	scanf("%d", &num);

	switch (num) {
	case 1:
	case 2:
		printf("1 또는 2입니다.\n");
		break;		
	case 3:		
	case 4:
		printf("3 또는 4입니다.\n");	
		break;
	default:
		printf("default\n");	
	}
	return 0;
}

break를 걸어주지 않아서 다음 case까지 넘어가는 것을 fall through 라고 한다. 예시 2와 같이 유용하게 사용할 수 있는 경우가 많다. 이렇게 활용하려면 동일한 실행을 하는 case가 연속되어야함을 주의하자.





반복문

  • for
  • while
  • do-while



for 문

for 문은 아래와 같이 작성된다.

for문에서 사용될 변수 i를 for문 내부의 초기화에서 선언해도 되고, for문 외부에서 미리 선언해도 된다. for문 내에서 선언하는 것이 최신 문법인 것 같다. 필요에 따라서 for문 외부에서 선언하기도 하는데, 루프를 종료한 후에 for문에서 사용된 루프 인덱스 i의 값이 필요할 때 주로 외부에서 선언한다. 증감에서 일반적으로 i++로 많이쓴다. 근데 내부적으로 i++ 원래 값을 증가시키고 결과값은 증가시키기 전의 값이라서 따로 저장이 필요하다. ++i에 비해서 메모리를 더 사용하는 것이다. 뭔 큰 차이가 있겠냐만은 그렇다고 하니까 나는 ++i로 사용하겠다.



위와 같은 순서로 for문이 실행된다. 루프 인덱스 i가 초기화 되거나 증감이 이루어진 후에 먼저 조건을 확인하고 조건이 만족되었을 때 루프 본체로 넘어가서 실행문이 실행된다. 이런 순서로 진행되므로 루프가 종료될 때 i에 저장된 최종값은 조건식 i < 3에 해당되지 않는 3이다.



while 문

while문 외부에서 제어 변수가 선언되어야 하고 내부에는 반드시 제어변수의 증감이 필요하다. 예시1이 가장 일반적인 형태이지만, 예시2와 같이 무한루프와 break를 활용하는 것이 더 편할 때도 많다.

예시1

#include <stdio.h>

int main(void)
{
    int i = 1; // 제어변수 초기화
    
    while (i <= 10) { // 조건식
        printf("%d ", i);
        ++i;	// 증감
    }
    return 0;
}

예시2

#include <stdio.h>

int main(void)
{
    int i = 1;
    
    while (1) {
    	if (i > 10)
            break;
        printf("%d ", i);
        ++i;
    }
    return 0;
}




do-while 문

while문과 달리 조건과 상관없이 무조건 한 번은 실행된다. 수치해석을 수행할 때 주로 while문을 사용하는데, 조건을 검사하기 위해서는 루프를 한 번 돌린 결과값이 필요할 경우가 있다. 이 때 루프 본체의 긴 코드를 while문 앞에 한 번 더 써줘야 한다. 함수로 빼기에도 두 번 밖에 안 쓰기 때문에 애매하다. 이 때 사용하면 좋다. 그 외에는 굳이 사용할 필요는 없을 것 같다. 파이썬에는 없는 C만의 문법이다. 아래는 앞선 while문의 예시1을 do-while로 똑같이 구현한 것이다.

#include <stdio.h>

int main(void)
{
    int i = 1;	// 제어 변수(초기식)
    
    do {
        printf("%d ", i);
        ++i;	// 증감
    } while (i <= 10); 	// 조건식
    
    return 0;
}

조건식이 마지막에 나오고, 세미콜론이 끝에 붙는다는 것을 주의하자.

profile
내 맘대로 요점정리

0개의 댓글