본문 바로가기

Studying/정보처리기사

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

01번

#include<stdio.h>

void main() {
	float a = 3 / 2;
	float b = 3.0 / 2;
	int c = (int)b;
	printf("%7.3f %7.3f %3d\n", a, b, c);
}

 

1) #include<stdio.h>

 : 표준 입력 및 출력 함수 사용하기 위해 필요한 헤더파일 포함.

 

2) void main()

 : C 프로그램은 main 함수에서 실행 시작하므로 main 함수 정의하는데 void는 아무 값도 반환하지 않음.

 

3) float a = 3 / 2;

 : 3을 2로 나눈 결과의 몫을 변수 a에 저장. 기억해야 할 것은 정수/정수는 정수로 반환

   정수/실수, 실수/정수 그리고 실수/실수는 실수로 반환. 따라서 a는 1을 저장.

 

4) float b = 3.0 / 2;

 : 3.0을 2로 나눈 결과의 몫을 변수 b에 저장.

   실수/정수이므로 실수를 반환하기 때문에 b는 1.0을 저장.

 

5) int c = (int)b;

 : 변수 c는 변수b의 값을 정수로 변환하여 저장. 정수로 변환하면 소수점자리는 버려지기 때문에 c는 1을 저장.

 

6) printf("%7.3f %7.3f %3d\n", a, b, c);

 : C 프로그램은 printf를 사용하여 출력.

 ⊙ %7.3f : 부동소수점 숫자 표시하는데 사용. 전체 필드 너비는 7자리(소수점도 포함)이고, 소수점 아래는 3자리까지 표시하도록 출력.

 ⊙ %3d : 정수를 표시하는데 사용. 전체 필드 너비는 3자리로 출력.

 

[출력] 

  1.000   1.500   1

02번

#include<stdio.h>

void main() {
	int su1 = 16, su2 = 4, mov1, mov2;
	mov1 = su1 >> 2;
	mov2 = su2 << 4;
	printf("%d %d\n", mov1, mov2);
}

 

1) int su1 = 16, su2 = 4, mov1, mov2;

 : 정수형 변수 su1, su2, mov1, mov2 선언하고 su1, su2에는 각 값을 초기화.

 

2) mov1 = su1 >> 2;

 : 오른쪽 시프트 연산자 >>를 사용하여 변수 su1의 비트를 오른쪽으로 2번 이동시키고 그 결과값을 mov1에 저장. 

 비트 오른쪽 시프트는 주어진 수를 2의 거듭제곱으로 나누는 효과를 가짐. 따라서 su1의 값인 16을 2^2으로 나누는 값을 mov1에 저장.

 mov1에는 16/4의 값인 4를 저장.

 

3) mov2 = su2 << 4;

 : 왼쪽 시프트 연산자 <<를 사용하여 변수 su2의 비트를 왼쪽으로 4번 이동시키고 그 결과값을 mov2에 저장.

 비트 왼쪽 시프트는 주어진 수를 2의 거듭제곱으로 곱하는 효과를 가짐. 따라서 su2의 값인 4를 2^4로 곱하는 값을 mov2에 저장.

 mov2에는 4*16의 값인 64를 저장.

 

4) printf("%d %d\n", mov1, mov2);

 : 서식 지정자 사용하여 변수 mov1, mov2의 값을 출력.

 ⊙ %d : 정수 표시하는데 사용.

 

[출력]

4 64

03번

#include<stdio.h>

void main() {
	int a, b, c, r;
	a = 4;
	b = 2;
	c = 3;
	r = a++ - ++b * (c << 2);
	printf("%d\n", r);
}

 

1) int a, b, c, r;

 : 정수형 변수 a, b, c, r 선언.

 

2) a = 4; b = 2; c = 3;

 : 변수 a, b, c에 각각 4, 2, 3 값을 초기화

 

3) r = a++ - ++b * (c << 2);

