본문 바로가기

Studying/정보처리기사

[정보처리기사 실기]_C언어 특강(2)

11번

#include<stdio.h>

int f(int a, int b) {
	int s;
	s = a + b + 1;
	return s;
}
void main() {
	int x, y, i, j;
	x = 10;
	y = ++x;
	i = --x / 2;
	j = y % 7 + i++;
	printf("%d\n", f(y, j));
}

 

1) 프로그램은 main 함수가 먼저 시작되니 main 함수 먼저 보기.

 

2) int x, y, i, j;

 : 정수형 변수 x, y, i, j 선언.

 

3) x = 10;

 : x에 10을 저장.

 

4) y = ++x;  

 : y = ++x에서 ++가 전위연산자이므로 x에 1 증가 후 y에 대입하면 y = 11. (x = 11)

 

5) i = --x / 2;

 : i = --x / 2에서 현재 x는 11이지만 --가 전위연산자이므로 x에 1 감소 후 2로 나누면 10 / 2가 되기 때문에 몫인 5를 j에 대입하면 i = 5 (x = 10)

 

6) j = y % 7 + i++;

 : j = y % 7 + i++에서 먼저 y % 7을 계산. %는 몫이 아닌 나머지를 반환.

 현재 y는 11이므로 11 % 7 = 4이고, 4 + i++ 계산하면 ++는 후위 연산자이므로 계산 후에 ++ 연산 실행. 현재 i는 5이므로 4 + 5 = 9. j = 9 저장 후 i = 6으로 증가.

 

7) f(y, j) : 출력 하기 전 f(y, j) 함수 호출. 이때 매개변수 y와 j가 함수 f의 인수로 전달

int f(int a, int b) {
	int s;
	s = a + b + 1;
	return s;
}

8) 함수를 살펴보면 int a, int b는 전달받은 y와 j의 값. 즉 a = 11, b = 9.

정수형 변수 s 선언 후 s = a + b + 1 = 11 + 9 + 1 = 21

return s이므로 21이 반환됨.

 

9) printf("%d\n", f(y, j));

 : 출력하면 21 정수로 출력

 

[출력]

21

12번

#include<stdio.h>
#define PRE(x) x * x

int main() {
	int a;
	a = 100 / PRE(3 + 7);
	printf("%d", a);
}

 

1) #define PRE(x) x * x

 : 매크로 PRE(x) 선언.

헷갈리지 말아야 할 것은 연산하지 않고, 매크로 형식 그대로 입력해서 연산해야 함. (매크로는 단순히 텍스트 치환이 일어난 것)

 

2) int a;

 : 정수형 변수 a 선언.

 

3) a = 100 / PRE(3 + 7);

 : PRE(3 + 7)은 매크로로 선언한 x가 3 + 7인 것. (계산 노노!!) 그대로 작성하면 a = 100 / 3 + 7 * 3 + 7.

계산하면 우선순위 높은 /, *먼저 연산되므로 100 / 3은 정수 / 정수이므로 정수인 몫을 반환하므로 33이고, 7 * 3 = 21

따라서 계산하면 33 + 21 + 7 = 61

 

4) printf("%d", a);

 : a의 값을 정수로 출력하면 a = 61

 

[출력]

61

13번

#include<stdio.h>

#define sum1(a, b) a + b

int sum2(int a, int b) {
	return a + b;
}
void main() {
	int s1, s2;
	s1 = 3 * sum1(2, 7);
	s2 = 3 * sum2(2, 7);
	printf("%d, %d\n", s1, s2);
}

 

1) main 함수가 먼저 시작하는 것을 확인.

 

2) int s1, s2;

 : 정수형 변수 s1, s2 선언.

 

