본문 바로가기
정보처리기사

정보처리기사 실기 프로그래밍 문제 C언어 기출 모음

by 셈이 2022. 10. 11.
728x90
반응형

정보처리기사 시험을 보고 난 뒤 느낀점은 '20문제 중에 코딩 문제는 일단 다 맞아야겠다' 였어요. 용어를 서술하는 문제는 너무 지엽적으로 나와서 맞추기가 어렵더라구요.

 

특히나 2020년도 이후에 ncs 기반으로 개편이 된 이후에 코딩문제가 8문제 정도 나오고 있습니다. 60점이 합격점수고 12문제만 맞으면 되니까, 코딩 문제 8문제 다 맞추고 다른거 4개 더 맞겠다 라는 생각으로 공부를 해야 하는것 같아요.

 

프로그래밍 문제는 C언어, 자바, 파이썬, SQL 이렇게 4부분에서 나옵니다. 저는 정리하면서 공부가 되는 편이여서, 하나 하나 기출문제와 모의고사를 분석해 보려고 합니다. 

 

대부분의 문제결과값이나 빈칸에 들어갈 알맞은 말을 쓰는 것이여서 문제 부분은 생략 하겠습니다.

 

정보처리기사 실기 C언어 기출 문제 (2020년~ 2022년도/ 9회분)

 

1.  2022년 2회차 15번

#include <stdio.h> 

int len(char* p); 
      
int main()
{ 
    char* p1 = "2022"; 
    char* p2 = "202207";   
      
    int a = p1; 
    int b = p2; 

    printf("%d", len(a) + len(b)); 
} 

int len(char*p)
{ 
     int r = 0;      
     while(*p != \0')
     { 
     	p++; 
        r++;
     } 
 }

 

더보기

답) 10

 

포인터 문제입니다. 포인터를 사용하는 이유 중의 하나가 바로 메모리 내의 문자열을 쉽게 다루기 위해서 입니다.

 

코드 문제를 풀때 가장 먼저 봐야할 곳은 함수 printf() 부분입니다. 그래야 우리가 궁극적으로 뭘 구해야 하는건지 알 수 있으니까요.함수 printf() 를 보시면  len(a)len(b)를 더하여 상수(%d)로 표현하는 문제입니다.

 

다음으로 이렇게 "2022" 쌍따옴표로 문자가 묶여 있는 것을 보실 수 있습니다. 이렇게 쌍따옴표로 묶여져 있는 것은 절대 불변의 데이터이며, 이를 우리는 "문자열상수"라고 이야기 합니다.

 

문자열 상수의 특징은 1. 붙어있다. 2. 마지막에 null값을 포함한다 입니다.

 

C언어에서 문자를 처리하는 자료형은 2가지가 있습니다. char(문자), string(문자열). 차이는 char는 개별 문자 한글자를 말하고, string은 두개 이상의 문자결합 구조를 말합니다.

 

그래서 자료형 char문자열을 저장할때는 배열 구조로 저장합니다. 그리고 가장 큰 특징은 맨뒤에 null문자가 자동으로 저장된다는 것입니다.  C언어에서 null은 한문자로 취급합니다.

 

또 null 은 코드 상으로 \0 혹은 ₩0 라고 표기합니다.

 

그래서 문제를 분석해 보면, char * p1 과 char * p2 는 아래와 같은 모양을 가집니다.

c언어 포인터 배열

여기서 포인터를 살짝만 설명해보자면, 철수네 집에 오렌지 3개가 있다. 라는 문장에서 철수네 집은 202호에요~ 라고 알려주는 것이 포인터 입니다. 

그래서 int* p = &a 에서 p와 &a주소 변수이고, 이 주소의 내용물을 나타내는 변수는 각각 *p, a 인겁니다.

주소변수 값변수
p *p
&a a
함수 int len(char*p) 를 분석해보면, *p가 널(\0)이 아닐때(!=) 까지 (while) 조건문을 돌리라는 뜻입니다.

따라서 len(a)=4 / len(b)= 6/ ∴ 4+6 =10 입니다.

 

 

 

 