우선연산자인 괄호 먼저 수행하면 c << 2는 c값인 3에 왼쪽 시프트 연산자 사용하면 2^2를 곱하게 되므로 12.

 a++는 ++가 뒤에 있는 후위연산자이므로 a의 값인 4로 계산되고 그 후에 a는 5로 증가

++b는 ++가 앞에 있는 전위연산자이므로 b의 값인 2를 ++하여 3으로 계산.

 : 따라서 변수 c는 4 - 3 * 12 = * 먼저 계산되므로 4 - 36 = -32의 값을 저장하게 됨.

 

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

 : 서식지정자 사용하여 변수 r의 값을 출력

%d : 정수 표시하는데 사용.

 

여기서 중요한것은 ++가 앞에 붙었는지 뒤에 붙었는지가 중요함. 

그리고 각각의 값을 출력한다고 하면 a = 5, b = 3, c = 3을 출력함.

 

[출력]

-32

04번

#include<stdio.h>

void main() {
	int x = 8;
	int y = 9;
	printf("%d ", !!x);
	printf("%d ", x && y);
	printf("%d", x || y);
}

논리연산자

 - !(NOT, ㄱ) : 원자식에 대한 부정

 - &&(AND, ∧) : 원자식 간 "그리고" 관계로 연결

 - ||(OR, ∨) : 원자식 간 "또는" 관계로 연결

 

- 0(거짓)이외에 숫자는 1(참)로 보는것을 알아두자.

- C언어는 단락회로평가(중지연산) 지원해줌. &&연산은 두 조건이 모두 참을 만족할 경우 참을 반환. 만약 앞에 조건이 거짓이면 뒤에 조건은 보지 않고 거짓을 반환함. 또한 || 연산을 사용하면 하나라도 참일 경우 참을 반환하는데 앞에 조건이 참이면 뒤에 조건은 보지 않고 참을 반환.

1) int x = 8; int y = 9;

 : 정수형 변수 x, y 선언하면서 각 값인 8과 9로 초기화.

 

2) printf("%d ", !!x);

 : !!는 논리연산자인 부정을 두 번 사용한 것. x는 0(거짓)이 아닌 값을 저장하고 있으므로 참인 값을 가지고 있지만 한 번 부정하면(!) 거짓이고, 또 한번 부정(!)하면 참(1)을 반환하므로 출력 결과는 1.

 

3) printf("%d ", x && y);

 : &&는 논리연산자인 AND를 의미. 둘 다 참(1)일 경우 참(1)을 반환하는데, x와 y는 현재 0(거짓)이 아닌 숫자를 저장하고 있기 때문에 둘 다 참(1)이므로 출력 결과는 1.

 

4) printf("%d", x || y);

 : ||는 논리연산자인 OR를 의미.

   둘 중 하나라도 참일 경우 참을 반환하는데, x와 y는 현재 0(거짓)이 아닌 숫자를 저장하고 있기 때문에 둘 다 참(1)이므로 결과는 1.

 

[출력]

1 1 1

05번

#include<stdio.h>

void main(void) {
	enum{AA, BB, CC=-100, FF, KK};
	printf("%d \n", AA + KK);
}

 

- enum은 열거형을 정의.

열거형은 상수 값들이 집합을 나타내며, 각 상수는 순서대로 0부터 시작하여 1씩 증가하는 값을 가짐.

 

1) enum{AA, BB, CC=-100, FF, KK}; : AA=0, BB=1씩 증가하다가 CC=-100의 값이 할당되었으므로 그 다음부터는 -100에서 1씩 증가는 값을 가짐. FF=-99, KK=-98 (여기서 -100에서 1증가한다고 -101이 아닌 -99임을 헷갈리지 말자.)

 

2) printf("%d \n", AA + KK); : AA + KK 상수를 더한 결과를 정수 형식으로 출력AA=0, KK=-98이므로 AA+KK는 0 + (-98) = -98

 