3) s1 = 3 * sum1(2, 7);

 : s1 변수에 매크로로 정의된 sum1(2, 7)을 계산.

 매크로는 단순히 텍스트 치환이므로 계산하는 것이 아닌 그대로 작성하기 때문에

 sum1(2, 7) = 2 + 7이 되고, 계산하면 s1 = 3 * 2 + 7 = 13(* 연산 먼저 수행) 이므로 s1 = 13.

 

4) s2 = 3 * sum2(2, 7);

 : s2 변수에 매크로가 아닌 sum2 함수를 호출하게 됨. 따라서 sum2 함수를 보면 int a, int b 인자를 받고 return a + b를 반환함.

 a = 2, b = 7 이기 때문에 return a + b = 2 + 7 = 9를 반환. 따라서  s2 = 3 * 9 = 27이므로 s2 = 27.

 

5) printf("%d, %d\n", s1, s2);

 : s1, s2를 정수로 출력하면 s = 13, s2 = 27

 

[출력]

13, 27

14번

#include<stdio.h>

void main() {
	int i, j, k = 0;
	for (i = 0; i <= 10; i++) {
		for (j = 0; j < 10; ++j) {
			if (i > 7) continue;
			k = k + 1;
			if (j >= 3) break;
		}
	}
	printf("%d\n", k);
}

 

for문을 살펴보면 이중 for문임을 알 수 있음. (해당 구문이 어디서부터 어디까지인지 인지하고 있어야 함)

for문 안에 continue, breeak 문이 있는데 continue 해당 for문의 continue 아래의 문장을 실행하지 않고 다음 단계(for문을 빠져나가는 것이 아님)로 넘어가는 반면, break 해당 for문을 아예 빠져나가게 됨.

 

for문을 실행해보면

① i = 0 일 때,

       j = 0 일 때 if 조건문을 보면 i > 7 일 때 continue 실행하지만 i는 현재 0이므로 거짓이기 때문에 k = 1. 

          다음 식인 if 조건문을 보면 j >= 3을 성립하지 않으므로 다음 단계 j++하여

       j = 1 일 때 현재 i는 계속 0이고, j의 값만 증가함.

          if 조건문을 보면 i > 7일 때 continue를 실행하지만 i는 현재 조건 성립하지 않으므로 k = 2.(if문 j >= 3 조건 성립X)

       j = 2일 때 위와 같은 조건으로 k = 3. (if문 j >= 3 조건 성립X)

       j = 3일 때 if 조건문(i > 7) 성립하지 않으므로, k = 4. 다음 if 조건문을 보면 j >= 3을 성립하므로 break문 실행하여 해당 for문을 빠져나감.

 

② i = 1 일 때,

       j = 0 일 때 if 조건문(i > 7) 성립하지 않으므로 k = 5. (if문 j >= 3 조건 성립X )

       j = 1 일 때 위와 같은 조건으로 k = 6. (if문 j >= 3 조건 성립X )

       j = 2 일 때 위와 같은 조건으로 k = 7(if문 j >= 3 조건 성립X )

       j = 3 일 때 if 조건문(i > 7) 성립하지 않으므로, k = 8 됨.

          다음 식인 if문을 보면 j >= 3을 성립하기 때문에 break 실행하여 해당 for문을 빠져나감.

 

계속 반복하다 보면 i = 7 일 때까지(i > 7이면 continue), j = 3일 때까지(j >= 3이면 break) 실행함.

따라서 i는 0 ~ 7까지 총 8개, j는 0 ~ 3까지 총 4개이므로 8 * 4 = 32이므로, k = 32의 값을 출력하게 됨.

 

[출력]

32

15번

#include<stdio.h>

void main() {
	int i, j, k = 0;
	for (i = 0; i <= 10; i++) {
		for (j = 0; j < 10; ++j) {
			if (j >= 3) break;
			k = k + 1;
			if (i > 7) continue;
		}
	}
	printf("%d\n", k)
}

 

14번 문제와 비슷함.

j의 for문을 살펴보면 j가 3과 같거나 이상이면 break가 실행되어 해당 for문을 빠져나가게 됨. 따라서 j는 0~2까지(3개) 실행하게 됨.