2. 2022년 2회차 16번

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
	int a[4] = {0, 2, 4, 8}; 
	int b[3] = {}; 
	int i = 1; 
	int sum = 0;
	int *p1; 

	for (i; i < 4; i++) 
    {
    	p1 = a + i; 
        b[i-1] = p1 - a[i-1];
        sum = sum + b[i-1] + a[i]; 
     } 

	printf("%d", sum); 
	return 0; 
}

 

더보기

답) 22

코드 문제는 함수 printf() 확인부터! 즉, 이 문제는 sum을 구하라는 문제입니다.

 

배열 a를 표현해보면 아래와 같습니다.

c언어 배열


p1 = a+1
b[0] = (a+1) -a[0] = 2-0=2
sum = sum +b[0] + a[1] = sum +2+2= 4 

p2 = a+2
b[1] = (a+2) -a[1] = 4-2=2
sum = sum +b[1] + a[2] = 4+2+2= 10 

p3 = a+3
b[2] = (a+3) -a[2] = 8-4=4
sum = sum +b[2] + a[3] = 10+4+8=22

∴ sum = 22 

 

 

 

 

 

3.  2022년 1회차 14번

Q) 다음 코드에서 입력값이 5가 들어갔을때의 출력값을 쓰시오.

#include <stdio.h

int func(int a) 
{
  if (a <= 1) return 1;
  return a * func(a - 1);
}
 
int main() 
{
  int a;
  scanf("%d", &a);
  printf("%d", func(a));
}

 

더보기

답) 120

c언어의 입력함수 scanf() 에서 5를 입력받아 printf()에서 func(5)를 출력하는 문제입니다.

 

5 X fun(4) => 5 X 4 X f(3) => X 4 X 3 X f(2) => 5 X 4 X 3 X 2 X f(1)

근데 문제에서  if (a <= 1return 1

따라서 5 X 4 X 3 X 2 X 1  = 120 입니다.

 

 

 

 

4.  2022년 1회차 15번

#include <stdio.h>
int main() 
{
  int number = 1234;
  int div = 10;
  int result = 0;
 
  while (number ( 1 ) 0) 
  {
    result = result * div;
    result = result + number ( 2 ) div;
    number = number ( 3 ) div;
  }
  
  printf("%d", result);
  return 0;
}

결과 : 4321

 

더보기

답)

1. >  2. %  3. /

 

 

산술 연산자 : +,  -,  *,  /,  %

대입 연산자 : =,  +=,  -+,  *=, /=,  %=

증감 연산자 : ++x, x++, --x, x--

비교 연산자 : ==,  !=, >,  <,  >=,  <=

논리연산자 : &&, ||, !

비트연산자 : &,  |,  ^,  ~,  <<,  >>

삼항연산자 : 조건식 ? 반환값1 (참) : 반환값2 (거짓)

연산자 우선순위 : 단항(++) > 산술 (*,+) > 시프트> 관계 (==, !=, >) > 비트 > 논리 > 삼항연산자 > 대입


문제를 보시면 1234를 입력했는데 4321이 출력된것을 알 수 있습니다.
숫자를 한번 대입해보면

result = 0 * 10 = 0
result = 0 + 1234 () 10

그럼 여기서 4321이 출력되어야 하니까, 어떻게든 4를 만들어야 합니다.
1234 를 10으로 나눈 나머지가 4 겠죠? 그렇기 때문에 나눈 나머지를 나타내는 연산자 %2번에 들어갑니다.

계속 대입을 해보면
1234 = 1234 () 10 입니다.
while문 두번째줄에서 나눈 나머지가 3이 되어야 하니까 num을 123으로 만들어야 합니다.
그래서 3번에는 연산자 / 가 들어갑니다. 1234를 10으로 나누면 123이 되니까요

그럼 아마 while문이 진행되면 1234 -> 123-> 12-> 1 -> 이렇게 진행이 될꺼에요. 
우리의 출력값은 4321이니까 1이 나오게 되면 그 이후로는 필요가 없겠죠?