[출력]

-98

06번

#include<stdio.h>

void main() {
	int a, b, c;
	a = 20, b = 30;
	c = (a > b) ? a-- : --b;
	printf("%d, %d\n", a, c);
}

 

1) int a, b, c;

 : 정수형 변수 a, b, c 선언.

 

2) a = 20, b = 30;

 : 변수 a, b에 각 값을 초기화.

 

3) c = (a > b) ? a-- : --b;

 : 조건 연산자 사용하여 a와 b 비교 후 c에 값을 할당. 조건이 참일 경우 a--, 거짓일 경우 --b 출력

  조건식 (a > b)는 a가 b보다 큰 지 여부 검사. a는 20, b는 30이므로 20>30이기 때문에 조건은 거짓.

 조건이 거짓이므로 --b 값을 c에 저장. 따라서 b는 30이기 때문에 --가 앞에 있으므로 1을 감소시킨 29가 c에 저장.

 여기서 b의 값도 29로 저장.

 

4) printf("%d, %d\n", a, c);

 : a와 c의 값을 정수로 출력하므로 a=20, c=29.

 

[출력]

20, 29

07번

#include<stdio.h>

void main() {
	int a, b, c;
	a = (b = 7, (c = ++b + 2) + 5);
	printf("%d, %d, %d\n", a, b, c);
}

 

1) int a, b, c;

 : 정수형 변수 a, b, c 선언.

 

2) a = (b = 7, (c = ++b + 2) + 5);

 : 연산자는 왼쪽에서 오른쪽으로 표현식 평가하고, 마지막 표현식의 결과 반환.

 순서대로 보면 b=7로 선언. b에 7 값을 저장.

 그 다음 (c = ++b + 2) 식을 보면 c에 ++b연산하여 +2 값을 계산하여 저장. ++b 하면 b는 8이 되므로 8+2=10을 변수 c에 저장.

마지막으로 (c = ++b + 2) + 5 식을 보면 10 + 5 = 15를 변수 a에 저장.

 

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

 : a, b, c의 값을 정수로 출력하므로 a = 15, b = 8, c = 10

 

[출력]

15, 8, 10

 


08번

#include<stdio.h>

void main() {
	int a = 10, b = 0, c = 0;
	if (a > 15 && ++b < 12 || c++) {
		c++;
	}
	printf("%d, %d, %d", a, b, c);
}

 

1) int a = 10, b = 0, c = 0;

 : 정수형 변수 a, b, c 선언하면서 각 값을 초기화.

 

2) if (a > 15 && ++b < 12 || c++) {c++;}

 &&는 조건 두 개가 참일 경우 참을 반환. 앞에 조건이 거짓일 경우 뒤에 있는 조건은 평가하지 않고 넘어감.

a > 15에서 a는 10을 저장하고 있으므로 10 > 15는 거짓이기 때문에 뒤에 조건 ++b < 12는 판단하지 않음.

따라서 ++b는 연산되지 않으므로 b는 0 값을 그대로 가지고 있음.

 ||는 조건 두 개 중 한 개가 참일 경우 참을 반환. 앞에 조건(왼쪽 피연산자)은 거짓이기 때문에 뒤에 조건(오른쪽 피연산자)을 판단하는데 c++은 ++가 후위연산자이므로 먼저 조건 판단 후에 c의 값이 1증가하게 됨.

현재 c는 0을 가지고 있으므로 거짓이기 때문에 거짓||거짓은 거짓을 반환하고, c의 값은 1증가하여 c는 1을 저장.

 

3) printf("%d, %d, %d", a, b, c);

 : a, b, c의 값을 정수로 출력하므로 a=10, b=0, c=1

 

[출력]

10, 0, 1

09번

#include<stdio.h>

int main() {
	int a = 1, b = 2, c = 3, d = 4;
	if ((a == b) && (c++ == d)) c++;
	printf("%d", c);
}

 