i의 for문을 살펴보면 i가 10이 되어도 j의 for문을 실행하여 k의 값은 증가하게 됨.

continue문은 실행이 되지만 i의 값이 7 이상이어도 영향은 주지 않으므로 i는 0~10까지(11개) 반복함. 3 * 11 = 33이므로 k = 33의 값을 출력함.

 

[출력]

33

16번

#include<stdio.h>

void main() {
	int i, j, k = 0;
	for (i = 0; i <= 10; i++) {
		for (j = 0; j < 10; ++j) {
			if (j >= 5) break;
			k = k + 1;
		}
		if (i > 6) continue;
	}
	printf("%d\n", k);
}

 

1) int i, j, k = 0;

 : 정수형 변수 i, j, k 선언하고 k는 0으로 초기화.

 

2) for문

  ① i = 0 일 때,

         j = 0 일 때 j >= 5 성립하지 않으므로 k = k + 1 = 0 + 1 = 1. k = 1 값을 가짐.

         j = 1 일 때 j >= 5 성립하지 않으므로 k = 2 값을 가짐.

         j = 2 일 때 j >= 5 성립하지 않으므로 k = 3 값을 가짐.

         j = 3 일 때 j >= 5 성립하지 않으므로 k = 4 값을 가짐.

         j = 4  때 j >= 5 성립하지 않으므로 k = 5 값을 가짐.

         j = 5 일 때 j >= 5 성립하므로 break 만나 j의 for문을 빠져나가고 i의 for문으로 올라감.

   ② i = 1 일 때,

         j = 0 일 때 j >= 5 성립하지 않으므로 k = 6 값을 가짐.

         j = 1 일 때 j >= 5 성립하지 않으므로 k = 7 값을 가짐.

         j = 2 일 때 j >= 5 성립하지 않으므로 k = 8 값을 가짐.

         j = 3 일 때 j >= 5 성립하지 않으므로 k = 9 값을 가짐.

         j = 4  때 j >= 5 성립하지 않으므로 k = 10 값을 가짐.

         j = 5 일 때 j >= 5 성립하므로 break 만나 j의 for문을 빠져나가고 i의 for문으로 올라감.

 

i의 for문에서 if 조건문을 보면 i > 6 일 때 continue가 실행.

하지만 i가 6 이상 일 때도 j의 for문을 반복하며 실행하니 k의 값은 증가하게 되고, continue는 영향을 주지 않음.

따라서 i는 0부터 10까지(11개) 반복되고, j는 0부터 4까지(5개) 반복되므로 11 * 5 = 55. 즉 k = 55의 값을 출력하게 됨.

 

3) printf("%d\n", k);

 : k값을 정수로 출력하면 55

 

[출력]

55

17번

#include<stdio.h>

void main() {
	int c = 100;
	switch (9) {
	case 0 : c += 2; break;
	default : c = 0;
	case 2 : c += 1;
	case 8 : c += 2; break;
	case 7 : c += 4;
	}
	printf("%d\n", c);
}

 

1) int c = 100;

 : 정수형 변수 c 선언하면서 100으로 초기화.

 

switch (표현식)
{
     case 값1 : 실행문1; break;
     case 값2 : 실행문2; break;
     ...
     default : 실행문n; break;
}

 

표현식의 결과값이 값1이면 실행문1 실행하고, 값2이면 실행문2를 수행하는 것.

해당 결과값이 없으면 default 값 실행.

case 키워드와 default 키워드 사용하는데 이를 case 레이블, default 레이블이라 하고, case 레이블은 상수(값)가 들어오며, default 레이블은 생략 가능.

2) switch 구문

 : switch 문은 값 9로 시작. 9로 시작하는 값이 case에 없으므로 default로 이동.

default에서 break 만나기 전 구문까지 실행. 그래서 default, case2, case8까지 실행함. (case8에서 break문을 가짐)