그래서 1번답 number () 0에 들어가는 연산자는 > 가 되는겁니다.
num이 0보다 클때만 while문을 돌립니다~ 라는 뜻이죠.

 

 

 

 

 

5.  2022년 1회차 19번

#include <stdio.h> 

int isPrime(int number) 
{ 
  int i; 
  for (i=2; i<number; i++) 
  { 
    if (number % i == 0) return 0; 
  } 
  return 1; 
} 
 
int main(void) 
{ 
  int number = 13195, max_div=0, i; 
  for (i=2; i<number; i++) 
  	if (isPrime(i) == 1 && number % i == 0) 
		max_div = i; 
  
  printf("%d", max_div); 
  return 0; 
}

 

더보기

답) 29

 

대부분 해설을 보니까 isPrime이 소수 판별을 하는 함수인걸 안 상태에서 문제를 푸시더라구요. 근데 몰라도 풀 수 있습니다.

 

코딩문제를 풀땐 항상 printf() 함수부터 확인합니다. max_div를 구하라는 문제네요.
if문을 살펴보면 isPrime 값이 1 이면서 number % i가 0일때 max_div 가 i 라고 하네요

 

함수 isPrime을 살펴보겠습니다.
isPrime()을 살펴보시면 number를 i로 나눈 나머지가 0이 아닐때 return값 1을 가집니다.
즉, 어떤 수로도 나눌 수 없는 수 일때 값이 1이라는 뜻입니다.
이렇게 어떤 수로도 나눌 수 없는 수를 우리는 소수라고 하죠?

그래서 isPrime(i) ==1 일때는 i는 2부터 13195사이의 소수라는걸 알 수 있습니다.
왜냐하면 for문에서 정해준 i의 범위가 number까지인데, main 함수에서 number를 13195라고 값을 초기화 했으니까요

다음은 number % i==0을 살펴보겠습니다.
number % i, 즉 13195를 i로 나누었을때 나머지가 0 이라는 뜻입니다.

 

그래서 소수이면서 13195를 나누었을때 나누어 떨어지는 숫자를 찾으면 되는 겁니다.

근데 보면 13195가 숫자가 더럽잖아요. 뭘로 나누어 떨어지는지 예측하는게 너무 어려우니까 일단 5부터 나눠보겠습니다. 끝자리가 5로 끝나니까요.

그럼 5X2639 입니다. 여기서 5보다 크고, 소수이면서, 곱했을때 끝자리가 9가 나오는 숫자를 골라보면 7이 나옵니다. 7*7=49잖아요.

 

그럼 5X 7 X 377 입니다. 똑같이 7보다 크고, 소수이면서, 곱했을때 끝자리가 7이 나오는 숫자는 9겠네요. 9*3 =27 이니까요. 안나눠 떨어집니다. 그럼 13으로 나눠보겠습니다.

그럼 5X 7 X 13 X 29입니다.

여기서 비전공자분들은 max가 최대값을 구하게 만드는 함수인가? 싶으실 수도 있는데 max는 그냥 변수 이름입니다. 저자리에 변수 a가 들어가도 답은 29입니다.

조건문 for문이 계속 돌아가면서 정답인 5를 만나면 max_div에 저장, i값이 커지면서 만난 또다른 정답인 7을 max_div에 저장, 또 다시 만난 정답 13 저장, 그리고 또다시 만난 정답 29저장. 어? for문이 끝났네? 마지막에 저장된 29 출력. 이렇게 되는 겁니다.

 

그런데 시험이니까 변수 이름 하나도 전부 의도를 하고 주기 때문에, 변수이름이 max_div. max니까 최대를 구하라는 건가보다. 하시면 됩니다. 그리고 실제로도 최대 최소를 구할때 변수 이름은 거의 max, min으로 두니까요.

 

 

 

 

 

6. 2021년 3회차 12번

#include <stdio.h>
 