1) int a = 1, b = 2, c = 3, d = 4;

 : 정수형 변수 a, b, c, d 선언하면서 각 값을 초기화.

 

2) if ((a == b) && (c++ == d)) c++;

 : if 조건문. 조건이 참일 경우 해당 조건문 안의 식을 계산. 논리연산자 &&는 두 조건 모두 참일 경우 참을 반환.

 a == b에서 1==2는 거짓이기 때문에 첫 번째 조건은 거짓을 반환.

 따라서 c++ == d는 조건을 판단하지 않기 때문에 c의 값은 변하지 않음.

 조건문은 거짓이므로 조건 내부의 c++은 실행되지 않음.

 

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

 : c의 값을 정수로 출력하므로 c=3

 

[출력]

3

10번

#include<stdio.h>

int main(void) {
	int i, j, a = 0, b = 1;
	for (i = 1, j = 1; i++ < 3; )
		j += i;
	printf("i = %d, j = %d\n", i, j);
	if (a == b >= a != b)
		printf("True\n");
	else
		printf("False\n");
}

 

1) int i, j, a = 0, b = 1;

 : 정수형 변수 i, j, a, b 선언 후 a와 b에는 각 값을 초기화

 

for(초기화식; 조건식; 증감식) {

     실행문장;

}

for (i = 1, j = 1; i++ < 3; )
	j += i;

2) for 반복문

 i와 j는 1로 초기화.

 i는 1씩 증가하면서 3이 되기 전까지 실행

 

 ① i = 1, j = 1일 때, i++ < 3 조건 확인 후(1<3은 참) i는 1 증가. (현재 i = 2)

       j += i는 j = j + i로 풀어서 쓸 수 있고 j = 1, i = 2이므로 1 + 2 = 3. 따라서 j = 3. 다음 반복문으로 넘어가 

 ② i = 2, j = 3일 때 i++ < 3 조건 확인 후 (2 < 3은 참) i는 1 증가. (현재 i = 3)

       j + = i에서 j = 3, i = 3이므로 3 + 3 = 6. 따라서 j = 6. 다음 반복문으로 넘어가

 ③ i = 3, j = 6일 때 i++<3 조건 확인 하면 3 < 3은 거짓이므로 for문을 빠져나감.

   여기서 알아야 할 것은 i는 조건을 확인 후 빠져나간 것, 즉 ++연산이 수행된 후에 빠져나간 것이므로 현재 i는 4의 값을 가지고 빠져나감.

 

3) printf("i = %d, j = %d\n", i, j);

 : i와 j의 값을 정수로 출력하므로 for문 빠져나오기 직전에 마지막 i와 j의 값은 4와 6임.

   i는 for문 빠져나오기 전 조건식에서 ++ 연산 수행 후 빠져나왔고, j는 for문에서 값을 6으로 가지고 빠져나옴.

 

대소비교가 등가비교보다 우선순위가 높음

 

- 대소비교 : >, <, <=, => ...
- 등가비교 : !=, == ...

 

if (a == b >= a != b)
	printf("True\n");
else
	printf("False\n");

4) if 조건문

 대소비교가 우선순위 더 높으므로 b >= a 먼저 연산. a = 0, b= 1이므로 1 >= 0은 참(1)이므로 1 반환.

 a == 1(b >= a) 연산하면 a = 0이므로 0 == 1은 거짓(0)이기 때문에 0 반환.

 0 (a == b >= a) != b 연산하면 b = 1이므로 0 != 1은 참(1)이기 때문에 1(참) 반환.

 따라서 if문은 else가 아닌 if문을 실행하므로 Ture 출력

 

[출력]

i = 4, j = 6
True

 

 

 

 

 

! 에듀윌에서 무료로 제공한 '정보처리기사 비밀 언어 특강' 강의 보며 혼자 공부한 것으로,

틀린 부분이 있다면 댓글로 남겨주세요. 감사합니다!