따라서 default에서 c는 0 값이고, case2에는 c += 1이므로 c = 1, case8에는 c += 2이므로 c = c + 2 = 1 + 2 = 3이 되므로 c = 3을 출력.

 

3) printf("%d\n", c);

 : c 값을 정수로 출력하면 3

 

[출력]

3

18번

#include<stdio.h>

void main() {
	int sum = 0, n = 0;
	int i[7] = { 3, -5, 8, 10, -9, 4, 6 };
	for (; n < 6; n++) {
		if (i[n] > sum) {
			int temp;
			temp = i[n + 1];
			i[n + 1] = i[n];
			i[n] = temp;
		}
		sum += i[n];
	}
	printf("%d\n", sum);
}

 

1) int sum = 0, n = 0;

 : 정수형 변수 sum, n 선언하면서 0으로 초기화.

 

2) int i[7] = { 3, -5, 8, 10, -9, 4, 6 };

 : 길이 7인 정수형 배열 선언하면서 초기화. 배열은 첫 번째부터 i[0] ~ i[6]으로 1이 아닌 0부터 시작.

3 -5 8 10 -9 4 6

 

3) for문

 : 조건은 n < 6이므로 n은 0에서 5까지 반복하며 총 6번 반복함.

 

 ① n = 0 일 때 (1회),

       ⊙ if 조건문 보면 i[0] > sum이고, i[0]은 3, sum은 0이기 때문에 3 > 0 조건 성립 하므로 for문실행.

        for문을 보면 temp라는 변수 선언하여 i[0]과 i[1] 자리를 바꿈.

        i의 배열은 {-5, 3, 8, 10, -9, 4, 6}이 됨.

       ⊙ sum += i[0] = sum + i[0] = 0 + (-5). 따라서 sum = -5

 ② n = 1일 때 (2회),

       ⊙ if 조건문 보면 i[1] > sum이고, i[1]은 3, sum은 -5이기 때문에 3 > -5 조건 성립하므로 for문 실행.

       ⊙ i[1]과 i[2]의 자리를 바꾸면 i의 배열은 {-5, 8, 3, 10, -9, 4, 6}이 됨.

        sum += i[1] = sum + i[1] = -5 + 8 = 3. 따라서 sum = 3

 ③ n = 2 일 때 (3회),

       ⊙ if 조건문 보면 i[2] > sum이고, i[2]는 3, sum은 3이므로 3 > 3 조건 성립하지 않으므로 for문 실행 안함. (배열 그대로)

       ⊙ sum의 값은 더해야 하므로 sum += i[2] = sum + i[2] = 3 + 3 = 6. 따라서 sum = 6

 ④ n = 3 일 때 (4회),

       ⊙ if 조건문 보면 i[3] > sum이고, i[3]은 10, sum은 6이므로 10 > 6 조건 성립하므로 for문 실행.

       ⊙ i[3]과 i[4]의 자리를 바꾸면 i의 배열은 {-5, 8, 3, -9, 10, 4, 6}이 됨.

       ⊙ sum += i[3] = sum + i[3] = 6 + (-9) = -3. 따라서 sum = -3

 ⑤ n = 4 일 때 (5회),

       ⊙ if 조건문 보면 i[4] > sum이고, i[4]는 10, sum은 -3이므로 10 > -3 조건 성립하므로 for문 실행.

       ⊙ i[4]와 i[5]의 자리를 바꾸면 i의 배열은 {-5, 8, 3, -9, 4, 10, 6}이 됨.

       ⊙ sum += i[4] = sum + i[4] = -3 + 4 = 1. 따라서  sum = 1

 ⑥ n = 5 일 때 (6회),

       ⊙ if 조건문 보면 i[5] > sum이고, i[5]는 10, sum은 1이므로 10 > 1 조건 성립하므로 for문 실행.

        i[5]와 i[6]의 자리를 바꾸면 i의 배열은 {-5, 8, 3, -9, 4, 6,10}이 됨.

        sum += i[5] = sum + i[5] = 1 + 6 = 7. 따라서 sum = 7

 