int main()
{
	int *arr[3];
	int a = 12, b = 24, c = 36;

	arr[0] = &a;
	arr[1] = &b;
	arr[2] = &c;
 
	printf("%d\n", *arr[1] + **arr + 1);
}

 

더보기

답)37

 

포인터를 살짝만 설명해보자면, 영희네 집에 오렌지 3개가 있다. 라는 문장에서 영희네 집은 202호에요~ 라고 알려주는 것이 포인터 입니다. 

그래서 int* arr = &a 에서 arr와 &a 주소 변수이고, 이 주소의 내용물을 나타내는 변수는 각각 *arr, a 인겁니다.

주소변수 값변수
p *p
&a a

그래서 arr[0] = &a; 이런식으로 a앞에 &를 붙이는 것입니다. arr는 값을 담는 배열이 아닌, 주소를 담는 배열이니까요

arr[0]a의 주소를, arr[1]b의 주소를, arr[2]c의 주소를 담고있습니다.

 

*arr[1]은 b의 주소가 담고 있는 값인 24입니다.

 

**arr이중포인터 인데, 간단하게 *(*arr) 이렇게 해석하시면 됩니다. 주소 배열 arr의 주소를 말합니다. 그리고 arr처럼 배열의 이름만 있는 경우 배열의 첫번째 요소를 뜻합니다.

그래서 **arr + 1 = 12 +1 = 13 입니다.

∴24 + 13 = 37

 

 

 

 

 

 

7.  2021년 3회차 17번

#include <stdio.h>
 
struct jsu 
{
  char name[12];
  int os, db, hab, hhab;
};
 
int main()
{
   struct jsu st[3] = {{"데이터1", 95, 88}, {"데이터2", 84, 91}, {"데이터3", 86, 75}};
   struct jsu* p;
 
   p = &st[0];
 
   (p + 1)->hab = (p + 1)->os + (p + 2)->db;
   (p + 1)->hhab = (p+1)->hab + p->os + p->db;
 
   printf("%d\n", (p+1)->hab + (p+1)->hhab);
}

 

더보기

답) 501

jsu에는 {name, os, db, hab, hhab} 총 5개의 데이터가 들어가 있습니다.

이문장에서 struct jsu* p; p는 struct jsu의 포인터 변수 임을 알 수 있습니다. 
p = &st[0]; 포인터 변수 p는 배열 st[0]의 주소를 말합니다.

p = {"데이터1", 95, 88}

 

(p+1)→hab = (p+1)→os + (p+2)→db; 

(p+1) = {"데이터2", 84, 91}, (p+2) = {"데이터3", 86, 75}

(p+1)→os + (p+2)→db : 84 + 75 = 159

 

(p+1)→hhab = (p+1)→hab + p→os + p→db; 

(p+1)→hab + p→os + p→db : 159 + 95 + 88 = 342

 

printf("%d", (p+1)→hab + (p+1)→hhab)

(p+1)→hab + (p+1)→hhab : 159 + 342 = 501

 

 

 

 

 

 

8. 2021년 2회차 16번

int main()
{
   int res;
   res = mp(2,10);
   printf("%d",res);
   return 0;
}

int mp(int base, int exp) 
{
   int res = 1;
   for(int i=0; i < exp; i++)
   {
      res = res * base;
   }
   
   return res;
}

 

더보기
답) 1024

 

코딩 문제는 printf() 부터 확인하자. 그럼 이 문제는 res의 값을 구하라는 문제인걸 알 수 있습니다.

 

그래서 숫자를 하나씩 대입해보면 i가 9일때까지 res에 2를 곱하란 뜻입니다.

res = 1*2 =2
res = 2*2 =4 .... 이런식으로 나아갑니다. 그래서 마지막엔
res = 512 * 2 = 1024 가 됩니다.

 

 

 

 

 

 

 

9. 2021년 2회차 18번

int main()
{
   int arr[3];
   int s = 0;
   *(arr+0)=1;
   
   arr[1] = *(arr+0)+2;
   arr[2] = *arr+3;

   for(int i=0; i<3; i++)
   {
      s=s+arr[i]
   }

   print("%d",s);
}

 

더보기

답) 8

 

*(arr +0) = 1 이라는 말은 배열 arr의 첫번째 값의 주소의, 데이터값이 1이라는 뜻입니다.

 arr[1] = *(arr+0)+2 = 1+2=3
 arr[2] = *arr+3 = 1+3 =4

 

그래서 arr배열을 나타내보면 아래의 표와 같습니다.

c언어 배열

이제 for문을 보면 배열 arr[0]+ arr[1]+arr[2] 를 구하라는걸 알 수 있습니다.

따라서 답은 1+3+4=8

 

 

 

 

 

10.  2021년 1회차 15번

#include <stdio.h>

struct good 
{
    char name[10];
    int age;
};
 
void main()
{
    struct good s[] = {"Kim",28,"Lee",38,"Seo",50,"Park",35};
    
    struct good *p;
    p = s;
    p++
    
    printlf("%s\n", p-> name);
    printlf("%d\n", p-> age);
}

 

더보기

답)

Lee 38

 

보통 증감연산자가 있는 문제는 for문이나 while문 처럼 조건문 안에 넣어서 뺑뱅 돌리는 겅우가 많습니다. 그런데 이 문제는 아닙니다! 자세히 보시면 p++ 주위에 조건문이 없습니다. 

 

p에 1만 더하라는 뜻이죠.

 

struct good의 첫번째 요소의 주소를 나타내는 p, 그 p에 1을 더한거니까 두번째 요소의 값을 출력하면 됩니다.

 

즉, p++로 인해 s[0]이 s[1]가 되면서 두번째 배열의 데이터값인 Lee와 38이 출력됩니다.

 

 

 

 

 

11. 2020년 4회차 18번

#include <stdio.h>

void main()
{
	char *p = "KOREA"
    printf("%s\n" , p);
    printf("%s\n" , p+3);
    printf("%c\n" , *p);
    printf("%c\n" , *(p+3));
    printf("%c\n" , p+2);
}

 

더보기

답)

KOREA

EA

K

E

M

 

C언어에서 문자를 처리하는 데이터형은 2가지가 있습니다. char(문자), string(문자열). 차이는 char는 개별 문자 한글자를 말하고, string은 두개 이상의 문자결합 구조를 말합니다.

 

그리고 "KOREA" 이렇게 쌍따옴표로 묶여져 있는 것을 "문자열 상수"라고 하며, 이는 절대 불변의 데이터입니다.

 

그리고 가장 큰 특징은 문자열을 저장할때 맨뒤에 null문자가 자동으로 저장된다는 것입니다.  C언어에서 null은 한문자로 취급합니다. 그래서 KOREA를 예로 들면 K,O,R,E,A,\0 해서 총 6문자가 저장이 되는거죠

 

null 은 코드 상으로 \0 혹은 ₩0 라고 표기합니다.

 

C언어에서 문자열을 출력하는 자료형도 2가지가 있습니다. %c (단일문자) , %s (문자열) . 번외로 %p는 포인터의 주소를 출력합니다.

 

테스트 코드를 예시로 들어보겠습니다.

char *str = "KOREA" 를 보시면, str은 문자열상수 "KOREA"의 주소값을 저장합니다.

따라서 str %p값, 즉 "KOREA"의 시작점인 K의 주소값 "0x55ab292e9004"를 출력했고

 

주소인 str 의 한문자만 출력하는 %c 의 결과값은 주소"0x55ab292e9004"의 첫글자인 0을 출력하는 것이고, *str은 str의 값을 의미하고 이를 한문자만 출력하는 %c의 결과값은 K가 되는것이죠.

 

%s는 조금 특이한 녀석입니다. 애초에 입력을 받을때 주소를 입력받아야 합니다. 그래서 코드를 보시면 주소인 str을 입력받을땐 정상작동 하지만 값변수인 *str을 넣으면 오류가 나는 것을 보실 수 있습니다. 

 

즉 %s는 주소를 입력받아, 주소지 안에 있는 내용물을 null(\0) 전까지 출력하는 자료형 입니다.

 