4) printf("%d\n", sum);

 : sum 값을 정수로 출력하면 7

 

[출력]

7

19번

#include<stdio.h>
#define change(x, y) imsi=x; x=y; y=imsi;

void main() {
	int i, j, K = 5, imsi;
	int num[5] = { 5, 9, 3, 7, 4 };
	for (i = 0; i < K; i++) {
		for (j = 0; j < (K - i); j++) {
			if (num[j] < num[j + 1]) {
				change(num[j], num[j + 1]);
			}
		}
	}
	printf("%d\n", num[1]);
}

 

이 코드는 num[ ]의 값을 내림차순으로 정렬하는 버블 정렬의 형태를 취함.

if문 조건의 부등호에 따라 오름차순, 내림차순이 결정되고, 현재 코드는 내림차순 코드.

 

1) #define change(x, y) imsi=x; x=y; y=imsi;

 : x와 y의 값을 임시 변수 imsi 사용하여 교환하는 change 매크로 정의.

 

2) int i, j, K = 5, imsi;

 : 정수형 변수, i, j, K, imsi 선언 후 K에는 5로 초기화.

 

3) int num[5] = { 5, 9, 3, 7, 4 };

 : 길이 5인 정수형 배열 선언 하면서 초기화.

5 9 3 7 4

 

3) for문

⊙ i의 for문은 i가 0부터 시작해서 K인 5 전까지(0~4) 반복 실행.

j의 for문은 j가 0부터 시작해서 K - i인 4~1까지 반복 실행.

 

 ① i = 0 일 때 (j < 5)

        j = 0 일 때

          if 조건문 num[0] < num[1]이고 num[0]은 5, num[1]은 9이므로 5 < 9 조건 성립.

          ⊙ num[0]과 num[1]의 자리를 바꾸면 num의 배열은 {9, 5, 3, 7, 4}이 됨.

        j = 1 일 때

          ⊙ if 조건문 num[1] < num[2]이고 num[1]은 5, num[2]는 3이므로  5 < 3 조건 성립하지 않음.

        j = 2 일 때

          ⊙ if 조건문 num[2] < num[3]이고 num[2]는 3, num[3]은 7이므로  3 < 7 조건 성립.

          ⊙ num[2]와 num[3]의 자리를 바꾸면 num의 배열은 {9, 5, 7, 3, 4}이 됨.

        j = 3 일 때

          ⊙ if 조건문 num[3] < num[4]이고 num[3]은 3, num[4]는 4이므로  3 < 4 조건 성립.

          num[3]와 num[4]의 자리를 바꾸면 num의 배열은 {9, 5, 7, 4, 3}이 됨.   

        j = 4 일 때

          ⊙ if 조건문 num[4] < num[5]이고 num[5]는 배열의 범위를 벗어나므로 실행하지 않음.

 ② i = 1일 때 (j < 4)

        j = 0 일 때

          ⊙ if 조건문 num[0] < num[1]이고 num[0]은 9, num[1]은 5이므로 9 < 5 조건 성립하지 않음.

        j = 1 일 때

          ⊙ if 조건문 num[1] < num[2]이고 num[1]은 5, num[2]는 7이므로 5 < 7 조건 성립.

          ⊙ num[1]과 num[2]의 자리를 바꾸면 num의 배열은 {9, 7, 5, 4, 3}이 됨.

          ⊙ 사실 여기에서 정렬은 끝이 났음.

        j = 2 일 때

          ⊙ if 조건문 num[2] < num[3]이고 num[2]는 5, num[3]은 4이므로 5 < 4 조건 성립하지 않음.

        j = 3 일 때

          ⊙ if 조건문 num[3] < num[4]이고 num[3]은 4, num[4]는 3이므로 4 < 3 조건 성립하지 않음.

 ③ i = 2 일 때 (j < 3)

        j = 0 일 때

          ⊙ if 조건문 num[0] < num[1]이고 num[0]은 9, num[1]은 7이므로 9 < 7 조건 성립하지 않음.

        j = 1 일 때

          ⊙ if 조건문 num[1] < num[2]이고 num[1]은 7, num[2]는 5이므로 7 < 5 조건 성립하지 않음.

        j = 2 일 때

          ⊙ if 조건문 num[2] < num[3]이고 num[2]는 5, num[3]은 4이므로 5 < 4 조건 성립하지 않음.

 ④ i = 3 일 때 (j < 2)

        j = 0 일 때

          ⊙ if 조건문 num[0] < num[1]이고 num[0]은 9, num[1]은 7이므로 9 < 7 조건 성립하지 않음.

        j = 1 일 때

          ⊙ if 조건문 num[1] < num[2]이고 num[1]은 7, num[2]는 5이므로 7 < 5 조건 성립하지 않음.

 ⑤ i = 4 일 때 (j < 1)

        j = 0 일 때

          ⊙ if 조건문 num[0] < num[1]이고 num[0]은 9, num[1]은 7이므로 9 <  7 조건 성립하지 않음.

 

따라서 범위에 따라 코드를 실행하면 num 배열의 최종 출력은 {9, 7, 5, 4, 3}이 됨

 

4) printf("%d\n", num[1]);

 : num[1]의 값을 정수로 출력하면 7

 

[출력]

7

20번

#include<stdio.h>

int foo(int a, int b) {
	if (a > b) return 0;
	else return b + foo(a + 1, b);
}
void main() {
	int a = 7, b = 10, y;
	y = foo(a, b);
	printf("%d\n", y);
}

 

이 코드는 재귀함수 사용하는 사용

 

1) int a = 7, b = 10, y;

 : 정수형 변수 a, b, y 선언 후 a에는 7, b에는 10 초기화.

 

2) y = foo(a, b);

 : foo 함수가 a와 b 함께 호출하며 이 때 초기값 a = 7, b = 10이므로 함수 실행하면 7 > 10 조건 성립하지 않으므로 else 문 실행.

 

3) else return b + foo(a + 1, b);

 : b = 10, a = 7이므로 return 10 + foo(8, 10);

 

4) 다시 foo함수 실행하면 a = 8, b = 10이므로 8 > 10 조건 성립하지 않으므로 else 문 실행.

 

5) else return b + foo(a + 1, b);

 : b = 10, a = 8이므로 return 10 + foo(9, 10);

 

6) 다시 foo 함수 실행하면 a = 9, b = 10이므로 9 > 10 조건 성립하지 않으므로 else 문 실행.

 

7) else return b + foo(a + 1, b);

 : b = 10, a = 9이므로 return 10 + foo(10, 10);

 

8) 다시 foo 함수 실행하면 a = 10, b = 10이므로 10 > 10 조건 성립하지 않으므로 else 문 실행.

 

9) else return b + foo(a + 1, b);

 : b = 10, a = 10이므로 return 10 + foo(11, 10);

 

10) 다시 foo 함수 실행하면 a = 11, b = 10이므로 11 > 10 조건 성립하므로 return 0 반환.

 

11) 최종적으로 foo(11, 10) = 0 / foo (10, 10) = 10 / foo (9, 10) = 10 / foo (8, 10) = 10 이므로 10 + 10 + 10 + 10 = 40이 반환.

이 값은 y에 저장되어 출력.

 

12) printf("%d\n", y);

 : y의 값을 정수로 출력하면 40

 

[출력]

40

 

 

 

 

 

! 강의 보며 혼자 공부한 것으로,

틀린 거 있을 시 댓글로 가르쳐주시면 감사하겠습니다!