그래서 문제를 다시보면 

 

printf("%s\n" , p); 즉 주소 p에가서 null문자 전까지 출력하란 뜻입니다. 그래서 KOREA가 출력됩니다. 

 

printf("%s\n" , p+3); 주소 p+3에 가서 null 문자 전까지 출력하면 EA

 

printf("%c\n" , *p); *p는 값변수죠? 그러니까 주소 p의 값을 한문자만 출력하면 K

 

printf("%c\n" , *(p+3)); p+3의 값을 한문자만 출력하면 E

 

printf("%c\n" , *p+2); *p는 아까말했듯이 K죠. 알파벳 순서상 K,L,M,N 이런식으로 나가고, K에서 2칸을 간 M이 출력됩니다.

 

여기서 주의하셔야 할것은 문자열상수 "KOREA"에서 두칸을 가는것이 아니라 문자자체 (*p)에서 두칸을 움직이는 것이여서 아스키코드 상에서 덧셈이 일어납니다. 그래서 M이 출력되는 것입니다.

 

 

 

 

 

12. 2020년 3회차 2번

#include <stdio.h>

void main()
{
	int i=0, c=0;
	while (i<10)
    {
		i++;
		c*=i
    }
	printf("%d",c);
}

 

더보기

답)

0

 

c가 0이므로 c에다가 어떤 숫자를 곱해도 0이 됩니다.

 

 

 

 

13. 2020년 3회차 13번

#include <studio.h>

int r1()
{
	return 4;
}
int r10()
{
	return (30+r1());
}
int r100()
{
	return (200+r10());
}
int main()
{
	printf("%d\n", r100());
    return 0;
}
더보기

답) 234

 

r100()= 200+ r10() = 200 + 30+ r1() = 200 +30 + 4 = 234

 

 

 

 

 

 

14. 2020년 1회차 12번

#include <stdio.h>

void main()
{
 	int i,j;
    int temp;
    int a[5] = {75,95,85,100,50};
    
    for(i=0; i<4; i++){
    	for(j=0; j<4-i; j++){
        	if(a[j] > a[j+1]){
            	temp=a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
             }
           }
        }
        
       	for(i=0; i<5; i++){
        	printf("%d", a[i]);
        }
  }

 

더보기

답) 50, 75, 85, 95, 100

 

temp=a[j];

a[j] = a[j+1];
a[j+1] = temp; 는 자리를 바꾸는 코드입니다. 그럼 언제 자리를 바꾸냐면

 

a[j]가 a[j+1]보다 클때 자리를 바꿉니다. 즉 큰 숫를 뒤로 보내는죠. 이 말은 배열안의 숫자를 오름차순 정렬 하라는 뜻입니다.

 

∴답은 50,75, 85, 95, 100

 

 

 


 

 

정보처리기사 실기 프로그래밍 문제 Java 기출 풀이 모음

2022년 정보처리기사 실기 2회차를 보고 느낀 점은 '코딩 문제는 일단 다 맞아야겠다' 였어요. 용어를 묻는 문제가 너무 지엽적으로 나와서 답을 적어내기가 어렵더라고요. 특히나 2020년도 이후에

roadtofree.tistory.com

 

정보처리기사 실기 프로그래밍 문제 파이썬 기출 풀이 모음

2022년 정보처리기사 실기를 보고 느낀 점은 '코딩 문제를 일단 다 맞자!' 였어요. 용어를 묻는 문제가 너무 지엽적으로 나오기도 했고, 그 많은 방대한 범위를 정확하게 써 내려갈 정도로 공부를

roadtofree.tistory.com

 

정보처리기사 실기 프로그래밍 문제 SQL 기출 풀이 모음

정보처리기사 실기 2회차를 보고, 또 떨어지고 나서 느낀점은 '코딩 문제는 일단 다 맞아야 겠구나!' 였어요. 용어를 묻는 문제가 생각보다 너무 많이 나오기도 했고, 그 내용이 너무 지엽적이여

roadtofree.tistory.com

 

반응형