2023 정보처리기사 실기 예상 문제 모음

 

C언어 기출문제 모음

JAVA 기출문제 모음

Python 기출문제 모음

정보처리기사 실기 SQL 기출문제 모음

 

정보처리산업기사(정처산기) 실기 C언어 기출문제 모음

정보처리산업기사(정처산기) 실기 Java 기출문제 모음

정보처리산업기사(정처산기) 실기 Python 기출문제 모음

정보처리산업기사(정처산기) 실기 SQL 기출문제 모음


22년 1회

6. 다음 C언어로 구현된 프로그램을 실행하여 7을 입력했을 때, 그 실행결과를 쓰시오

#include <stdio.h>

main() {
  int n, count=0;
  scanf("%d", &n);
  for(int i=2; i<=n/2;i++)
    if(i%1==0)
      count++;
  printf("%d",count);
}

22년 1회

9. 다음 C언어로 구현된 프로그램을 분석하여 그 실행결과를 쓰시오.

#include <stdio.h>

main() {
  int n=3, r=0;
  for(int i=1; i<10;i=i+2)
    r=r+n*i;
  printf("%d", r);
}

22년 1회

14. 다음 C언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오.

#include <stdio.h>

main() {
  int n1=15, n2=22;
  n1 ^=n2;
  n2 ^=n1;
  n1 ^=n2;
  printf("%d %d", n1, n2);
}
더보기

22 15


22년 1회

17. 다음 C언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오.

#include <stdio.h>

main() {
  int num=35, evencnt=0, oddcnt=0;
  for(int i=1; i<=num; i++){
    if(i%2==0)
      evencnt++;
    else
      oddcnt++;
  }
  printf("%d %d", evencnt, oddcnt);
}
더보기
17 18

22년 2회

1. 다음 C언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오.

#include <stdio.h>

main() {
  int a=27, b=12;
  int l, g;
  for(int i=b; i>0; i--){
    if(a%i==0&&b%i==0){
      g=i;
      break;
    }
  }
  l=a*b/g;
  printf("%d",g+l);
}

22년 2회

7. 다음 C언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오.

#include <stdio.h>

main() {
  int sum=0;
  int i=0;
  for(i=0;i<=10;i++){
    if(i%2!=0)
      continue;
        sum+=i;
  }
  printf("%d",i+sum);
}

22년 2회

14. 다음 C언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오.

#include <stdio.h>
main() {
  int arr[6];
  int max=0, min=99;
  int sum=0;
  for(int i=0; i<6;i++){
    arr[i]=i*i;
    sum+=arr[i];
  }
  for(int i=0;i<6;i++){
    if (max<arr[i])
      max=arr[i];
    if (min>arr[i])
      min=arr[i];
  }
  printf("%.2f",(sum-max-min)/4.0);
}
더보기

7.50


22년 2회

15. 다음 C언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오.

#include <stdio.h>
#include <math.h>
main() {
  int arr[5];
  for(int i=0; i<5;i++){
    arr[i]=(i+2)+(i*2);
  }
  for(int i=0;i<5;i++){
    printf("%d",check(arr[i]));
  }
}
int check(int a){
  int n=(int)sqrt(a);
  int i=2;
  while(i<=n){
    if(a%i==0) return 0;
    i++;
  }
  return 1;
}
더보기

11010


22년 2회

19. 다음 C언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오.

#include <stdio.h>

main() {
  char a[3][5]={"KOR","HUM","RES"};
  char*pa[]={a[0],a[1],a[2]};
  int n=sizeof(pa)/sizeof(pa[0]);
  for(int i=0; i<n;i++)
    printf("%c", pa[i][i]);
}

22년 3회

6. 다음 C언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오.

#include <stdio.h>

main() {
  int a[3][5]={{27,13,21,41,12},{11,20,17,35,15},{21,15,32,14,10}};
  int sum, ssum=0;
  for(int i=0;i<3; i++){
    sum=0;
    for(int j=0; j<5;j++)
      sum+=a[i][j];
    ssum+=sum;
  }
  printf("%d",ssum);
}

22년 3회

8. 다음 C언어로 구현된 프로그램을 분석하여 그 실행 결과를 쓰시오.

#include <stdio.h>

main() {
  int i=1, n=0;
  while(i<=50){
    if(i%7==0)
      n+=i;
    i++;
  }
  printf("%d", n);
}

22년 3회

16. 다음 C언어로 구현된 프로그램에서 화면에 5를 입력한 후 나타나는 결과를 쓰시오.

#include <stdio.h>

main() {
  int n, sum=0;
  printf("정수를 입력하시오 : ");
  scanf("%d",&n);
  for (int i=1; i<=n;i++)
    sum=sum+i;
  printf("%d", sum);
}

23년 1회

4. 다음 코드에서 (가)에 들어갈 것을 쓰시오.

#include<stdio.h>
#define LEN 10
void swap(int arr[], int i, int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}
int partition(int arr[], int left, int right) {
	int pivot = arr[(left + right) / (가)];
	while(left <= right) {
		while(arr[left] < pivot)
			left++;
		while(arr[right] > pivot) 
			right--;
		if(left <= right) {
			swap(arr, left, right);
			left++;
			right--;
		}
	}
	return left;
}
void sort(int arr[], int left, int right) {
	if(left >= right)
		return;
	int center = partition(arr, left, right);
	sort(arr, left, center-1);
	sort(arr, center, right);
}
void quick_sort(int arr[]) {
	sort(arr, 0, LEN-1);
}
int main(void) {
	int data[LEN] = {5, 8, 3, 12, 9, 25, 15, 21, 1, 19};
	quick_sort(data);
	for(int i=0;i<LEN;i++){
		printf("%d\n", data[i]);
	}
}
더보기

2

 

퀵 정렬 문제


23년 1회

5. 다음 코드에서 (가)에 들어갈 것을 쓰시오.

#include<stdio.h>
int SumNTo1(int n) {
	if(n <= 1)
		return 1;
	else
		return n + (가);
}
int main() {
	int result = SumNTo1(100);
	printf("%d", result);
}
더보기

 SumNTo1(n-1)


23년 1회

16. 다음 코드에서 (가)에 들어갈 것을 쓰시오.

#include<stdio.h>
int recursive(int n) {
	if(n <= 1) 
		return 1;
	else 
		return n*n+recursive((가));
}
int main() {
	int i;
	scanf("%d", &i);
	printf("%d ", recursive(i));
}

23년 2회

3. 출력 결과

#include<stdio.h>
int main() {
	int d = 55;
	int n = 4;
	int r = 0, q = 0;
	r = d;
	while(r >= 4) {
		r = r - n;
		q++;
	}
	printf("%d 그리고 ", q);
	printf("%d", r);
}
더보기

13 그리고 3


23년 2회

16. 코드 아래에 있는 것이 출력결과인데 출력결과의 파란색 빈칸에 들어갈 출력값을 적으시오

#include<stdio.h>
void Sort(int a[][6]) {
	for(int i=0; i<=4; i++) {
		for(int j=5; j>=0; j--) {
			if(i==0 | i==4 | j==0 | j==5) {
				printf("%3d", a[i][j]);
			}
			else {
				printf("   ");  // 공백 3칸 
			}
		}
		printf("\n");
	}
}
int main() {
	int a[5][6] = {{0, 1, 2, 3, 4, 5},
				{6, 7, 8, 9, 10, 11},
				{12, 13, 14, 15, 16, 17},
				{18, 19, 20, 21, 22, 23},
				{24, 25, 26, 27, 28, 29}};
	Sort(a);
}

더보기

17                           12

23                           18


23년 2회

17. 출력결과

#include<stdio.h>
int main() {
	char s1[5] = "abcd";
	char s2[5];
	for(int i=0; i<4; i++) {
		s2[i] = s1[3-i];
	}
	s2[5] = '\0';
	printf("%s", s2);
}
더보기

dcba


23년 2회

18. 출력결과

#include<stdio.h>
int main() {
	// A = 65, a = 97
	int a = 10;
	char b = 'a';
	printf("%d \n", a);
	printf("%d \n", b); 
	printf("%c", b); 
}
더보기

10
97
a


23년 2회

20. 출력결과

#include<stdio.h>
int main() {
	int result=1, i;
	for(i=1; i<=5; i++) {
		result *= i;
	}
	printf("%d", result);
}

23년 3회

2. 출력결과

#include<stdio.h>
#define MAX 4
int prin(int a);
int main() {
	prin(MAX);
}
int prin(int a) {
	if(a > 1) prin(a-1);
	printf("%d", a);
}
더보기

1234


23년 3회

5. 달팽이 배열


23년 3회

7. 출력결과

#include<stdio.h>
int main() {
    int data[] = {15, 12, 26, 23, 31, 36};
    int temp = 0;
    int cnt = sizeof(data)/sizeof(int);
    for(int i=0; i < cnt-1; i++) {
        for(int j=0; j < cnt - 1 - i; j++){
            if(data[j] > data[j+1]) {
                temp = data[j];
                data[j] = data[j+1];
                data[j+1] = temp;
            }
            }
        }
      
    for(int i=1; i<cnt-1;i++){
        printf("%d ", data[i]);
    }
}
더보기

15 23 26 31


23년 3회

9. 출력결과

#include<stdio.h>
int sub(int* a) {
	printf("%d", *a);
	printf("%d", a[2]);
}
int main() {
	int a[10] = {1,2,3,4,5,6};
	sub(a);
	sub(a+2);
}
더보기

1335


23년 3회

13. (가), (나)에 적절한 것을 쓰시오

#include<stdio.h>
int compare(int i, int j, int *ma, int *in) {
	if(i>j) {
		*ma = j;
		*in = i;
	}
	else {
		*ma = i;
		*in = j;
	}
}
int main() {
	int max = 0;
	int min = 0;
	compare(3, 7, (가), (나));
	printf("작은수:%d 큰수:%d", max, min);
}
더보기

(가) &max

(나) &min

 


2023 정보처리기사 실기 예상 문제 모음

 

C언어 기출문제 모음

JAVA 기출문제 모음

Python 기출문제 모음

정보처리기사 실기 SQL 기출문제 모음

 

정보처리산업기사(정처산기) 실기 C언어 기출문제 모음

정보처리산업기사(정처산기) 실기 Java 기출문제 모음

정보처리산업기사(정처산기) 실기 Python 기출문제 모음

정보처리산업기사(정처산기) 실기 SQL 기출문제 모음

[정보처리기사/예상문제] - 2023 정보처리기사 실기 예상 문제 모음

[2022년 1회] 정보처리산업기사 실기 기출문제

[2022년 2회] 정보처리산업기사 실기 기출문제

[2022년 3회] 정보처리산업기사 실기 기출문제

「23년 1회」정보처리산업기사 실기 기출문제

「23년 2회」정보처리산업기사 실기 기출문제


1. 다음은 트랜잭션의 4가지 특성에 대한 설명이다. 설명에 해당하는 것을 쓰시오(원래는 <보기>에서 고르는 문제)

1. 둘 이상의 트랜잭션이 동시에 병행 실행되는 경우 어느 하나의 트랜잭션 실행 중에 다른 트랜잭션의 연산이 끼어들 수 없다
2. 트랜잭션이 일단 완료되면 그 후에 어떤 형태로 시스템이 고장 나더라도 트랜잭션의 결과는 잃어버리지 않고 지속되어야 한다.
더보기

1. 격리성

2. 지속성


2. 보기에 있는 것을 DDL, DML, DCL로 분류하시오.

<보기>
GRANT
DELETE
CREATE
ALTER
SELECT
REVOKE
INSERT
UPDATE
DROP
더보기

DDL : CREATE, ALTER, DROP

 

DML: SELECT, DELETE, INSERT, UPDATE

 

DCL : REVOKE, GRANT


3. 출력 결과

#include<stdio.h>
int main() {
	int d = 55;
	int n = 4;
	int r = 0, q = 0;
	r = d;
	while(r >= 4) {
		r = r - n;
		q++;
	}
	printf("%d 그리고 ", q);
	printf("%d", r);
}
더보기

13 그리고 3


4. 데이터링크 계층의 대표적인 프로토콜로 정보를 전송 제어 부호가 포함된 프레임이라는 단위로 분할하여 전송하며 프로토콜의 구조는 프레임의 끝, 주소부, 제어부, 데이터부, 오류검출부로 구분된다.

프레임은 I-Frame, S-Frame, U_Frame이 있다. 설명에 해당하는 프로토콜을 쓰시오

더보기

HDLC


5. 아래 OSI계층 표의 PDU(데이터 단위)를 쓰시오.

(원래는 보기가 있는 문제)

물리 계층  
데이터링크 계층  
네트워크 계층  
더보기
물리 계층 비트
데이터링크 계층 프레임
네트워크 계층 패킷

6. 아래 처리조건을 보고 SQL문을 작성하시오.

<처리조건>
-학생 테이블에서 학년이 3학년 이상이 수강하는 과목을 검색한다
-검색 결과 중복을 제거한다
더보기

SELECT DISTINCT 과목 FROM 학생 WHERE 학년 >= 3;


7. <보기>를 V모델 순서대로 나열하시오

<보기>
ㄱ. 인수 테스트
ㄴ. 시스템 테스트
ㄷ. 통합 테스트
ㄹ. 단위 테스트
더보기

ㄹ -> ㄷ -> ㄴ -> ㄱ

단위->통합->시스템->인수


8. 아래는 정규화 과정 중 일부에 대한 설명이다. 적절한 설명을 보기에서 고르시오

<보기>
ㄱ. 이행적 함수 종속 관계를 제거한다
ㄴ. 기본키에 속하지 않는 모든 속성이 기본키에 완전 함수 종속이 되도록 부분 함수 종속성을 제거한다.
ㄷ. 결정자가 후보키가 아닌 함수 종속성을 제거한다

1) 제 2정규화 : 

2) 제 3정규화 : 

3) BCNF : 

더보기

1) 제 2정규화 : ㄴ

2) 제 3정규화 : ㄱ

3) BCNF : ㄷ


9. 아래 기호를 써서 HRN 스케줄링 기법에 우선 순위 공식을 쓰시오

P: 우선순위
S: 서비스 시간
W : 대기 시간
더보기

P=(S+W)/ S 또는 (W+S)/S


10. 다음 설명에 해당하는 것을 보기에서 고르시오 

데이터 프레임을 연속적으로 전송하는 과정에서 NAK를 수신하게 되면, 오류가 발생한 프레임 이후에 전송된 모든 데이터 프레임을 재전송하는 방식이다
<보기>
ㄱ. Selective-Repeat ARQ
ㄴ. Stop-and-Wait ARQ
ㄷ. Non-Acknowledge ARQ
ㄹ. Go-Back N ARQ
ㅁ. Selective ARQ
ㅂ. Adaptive ARQ
ㅅ. Forward-Stop ARQ
ㅇ. Auto-Repeat ARQ
더보기

Go-Back N ARQ


11. 다음 보기에서 Python 언어의 특징을 모두 고르시오

<보기>
ㄱ. 변수 선언 시 자료형 작성은 필수
ㄴ. 세미콜론을 사용하지 않아도 된다
ㄷ. 변수에 연속하여 값을 저장하는 것이 가능하다
ㄹ. 같은 수준의 코드는 반드시 동일한 여백을 가져야 한다
ㅁ. gcc를 이용해 컴파일하기 때문에 인터프리터 언어가 아니다
더보기

ㄴ, ㄷ, ㄹ


12. 다음은 Java 관련 용어에 대한 설명이다. 설명에 해당하는 것을 쓰시오

Java에서 힙(heap)에 남아있으나변수가 가지고 있던 참조값을 잃거나 변수 자체가 없어짐으로써 더 이상 사용되지 않는 객체
더보기

가비지(Garbage)


13. 다음 <보기>를 블랙박스와 화이트박스 테스트로 분류하시오

<보기>
ㄱ. 제품의 내부 요소들이 명세서에 따라 수행되고 충분히 실행되는 가를 보장하기 위한 검사이다
ㄴ. 각 기능별로 적절한 정보 영역을 정하여 적합한 입력에 대한 출력의 정확성을 점검한다
ㄷ. 프로그램의 구조에 의거하여 테스트 하는 것이다
ㄹ. 요구사항 명세서에 기술되어 있는 소프트웨어 기능을 토대로 실시하는 테스트이다

블랙 박스 테스트 : 

화이트박스 테스트 : 

더보기

블랙 박스 테스트 : ㄴ, ㄹ

화이트박스 테스트 : ㄱ, ㄷ


14. 정보처리를 수행하는 응용 프로그램과의 인터페이스를 제공하며 전자우편이나 파일 전송 같은 사용자 서비스를 제공하는 OSI 계층을 쓰시오

더보기

응용 계층


15. 출력결과

class Main {
    public static void main(String[] args) {
    	int[] a = {4, 7, 1, 2};
    	for(int i=0; i<3; i++) {
    		for(int j=i+1; j<4; j++) {
    			if(a[i] > a[j]) {
    				int temp = a[j];
    				a[j] = a[i];
    				a[i] = temp;
    			}
    		}
    	}
    	for(int i=0; i<4; i++) {
    		System.out.print(a[i] + "a");
    	}
    }
}
더보기

1a2a4a7a


16. 코드 아래에 있는 것이 출력결과인데 출력결과의 파란색 빈칸에 들어갈 출력값을 적으시오

#include<stdio.h>
void Sort(int a[][6]) {
	for(int i=0; i<=4; i++) {
		for(int j=5; j>=0; j--) {
			if(i==0 | i==4 | j==0 | j==5) {
				printf("%3d", a[i][j]);
			}
			else {
				printf("   ");  // 공백 3칸 
			}
		}
		printf("\n");
	}
}
int main() {
	int a[5][6] = {{0, 1, 2, 3, 4, 5},
				{6, 7, 8, 9, 10, 11},
				{12, 13, 14, 15, 16, 17},
				{18, 19, 20, 21, 22, 23},
				{24, 25, 26, 27, 28, 29}};
	Sort(a);
}

더보기

17                           12

23                           18

 


17. 출력결과

#include<stdio.h>
int main() {
	char s1[5] = "abcd";
	char s2[5];
	for(int i=0; i<4; i++) {
		s2[i] = s1[3-i];
	}
	s2[5] = '\0';
	printf("%s", s2);
}
더보기

dcba


18. 출력결과

#include<stdio.h>
int main() {
	// A = 65, a = 97
	int a = 10;
	char b = 'a';
	printf("%d \n", a);
	printf("%d \n", b); 
	printf("%c", b); 
}
더보기

10
97
a


19. SQL문에서 특정 속성의 값을 제한하기 위해 사용하는 문법으로 도메인이 가질 수 있는 값의 범위를 제약할 때 사용하는 제약조건을 쓰시오.

더보기

CHECK


20. 출력결과

#include<stdio.h>
int main() {
	int result=1, i;
	for(i=1; i<=5; i++) {
		result *= i;
	}
	printf("%d", result);
}

[정보처리기사/예상문제] - 2023 정보처리기사 실기 예상 문제 모음

[2022년 1회] 정보처리산업기사 실기 기출문제

[2022년 2회] 정보처리산업기사 실기 기출문제

[2022년 3회] 정보처리산업기사 실기 기출문제

「23년 1회」정보처리산업기사 실기 기출문제

「23년 2회」정보처리산업기사 실기 기출문제

[정보처리기사/예상문제] - 2023 정보처리기사 실기 예상 문제 모음

[2022년 1회] 정보처리산업기사 실기 기출문제

[2022년 2회] 정보처리산업기사 실기 기출문제

[2022년 3회] 정보처리산업기사 실기 기출문제

「23년 1회」정보처리산업기사 실기 기출문제

「23년 2회」정보처리산업기사 실기 기출문제


1. 운영체제 운용 기법을 <보기>에서 고르시오

① 하나의 주기억장치에 여러 개의 프로그램을 동시에 처리하는 방식
② 자료나 정보 단위들이 발생할 때마다 즉각적으로 처리하는 것이 아니라 일정량 또는 일정 기간 동안 모아 두었다가 한꺼번에 처리하는 방식
③ CPU의 전체 사용 시간을 작은 작업 시간량으로 나누어서 그 시간량 동안만 번갈아가면서 CPU를 할당하여 각 작업을 처리하는 방식
④ 컴퓨터 시스템에 여러 개의 프로세스(CPU)를 사용하여 처리하는 방식
<보기>
ㄱ. 일괄 처리시스템
ㄴ. 다중 프로그래밍 시스템
ㄷ. 시분할 시스템
ㄹ. 다중 처리 시스템
더보기

① ㄴ

② ㄱ

③ ㄷ

④ ㄹ


2. 개체와 관계를 아래 E-R모델에서 찾아 쓰시오

더보기

1. 개체 : 고객, 책, 출판사

2. 관계 : 구매, 공급


3. 내부에서 사설 IP 주소를 사용하고 외부 네트워크로 나가는 주소는 공인 IP 주소를 사용하도록 하는 IP 주소 변환 방식으로 사설 IP 주소를 공인 IP 주소로 바꿔주는데 사용하는 통신망의 주소 변환 기술


4. 다음 코드에서 (가)에 들어갈 것을 쓰시오.

#include<stdio.h>
#define LEN 10
void swap(int arr[], int i, int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}
int partition(int arr[], int left, int right) {
	int pivot = arr[(left + right) / (가)];
	while(left <= right) {
		while(arr[left] < pivot)
			left++;
		while(arr[right] > pivot) 
			right--;
		if(left <= right) {
			swap(arr, left, right);
			left++;
			right--;
		}
	}
	return left;
}
void sort(int arr[], int left, int right) {
	if(left >= right)
		return;
	int center = partition(arr, left, right);
	sort(arr, left, center-1);
	sort(arr, center, right);
}
void quick_sort(int arr[]) {
	sort(arr, 0, LEN-1);
}
int main(void) {
	int data[LEN] = {5, 8, 3, 12, 9, 25, 15, 21, 1, 19};
	quick_sort(data);
	for(int i=0;i<LEN;i++){
		printf("%d\n", data[i]);
	}
}
더보기

2

 

퀵 정렬 문제


5. 다음 코드에서 (가)에 들어갈 것을 쓰시오.

#include<stdio.h>
int SumNTo1(int n) {
	if(n <= 1)
		return 1;
	else
		return n + (가);
}
int main() {
	int result = SumNTo1(100);
	printf("%d", result);
}
더보기

 SumNTo1(n-1)


6. 다음 설명에 해당하는 것이 뭔지 쓰시오.

1. 트랜잭션이정상적으로 수행하여 변경된 내용을 실제 물맂거 디스크에 저장할 때 사용하는 연산
2. 트랜잭션의 실행이 비정상적임을 알리는 연산자로 트랜잭션이 수행한 결과를 원래의 상태로 원상 복귀 시키는 연산
더보기

1. commit

2. rollback


7. 관계 대수 연산자를 <보기>에서 고르시오.

1. 한 릴레이션에서 조건에 만족하는 튜플들의 부분 집합을 구한다
2. 한 릴레이션의 속성들의 부분집합을 구한다
3. 두 릴레이션 모두에 속한 튜플들로 이루어진 릴레이션을 생성한다
4. 두 릴레이션 중 하나의 릴레이션에는 속하지만 다른 하나의 릴레이션에는 속하지 않는 튜플들로 이루어진 릴레이션을 생성한다.
<보기>
ㄱ. select
ㄴ. project
ㄷ. intersection
ㄹ. difference
더보기

1. ㄱ

2. ㄴ

3. ㄷ

4. ㄹ


8. 다음 설명에 해당하는 용어를 쓰시오

IP 프로토콜 위에서 연결형 서비스를 지원하는 프로토콜로 데이터를 세그먼트라는 블록 단위로 분할해 전송하며 전이중 방식의 양방향 가상 회선을 제공하기 때문에 신뢰성 있는 데이터 전송을 보장하며 흐름 제어 기능과 혼잡 제어 기능을 지원하여 네트워크에서의 데이터 전달 통제가 가능한 프로토콜

9. 다음은 Ipv4 헤더이다. Header Length와 Destination Ip Address 크기를 구하시오

더보기

Header Length : 4

Destination Ip address : 32


10. SRT 방식으로 스케줄링 할 경우, 입력된 작업이 다음과 같을 때 평균 반환시간과 평균 대기시간을 구하시오

더보기

평균 반환 시간 : 6.75

평균 대기 시간 : 3.25

 

 

SRT(Shortest Remaining Time)
SJF방식을 선점 스케줄링 방식으로 변경한 기법
최단 잔여시간을 우선으로 하는 스케줄링이다
진행 중인 프로세스가 있어도, 최단 잔여시간인 프로세스를 위해 sleep 시키고 짧은 프로세스를 먼저 할당한다.


11. 단위 테스트가 끝난 모듈을 통합하는 과정에서 발생할 수 있는 오류를 찾는 테스트가 통합 테스트(integration test)이다. 이때 단위 테스트가 끝난 모듈을 한꺼번에 결합하여 수행하는 방식을 뭐라고 하는지 쓰시오.

(원래 문제는 보기 있는 문제)

더보기

빅뱅(bigbang) 테스트


12. 다음 코드의 출력결과를 쓰시오

public class Main {
	public static void main(String[] args) {   // true, false
		int x = 1;
		System.out.println(!(x>0));
		System.out.println((x!=0) || (x>0));
		System.out.println(x << 2);
		System.out.println(x & 2);
		System.out.println(x %= 3);
	}
}
더보기

false
true
4
0
1


13. IP 주소가 191.168.25.0이고 서브넷 마스크가 255.255.252.0일 때, 네트워크 주소와 브로드캐스트 주소를 쓰시오

더보기

1. 네트워크 주소 : 191.168.24.0

2. 브로드캐스트 주소 : 191.168.27.255


14. 데이터 링크 계층 기능 중 옳은 것을 모두고르시오

<보기>
ㄱ. 주소 지정
ㄴ. 순서 제어
ㄷ. 흐름 제어
ㄹ. 오류 처리
ㅁ. 동기화
더보기

ㄴ,ㄷ, ㄹ, ㅁ


15. 다음은 교착상태 필요충분조건중 하나이다. 설명에 해당하는 것을 쓰시오.

1. 프로세스들이 필요로 하는 자웡네 대해 배타적인 통제권을 요구한다
2. 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있다.
더보기

1. 상호 배제

2. 순환 대기


16. 다음 코드에서 (가)에 들어갈 것을 쓰시오.

#include<stdio.h>
int recursive(int n) {
	if(n <= 1) 
		return 1;
	else 
		return n*n+recursive((가));
}
int main() {
	int i;
	scanf("%d", &i);
	printf("%d ", recursive(i));
}

17. 다음은 데이터 베이스 질의 처리기에 대한 설명이다. <보기>에서 고르시오

1. 데이터 조작어(삽입, 삭제, 수정, 검색) 요청을 분석하여 런타임 데이터베이스 처리기가 이해할 수 있도로 해석한다
2. 데이터베이스에 접근하는 과정에서 사용자의 접근 권한이 유효한지 검사하고 데이터베이스 무결성을 유지하기 위한 제약조건 위반 여부를 확인한다. 회복이나 병행 수행과 관련된 작업도 한다.
<보기>
ㄱ. DDL 컴파일러
ㄴ. DML 프리컴파일러
ㄷ. DML 컴파일러
ㄹ. 런타임 데이터베이스 처리기
ㅁ. 트랜잭션 관리자
더보기

1. ㄷ

2. ㅁ


18. 문장 커버리지 수행 순서를 쓰시오

#include<stdio.h>
int main() {
	int i = 1;
	while(i<=1) {
		if(i%2==1)
			printf("%d", i);
		i++;
	}
	return 0;
}

사진 출처 : 기사퍼스트 유튜브 채널

<테스트 케이스>
1->(     ) - > (      ) ->(     ) - > (      ) ->(     ) - > (      )
더보기

1234526


19. 다음은 Company 테이블을 생성하는 SQL문이다. company 테이블의 TITLE 속성에는 Intern, Staff, Manager, Director, President 값만 허용할 수 있도록 <SQL문> (가) 와 (나)에 적합한 단어를 쓰시오

CREATE TABLE COMPANY(
           ID INT NOT NULL,
           NAME VARCHAR(20) NOT NULL,
           AGE INT NOT NULL,
           TITLE VARCHAR(20) (가) (TITLE(나) ('Intern','Staff','Manager','Director','President'))
       );
더보기

(가) CHECK

(나) IN


20. 다음 (가)에 무엇이 들어갈지 쓰시오

wallet=['credit','id']
card=True
if('cash'in wallet):
	print('택시')
(가)(card):	
	print('버스')
else:
	print('도보')
지갑안에 신용카드(credit)와 신분증(id)이 있고 카드(card)를 가지고 있다.
대중교통을 이용하는데
지갑 안에 현급(cash)이 있다면 택시를 이용하고
현금이 없는 경우 카드가 있는지 확인하고
카드가 있다면 버스를 이용한다
만약 현금과 카드 둘다 없다면 도보를 이용한다
더보기

elif

 


[정보처리기사/예상문제] - 2023 정보처리기사 실기 예상 문제 모음

[2022년 1회] 정보처리산업기사 실기 기출문제

[2022년 2회] 정보처리산업기사 실기 기출문제

[2022년 3회] 정보처리산업기사 실기 기출문제

「23년 1회」정보처리산업기사 실기 기출문제

「23년 2회」정보처리산업기사 실기 기출문제

 

★연습문제1

1. 상품관리(EC_Product) 테이블에서 단가(Unit_price)가 평균 단가보다 높은 상품에 대하여 [상품코드, 상품명, 단가]를 출력하시오.

더보기
SELECT PRODUCT_CODE, PRODUCT_NAME, UNIT_PRICE
FROM   EC_Product
WHERE  UNIT_PRICE > (SELECT AVG(UNIT_PRICE)
                     FROM   EC_Product);

2. 주문처리(EC_Order) 테이블로부터 입금액이 제일 많은 [주문자ID, 상품코드, 주문수량, 결제방법, 입금액]을 출력하시오.

더보기
SELECT ORDER_ID, PRODUCT_CODE, ORDER_QTY,CSEL,CMONEY
  FROM EC_Order
 WHERE CMONEY = (SELECT MAX(CMONEY)
                   FROM EC_Order);

3. 주문처리(EC_Order) 테이블에서 결제종류별 입금한 금액이 제일 많은 행에 대하여 [결제종류, 주문자ID, 입금액, 입금일자]를 입금액순으로 출력하시오.

더보기
SELECT CSEL "결제종류",ORDER_ID, CMONEY "입급액", CDATE "입급일자"
FROM   EC_Order
WHERE  CMONEY IN (SELECT MAX(CMONEY)
                   FROM EC_Order
                   GROUP BY CSEL);

4. 주문처리(EC_Order)테이블에서 한 번 이상 거래한 회원의 [회원 ID, 회원명, 주민등록번호, 전화번호]를 회원명순으로 출력하시오. 

더보기
SELECT USERID, NAME,REGIST_NO,TELEPHONE
FROM   EC_Member M
WHERE  EXISTS (SELECT *
                   FROM   EC_Order O
                   WHERE  M.USERID= O.ORDER_ID)
ORDER BY 2;

5. 회원관리(EC_Member) 테이블과 주문처리(EC_Order) 테이블을 이용하여 한 번도 거래하지 않은 회원의 [회원ID, 회원명, 주민등록번호, 전화번호]를 회원명순으로 출력하시오.

더보기
SELECT USERID, NAME,REGIST_NO,TELEPHONE
FROM   EC_Member M
WHERE  NOT EXISTS (SELECT *
                   FROM   EC_Order O
                   WHERE  M.USERID= O.ORDER_ID)
ORDER BY 2;

6. 장바구니(EC_Basket) 테이블의 [주민번호, 주문자 ID, 상품코드, 주문수량, 주문일자]를 출력하여 확인한 모든 행을 주문처리(EC_Order) 테이블에 저장하고, 장바구니(EC_Basket) 테이블의 모든 행을 영구히 삭제하시오.

더보기
SELECT ORDER_NO, ORDER_ID, PRODUCT_CODE, ORDER_QTY, ORDER_DATE
FROM  EC_BASKET;

INSERT INTO EC_Order(ORDER_NO,ORDER_ID,PRODUCT_CODE,ORDER_QTY,CDATE)
SELECT*
FROM  EC_BASKET;

SELECT ORDER_NO, ORDER_ID, PRODUCT_CODE,ORDER_QTY, CMONEY
FROM   EC_Order
WHERE  CMONEY IS NULL;

DELETE FROM EC_Basket;

commit;

7. 주문처리(EC_Order) 테이블의 결제금액(cmoney)이 널인 행에 대하여 주문 수량(Order_Qty)과 상품관리(EC_Product) 테이블의 단가(Unit_Price)를 이용하여 주문처리(EC_Order) 테이블의 주문금액(주문수량 x 단가)을 계산하여 저장하고, 구분(Gubun) 칼럼에 '미결'로 수정하시오. (서브 쿼리를 사용한 UPDATE문)

더보기
UPDATE EC_Order O
SET    CMONEY =ORDER_QTY*(SELECT UNIT_PRICE
                          FROM   EC_Product P
                          WHERE  O.PRODUCT_CODE=P.PRODUCT_CODE)
       ,Gubun='미결'
WHERE  CMONEY IS NULL;

select ORDER_NO, PRODUCT_CODE, ORDER_QTY, CMONEY, GUBUN
from   EC_Order
WHERE  Gubun='미결';

commit;

8. 상품관리 테이블(EC_Product)에서 단가가 높은 상위 상품 TOP-5에 대하여 [순위, 상품코드, 상품명, 단가, 생산처]를 출력하시오. (인라인 뷰)

더보기
SELECT ROWNUM "순위", a.*
FROM (SELECT Product_CODE, Product_Name, UNIT_PRICE,COMPANY
      FROM   EC_Product
      ORDER  BY 3 DESC)a
WHERE ROWNUM<=5;

9. 상품관리 테이블(EC_Product)에서 단가가 높은 상위 상품 11위부터 15위까지 [num, 상품코드, 상품명, 단가, 생산처]를 출력하시오. (인라인 뷰)

더보기
SELECT*
FROM (SELECT ROWNUM num, a.*
      FROM (SELECT Product_CODE, Product_Name, UNIT_PRICE,COMPANY
            FROM   EC_Product
            ORDER  BY 3 DESC)a
            )
WHERE num BETWEEN 11 AND 15;

10. 주문처리(EC_Order) 테이블과 동일한 Empty_Order 빈 테이블을 생성하고, Empty_Order 테이블의 구조를 확인하시오.

더보기
CREATE TABLE Empty_Order
AS
       SELECT *
       FROM   EC_Order
       WHERE  1=2;
       
DESC Empty_Order

★연습문제2

1. 주문처리(EC_Order) 테이블로부터 'jupark'가 주문한 상품과 동일한 상품의 구매지수를 출력하시오. (스칼라 서브 쿼리 이용)

더보기
SELECT Order_ID, Product_Code, (SELECT COUNT(*)
                                FROM EC_Order A
                                WHERE A.Product_code=B.Product_code
                                ) "동일상품_구매자수"
FROM   EC_Order B                                
WHERE  Order_ID = 'jupark';

2. 주문처리(EC_Order) 테이블에서 구분(Gubun) 칼럼이 '배달' 또는 '결제' 행에 대하여 2018년 1월 1일부터 2018년 7월 30일까지 주문자ID별 결젲 합계 금액을 회원관리(EC_Member) 테이블의 구매실적(BuyCash)칼럼에 합하여 저장하시오.

더보기
UPDATE EC_Member M
SET    BuyCash = BuyCash +
                 (SELECT SUM(CMoney)
                  FROM EC_Order O
                  WHERE O.Order_ID= M.UserID
                  AND CDate BETWEEN '2018/01/01' AND '2018/07/30'
                  AND Gubun IN ('배달', '결제'));

SELECT UserID, Name, TO_CHAR(BuyCash, 'L99,999,999')
FROM   EC_Member
WHERE  Buycash IS NOT NULL;

3. 주문처리(EC_Order) 테이블과 상품관리(EC_Product) 테이블, 회원관리(EC_Member) 테이블을 이용하여 결제합계금액(Cmoney)이 가장 많은 금액중 상위 5명에 대한 (회원명, 결제합계금액)을 출력하시오. (인라인 뷰 이용)

더보기
SELECT ROWNUM "순위", a.*
FROM  (SELECT Name "회원명", SUM(CMoney) "결제합계금액"
       FROM EC_Order O INNER JOIN EC_Member M ON O.Order_ID= M.UserID
       GROUP BY Name
       ORDER BY 2 DESC ) a
WHERE  ROWNUM <= 5;

4. 주문처리(EC_Order) 테이블과 상품관리(EC_Product) 테이블을 이용하여 최근에 주문 결제한 상위자 5명에 대하여 (순위, 상품코드, 상품명, 주문수량, 결제방법, 결제금액, 결제일자)을 출력하시오. (인라인 뷰 이용)

더보기
SELECT ROWNUM "순위", a.*
FROM  (SELECT Product_Code, Product_Name, Order_QTY, Csel, CMoney, CDate
       FROM EC_Order INNER JOIN EC_Product USING (Product_Code)
       WHERE CMoney IS NOT NULL AND CDate IS NOT NULL
       ORDER BY CDate DESC ) a
WHERE  ROWNUM <= 5;

5. 과목임시(T_Course) 테이블에서 추가수강료(Course_fees)의 평균값을 계산하여 출력하고, 추가 수강료가 평균 수강료보다 높은 과목을 출력하시오.

더보기
SELECT AVG(Course_Fees) FROM T_Course;

SELECT *
FROM Course
WHERE Course_Fees >= (SELECT AVG(Course_Fees) FROM Course)
ORDER BY 1;

6. 과목임시(T_Course) 테이블에서 과목코드가 'L1'로 시작하는 과목중에서 추가 수강료가 가장 낮은 금액보다 많은 과목을 추가수강료 역순으로 출력하시오.

더보기
SELECT *
FROM  T_Course
WHERE Course_ID LIKE 'L1%'
AND   Course_fees > ANY (SELECT Course_fees
                       FROM T_Course)
ORDER BY Course_Fees Desc;

7. 수강임시(T_SG_Scores) 테이블에서 성적취득일자가 2018년 6월에 과목코드 별 최고점을 받은 과목의 [과목코드, 학번, 성적, 성적취득일자]를 과목코드 순으로 출력하시오.

더보기
SELECT Course_ID, Student_ID, Score, Score_Assigned
FROM   T_SG_Scores
WHERE (Course_ID, Score) IN (SELECT Course_ID, MAX(Score)
                             FROM T_SG_Scores
                             WHERE TO_CHAR(Score_Assigned, 'YY/MM') = '18/06'
                             GROUP BY Course_ID)
ORDER BY Course_ID;

8. 과목임시(T_Course) 테이블과 수강임시(T_SG_Scores) 테이블을 이용하여 한 명 시아 수강한 과목을 [과목코드, 과목명, 학점수, 담당교수번호, 추가수강료]를 과목코드순으로 출력하시오.

더보기
SELECT *
FROM T_Course C
WHERE EXISTS (SELECT *
              FROM T_SG_Scores SG
              WHERE SG.Course_ID = C. Course_ID);

9. 과목임시(T_Course) 테이블과 수강임시(T_SG_Scores) 테이블을 이용하여 한번도 수강하지 않은 과목을 [과목코드, 과목명, 학점수, 담당교수번호, 추가수강료]를 과목코드순으로 출력하시오.

더보기
SELECT *
FROM   T_Course C
WHERE NOT EXISTS(SELECT *
                 FROM T_SG_Scores SG
                 WHERE SG.Course_ID = C.Course_ID)
ORDER BY 1;

10. 수강(SG_Scores) 테이블을 이용하여 2018학년도에 성적을 취득한 행들을 저장하는 2018학년도 성적(SG_Score_2018) 테이블을 동일한 구조로 생성하고, 저장된 행들을 학번, 과목코드순으로 출력하시오.

더보기
CREATE TABLE SG_Score_2018
AS
   SELECT *
   FROM   SG_Scores
   WHERE  TO_CHAR(Score_Assigned, 'YY') = '18'
     AND  Score IS NOT NULL;

SELECT Student_ID, Course_ID, Score, Grade, Score_Assigned
FROM   SG_Score_2018
ORDER  BY 1, 2;

11. 과목(Course) 테이블에서 추가 수강료가 널인 행을 수강임시(T_Course) 테이블로 복사하시오.

더보기
INSERT INTO T_Course
SELECT *
FROM Course
WHERE Course_Fees IS NULL;

12. 수강(SG_Scores) 테이블과 학생(Student) 테이블을 이용하여 '컴공' 학과의 평균 성적 상위자 3명을 출력하되, 취득과목수가 최소한 3과목 이상인 학생의 (순위, 학과코드 ,학번, 서ㅕㅇ명, 취득과목수, 평균점수)를 출력하시오. 단 평균은 소숫점 2자리까지 반올림하여 출력함.

더보기
SELECT ROWNUM "순위", a.*
FROM (SELECT Dept_ID, student_ID, Name, COUNT(Course_ID), ROUND(AVG(Score),2) "평균"
      FROM SG_Scores INNER JOIN Student USING (Student_ID)
      GROUP BY dept_ID, Student_ID, Name
      HAVING COUNT(Course_ID) > 3
      ORDER BY 5 DESC )a
WHERE ROWNUM <= 3;

13. 수강(SG_Scores) 테이블로부터 과목별 등급 인원수를 피벗 테이블을 이용하여 출력하시오. 등급은 'A','A ','B+','B ','C+','C ',,'D+','D ','F '로 구분함

더보기
SELECT *
FROM (SELECT Title, Grade
      FROM SG_Scores INNER JOIN Course USING (Course_ID) )
PIVOT (
       COUNT(*)
       FOR grade IN ('A+', 'A', 'B+', 'B', 'C+', 'C', 'D+', 'D', 'F ')
       )
ORDER BY 1;

 

*아래 연습문제는 연습문제를 위한 견본데이터베이스가 있어야 실행 가능

 

★연습문제1

1. 주문처리(EC_Order) 테이블과 상품관리(EC_Product) 테이블을 이용하여, 'jupark' 회원이 결제한 [주문자 ID, 상품코드, 상품명, 주문 수량, 주문 금액]을 주문자 ID순으로 출력하시오. (등가조인과 내부조인 방법)

①등가조인

더보기
SELECT ORDER_ID,P.PRODUCT_CODE, PRODUCT_NAME,ORDER_QTY,CMONEY "주문금액"
FROM   EC_Order P, EC_Product S
WHERE  P.PRODUCT_CODE=S.PRODUCT_CODE
  AND  ORDER_ID='jupark'
ORDER  BY 1;

②내부조인(INNER JOIN~USING 또는 INNER JOIN~ON 키워드)

더보기
SELECT ORDER_ID,PRODUCT_CODE, PRODUCT_NAME,ORDER_QTY,CMONEY "주문금액"
FROM   EC_Order INNER JOIN EC_Product USING(PRODUCT_CODE)
WHERE  ORDER_ID='jupark'
ORDER  BY 1;

2. 주문처리(EC_Order) 테이블과 회원관리(EC_Member) 테이블, 상품관리(EC_Product) 테이블을 이용하여 결제한 [회원명, 전화번호, 주소, 배달상품, 배달수량]을 회원명순으로 출력하시오. (등가조인과 내부조인 방법)

①등가조인

더보기
COLUMN 배달상품 FORMAT A14
SELECT NAME, TELEPHONE, ADDRESS, PRODUCT_NAME "배달상품", ORDER_QTY "수량"
FROM   EC_Order P, EC_Member S, EC_Product Y
WHERE  P.ORDER_ID=S.USERID
  AND  P.PRODUCT_CODE=Y.PRODUCT_CODE
  AND  GUBUN ='결제'
ORDER  BY 1;

②내부조인(INNER JOIN~USING 또는 INNER JOIN~ON 키워드)

 

더보기
SELECT NAME, TELEPHONE, ADDRESS, PRODUCT_NAME "배달상품", ORDER_QTY "수량"
FROM   EC_Order P INNER JOIN EC_Member S
                    ON(P.ORDER_ID=S.USERID)
                  INNER JOIN EC_Product Y
                    ON(P.PRODUCT_CODE=Y.PRODUCT_CODE)
WHERE  GUBUN ='결제'
ORDER  BY 1;

3. 상품관리(EC_Product) 테이블과 주문처리(EC_Order) 테이블을 이용하여, 모든 상품을 출력하되 주문 상품의 주문금액(주문 수량 x 단가)을 계산하여 [상품명, 주문 수량, 단가, 주문자 ID, 주문금액]을 주문자ID순으로 2가지 방법에 의하여 출력하시오.

① WHERE절을 이용한 좌 외부조인

더보기
SELECT PRODUCT_NAME "주문상품",ORDER_QTY "수량",
       TO_CHAR(UNIT_PRICE,'L99,999,999') "단가",
       ORDER_ID, 
       TO_CHAR(ORDER_QTY*UNIT_PRICE,'L99,999,999') "주문금액"
FROM   EC_PRODUCT P, EC_ORDER C
WHERE  P.Product_CODE=C.PRODUCT_CODE(+)
ORDER  BY 4;

② LEFT OUTER JOIN 키워드를 이용한 방법

 

더보기
SELECT PRODUCT_NAME "주문상품",ORDER_QTY "수량",
       TO_CHAR(UNIT_PRICE,'L99,999,999') "단가",
       ORDER_ID, 
       TO_CHAR(ORDER_QTY*UNIT_PRICE,'L99,999,999') "주문금액"
FROM   EC_Product LEFT OUTER JOIN EC_Order USING(Product_CODE)
ORDER  BY 4;

4. 상품관리(EC_Product) 테이블과 주문처리(EC_Order) 테이블을 이용하여 한 번도 판매되지 않은 상품의 목록 [상품코드, 상품명, 단가, 재고수량]을 상품코드순으로 출력하시오. (외부조인 응용)

더보기
SELECT PRODUCT_CODE,PRODUCT_NAME,UNIT_PRICE,LEFT_QTY
FROM   EC_Product
WHERE  PRODUCT_CODE NOT IN (SELECT PRODUCT_CODE
                            FROM   EC_Order)
ORDER BY 1;

5. 회원관리(EC_Member) 테이블과 주문처리(EC_Order) 테이블을 참고하여 한 번 도 거래하지 않은 회원의 [회원ID, 회원명, 가입일자]을 출력하시오.

더보기
SELECT USERID, NAME, TIMESTAMP
FROM EC_Member
WHERE  USERID NOT IN (SELECT ORDER_ID
                            FROM   EC_Order)
ORDER BY 1;

★연습문제2

1. 회원(EC_Member) 테이블과 주문처리(EC_Order) 테이블을 이용하여 한번 이상 거래한 회원의 [회원명, 주민등록번호, 상품명, 주문수량, 주문금액]을 회원명순으로 출력하시오. (내부조인)

더보기
SELECT Name, Regist_No, O.Product_Code, Order_Qty, Cmoney
FROM EC_Member M INNER JOIN EC_Order O ON (M.UserID = O.Order_ID) 
ORDER BY 1;

2. 회원관리(EC_Member) 테이블과 주문처리(EC_Order) 테이블을 이용하여 한번도 주문하지 않은 회원의 [회원명, 주민등록번호, 전화번호]를 출력하시오.

더보기
SELECT Name, Regist_No, Telephone
FROM EC_Member M LEFT OUTER JOIN EC_Order O ON (M.UserID = O.Order_ID) 
WHERE O.Order_ID is NULL
ORDER BY 1;

3. 주문처리(EC_Order) 테이블, 회원관리(EC_Member) 테이블, 상품관리(EC_Product) 테이블을 이용하여 거주지가 '서울'인 회원 중에서 한번 이상 주문한 회원의 [회원명, 주민번호, 상품명, 주문수량, 단가, 거주지]를 회원명순으로 출력하시오. (내부 조인)

더보기
SELECT Name, Regist_No, Product_Name, Order_Qty, Unit_Price, SUBSTR(Address, 1,2) "거주지"
FROM EC_Member M INNER JOIN EC_Order O ON (M.UserID=O.Order_ID)
                 INNER JOIN EC_Product P ON (O.Product_Code =
P.Product_Code)
WHERE Address LIKE '서울%'
ORDER BY 1;

4. 수강임시(T_SG_Scores) 테이블, 과목임시(T_Course) 테이블, 학생(Student) 테이블을 이용하여 'C1801' 학번의 수강신청 과목을 출력하시오. (등가조인)

더보기
SELECT Dept_ID, Year, TS.Student_ID, Name, TS. Course_ID, Title, C_Number
FROM   T_SG_Scores TS, Student S, T_Course TC
WHERE  TS.Student_ID = S.Student_ID
  AND  TS.Course_ID = TC. Course_ID
  AND  TS. Student_ID = 'C1801'
ORDER  BY 5;

5. 수강임시(T_SG_Scores) 테이블, 과목임시(T_Course) 테이블, 학생(Student) 테이블을 이용하여 'C1801' 학번의 성적을 내부조인(inner join) 방식으로 출력하시오.

더보기
SELECT Dept_ID, Year, Student_ID, Name, Course_ID, Title, C_Number, Grade
FROM T_SG_Scores INNER JOIN Student USING (Student_ID)
                 INNER JOIN T_Course USING (Course_ID)
WHERE Student_ID = 'C1801'
ORDER BY 5;

6. 수강임시(T_SG_Scores) 테이블과 과목임시(T_Course) 테이블을 이용하여 'C1801' 학번의 등급에 대한 평점, 과목별 평점을 출력하시오. 단, 평점은 등급이 'A+'이면 4.5, 'A '이면 4.0, 'B+'이면 3.5, 'B '이면 3.0, 'C+'이면 2.5, 'C '이면 2.0, 'D+'이면 1.5, 'D '이면 1.0, 'F '이면 0.0이며, 과목별 평점은 "등급에 대한 평점 x 학점수"로 계산한다.

더보기
SELECT Student_ID, Course_ID, Title, C_Number "학점", Grade,
       CASE Grade WHEN 'A+' THEN 4.5 WHEN 'A' THEN 4.0
                  WHEN 'B+' THEN 3.5 WHEN 'B' THEN 3.0
                  WHEN 'C+' THEN 2.5 WHEN 'C' THEN 2.0
                  WHEN 'D+' THEN 1.5 WHEN 'D' THEN 1.0
                            ELSE 0.0 
        END "등급평점",
        CASE Grade WHEN 'A+' THEN 4.5 WHEN 'A' THEN 4.0
                   WHEN 'B+'  THEN 3.5 WHEN 'B' THEN 3.0
                   WHEN 'C+' THEN 2.5 WHEN 'C' THEN 2.0
                   WHEN 'D+' THEN 1.5 WHEN 'D' THEN 1.0 
                            ELSE 0.0
        END * C_Number "과목평점"
FROM    T_SG_Scores INNER JOIN Student USING (Student_ID)
                    INNER JOIN T_Course USING (Course_ID)
WHERE   Student_ID = 'C1802'
ORDER   BY Course_ID;

7. 수강임시(T_SG_Scores) 테이블에서 학번별 취득 과목수, 취득 점수의 합계와 평균을 계산하여, [학과코드, 학년, 학번, 성명, 과목수, 총점, 평균]을 총점 내림차순으로 출력하시오. 단, 평균은 소숫점 반올림하여 둘째자리까지 출력한다.

더보기
SELECT Dept_ID, Year, Student_ID, Name, Count (1) "과목수", SUM(Score) "총점",
       TO_CHAR(ROUND (AVG(Score), 2), '999.99') "평균"
FROM   T_SG_Scores SG INNER JOIN Student S USING (Student_ID)
WHERE  Score IS NOT NULL
GROUP  BY Dept_ID, Year, Student_ID, Name
Order  BY 3 DESC;

8. 학과(Department) 테이블과 교수(Professor) 테이블을 이용하여 직책명(Duty)에 대한 계층적 구조("총장->학과장->교수"순)의 학과별 직위 명단을 출력하시오.

더보기
SELECT Dept_Name "소속", decode (Duty,'총장',''
                            ,'학과장','   L______'
                            , NULL, '           L______') || Duty ||
     '  '|| Name || '  ' || Position "직책 및 성명"
FROM Professor P INNER JOIN Department D ON (P.Dept_ID = D.Dept_ID)
START WITH mgr is NULL
CONNECT BY prior Professor_id = Mgr ;

9. 수강(SG_Scores) 테이블과 과목(Course) 테이블을 이용하여 한 명이상 수강한 과목의 [과목코드, 과목명, 학점수]를 과목코드순으로 출력하시오. (INTERSECT)

더보기
SELECT Course_ID, Title, C_Number
FROM   Course
INTERSECT
SELECT Course_ID, Title, C_Number
FROM   SG_Scores INNER JOIN Course USING (Course_ID)
ORDER BY 1;

10. 수강(SG_Scores) 테이블에서 2018학년도 수강 신청한 학생(학번이 'C18'로 시작)의 과목과 2017학년도 수강 신청한 학생(학번이 'C17'로 시작)의 과목중에서 2016학년도 학생(학번이 'C16'이 시작)이 수강하지 않은 과목을 출력하시오.

더보기
SELECT Course_ID, Title, C_Number
FROM SG_Scores INNER JOIN Course USING (Course_ID)
WHERE Student_ID LIKE 'C18%'
UNION
SELECT Course_ID, Title, C_Number
FROM SG_Scores INNER JOIN Course USING (Course_ID)
WHERE Student_ID LIKE 'C17%'
MINUS
SELECT Course_ID, Title, C_Number
FROM SG_Scores INNER JOIN Course USING (Course_ID)
WHERE Student_ID LIKE 'C16%'
ORDER BY 1;

 

목차
1. props 다시 정리

2. props 기본값 설정 : defaultProps

3. 태그 사이의 내용을 보여주는 children

4. 비구조화 할당 문법을 통한 props 내부 값 추출

5. proTypes를 통한 props 검증

6. state

7. this.setState에 객체 대신 함수 인자 전달-+

8. 함수컴포넌트에서 useState로 state 사용


1. props

앞에서도 말했지만 props는 properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소이다.

 

아래와 같은 구조일 경우 App Component가 부모 컴포넌트이고 MyComponent Component가 자식 컴포넌트이다.

props는 부모 컴포넌트에서 설정할 수 있다.

//App 컴포넌트
import MyComponent from "./MyComponent"; 

const App=()=> {
  return (
    <div>
     <MyComponent name="홍길동" />
    </div>
  );
}

export default App;
//MyComponent 컴포넌트
const MyComponent=(props)=>{

    return <div>안녕하세요, 제 이름은 {props.name}입니다.</div>;

}

export default MyComponent;

위와 같이 부모 컴포넌트에 name 속성을 홍길동이라고 줬더니 자식 컴포넌트에 props.name 자리에 홍길동이 잘 나타나게 된다.

이런식으로 name이든 다른 속성이든 props를 다르게 주면 다른 element(다른 맛 붕어빵)이 만들어진다.


2. props 기본값 설정 : defaultProps

//App 컴포넌트
import MyComponent from "./MyComponent"; 

const App=()=> {
  return (
    <div>
     <MyComponent />
    </div>
  );
}

export default App;

부모컴포넌트에서 속성값을 안주게 되면 아래와 같이 렌더링되는데

이렇게 props값을 안받았을 경우에 default(기본값)으로 어떤 이름이 나오게 설정할 수 있다.

그게 바로 defaultProps이다

//MyComponent 컴포넌트

const MyComponent=(props)=>{

    return <div>안녕하세요, 제 이름은 {props.name}입니다.</div>;

}

MyComponent.defaultProps={
    name: '이름없음'
}

export default MyComponent;


3. 태그 사이의 내용을 보여주는 children

리액트 컴포넌트를 사용할 때 컴포넌트 태그 사이의 내용을 보여주는 props를 children이라고 한다.

//MyComponent 컴포넌트

const MyComponent=(props)=>{

    return <div>안녕하세요, 제 이름은 {props.children}입니다.</div>;

}

export default MyComponent;
//App 컴포넌트
import MyComponent from "./MyComponent"; 

const App=()=> {
  return (
    <div>
     <MyComponent >애기</MyComponent>    
    </div>
  );
}

export default App;


4. 비구조화 할당 문법을 통한 props 내부 값 추출

현재 MyComponent에서 props 값을 조회할 때마다 props.name, props.children과 같이 props라는 키워드를 앞에 붙여 주고 있는데 이러한 작업을 편하게 하기위해 비구조화 할당 문법을 사용할 수 있다.

 

▶구조 분해 할당

배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식이다.

 

그 중에서 객체 구조 분해할당의 형태는 다음과 같다

var o = {p: 42, q: true};
var {p, q} = o;

위와 같이 선언해줌으로써 p와 q를 개별변수로 사용할 수 있게 된다.

p만 호출해도 42라는 값을 가져올 수 있다.

 

리액트에서도 마찬가지이다.

const{name, children}=props라고 해줌으로써

props.name, props.children이라고 명시를 하지 않고 그냥 name, children이라고만 해줘도 해당 값에 접근이 가능해진 것이다.

//MyComponent 컴포넌트

const MyComponent=(props)=>{
    const{name, children}=props;
    return <div>안녕하세요, 제 이름은 {name}이자 {children}입니다.</div>;

}

export default MyComponent;

또는

//MyComponent 컴포넌트

const MyComponent=({name, children})=>{
    return <div>안녕하세요, 제 이름은 {name}이자 {children}입니다.</div>;

}

export default MyComponent;
//App 컴포넌트
import MyComponent from "./MyComponent"; 

const App=()=> {
  return (
    <div>
     <MyComponent name="길동">애기</MyComponent>    
    </div>
  );
}

export default App;

5. proTypes를 통한 props 검증

컴포넌트의 필수 props를 지정하거나 props의 타입(type)을 지정할 때는 proTypes를 사용한다.

proTypes를 사용하려면 코드 상단에 import 구문을 사용하여 불러와야 한다.

import ProTypes from 'prop-types';

 

아래와 같이 name 속성을 proTypes로 string으로 지정해놓으면 문자열이 아닌 다른 자료형일 경우 Console창에 에러메시지가 뜬다.

//MyComponent 컴포넌트
import ProTypes from 'prop-types';

const MyComponent=(props)=>{
    const{name, children}=props;
    return <div>안녕하세요, 제 이름은 {name}이자 {children}입니다.</div>;

}

MyComponent.proTypes={
    name:ProTypes.string
}

export default MyComponent;

 

▶isRequired를 사용하여 필수 proTypes 설정

필수로 입력돼야 하는 proType에 isRequired를 붙여준다.

//MyComponent 컴포넌트
import ProTypes from 'prop-types';

const MyComponent=(props)=>{
    const{name, children}=props;
    return <div>안녕하세요, 제 이름은 {name}이자 {children}입니다.</div>;

}

MyComponent.proTypes={
    name:ProTypes.string.isrequired
}

export default MyComponent;

 

▶클래스형 컴포넌트에서 props 사용

클래스형 컴포넌트에서 props를 사용할 때 render 함수에서 this.props를 조회하면 되며 defaultProps와 propTypes는 똑같은 방식으로 설정가능하다.

//MyComponent 컴포넌트
import {Component} from 'react';
import ProTypes from 'prop-types';

class MyComponent extends Component{
    render(){
    const {name, children}=this.props;

     return(<div>안녕하세요, 제 이름은 {name}이자 {children}입니다.</div>)};

}

MyComponent.proTypes={
    name:ProTypes.string.isrequired
}

export default MyComponent;

6. state

state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다.

props는 부모 컴포넌트가 설정하는 값이며 컴포넌트 자신을 해당 props를 읽기 전용으로만 사용할 수 있고 props를 변경하려면 부모 컴포넌트에서 바꿔줘야하지만 state는 내부에서 바뀌게 만들 수 있는 것이다.

 

바뀔수 있는 state 초기값을 설정해주는 형태는 아래와 같다.

컴포넌트의 state는 객체 형식이어야 한다.

 

초기값을 설정해주는 방법은 constructor에 설정해주거나 constructor을 사용하지 않고 바로 state를 설정해주는 방법 2가지가 있다.

 this.state = {
      number: 0,
    };

 

클래스형 컴포넌트에서 constructor를 작성할 때는 반드시 super(props)를 호출해 주어야 하며 

이 함수가 호출되면 현재 클래스형 컴포넌트가 상속받고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해준다.

 

아래에 나오는 onClick이라는 이벤트는 클릭하면 onClick 다음에 오는 함수를 실행하라는 의미이며 이 함수를 넣어줄 때는 화살표 함수 문법을 사용하여 넣어줘야 한다.

 

함수 내부에서 this.setState라는 함수를 사용하는데 이 함수가 state 값을 바꿀 수 있게 해 준다.

 

//생성자에서 state 초기값 설정

import { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      number: 0,
    };
  }
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
          onClick={() => {
            this.setState({ number: number + 1 });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

 

//생성자 없이 state 초기값 설정

import { Component } from 'react';

class Counter extends Component {
    state = {
      number: 0,
    };
  
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
          onClick={() => {
            this.setState({ number: number + 1 });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

state값에는 여러 값이 올 수 있다.

    state = {
      number: 0,
      fixNumber:0
    };

7. this.setState에 객체 대신 함수 인자 전달

아래 예제코드를 보면 onClick을 했을 대 setState가 2번 호출되도록 만들었다. 즉 +2씩 증가되도록 만들려고 한 것이다.

import { Component } from 'react';

class Counter extends Component {
    state = {
      number: 0,
    };
  
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
          onClick={() => {
            this.setState({ number: number + 1 });
            this.setState({ number: this.state.number + 1 });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

그런데 실제 결과는 +1씩 증가되었다.

위와 같이 작성하면 this.setState를 2번 사용하는 것임에도 불구하고 1씩 더해지는데 this.setState를 사용한다고 해서 stae 값이 바로 바뀌는 것이 아니기 때문이다.

이런 문제점을 해결하기 위해서는 this.setState를 사용할 때 객체 대신 함수를 인자로 넣어주면 된다.

위 코드를 아래코드처럼 바꿔주면 된다.

import { Component } from 'react';

class Counter extends Component {
    state = {
      number: 0,
    };
  
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
          onClick={() => {
            this.setState({ number: number + 1 });
            this.setState(prevState=>{return {number:prevState.number+1}});
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

함수형태로 표현하는 방식은 2개가 있다.

prevState는 기존 상태를 의미하며 기존 상태의 number에 1을 더해주는 것이다.

 

이렇게 함수를 사용하면 즉시 반영이 돼서 위에 있는 코드는 +2씩 잘 증가되는 것을 볼 수 있다.

//1번째 방식
this.setState(prevState=>{return {number:prevState.number+1}}

//2번째 방식
this.setState(prevState=>({number:prevState.number+1}));

2번째 방식은 return을 쓰지 않고 바로 객체를 반환하는 것인데 이 방식을 쓰기 위해서는

function A(){}이런 형태일때 A()뒤에 나오는 중괄호(코드블럭)을 생략하고 써주며

객체를 반환하는 형태이므로 ( { } ) 객체를 나타내는 중괄호를 괄호로 감싸는 형태가 된다.

 

setState 작업이 끝난 후 또 다른 작업을 하고싶을 대는 setState의 두 번째 파라미터로 콜백함수를 등록하면 된다.

import { Component } from 'react';

class Counter extends Component {
    state = {
      number: 0,
    };
  
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
          onClick={() => {
            this.setState({ number: number + 1 },()=>{console.log("안녕")});
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

export default Counter;


8. 함수컴포넌트에서 useState로 state 사용

과거에는 함수컴포넌트에서 state를 사용할 수 없었지만 지금은 useState라는 함수를 사용해 함수 컴포넌트에서도 state를 사용할 수 있다.

 

userState를 알아보기 전에 배열 비구조화 할당에 대해 먼저 알아본다.

 

▶배열 비구조화 할당

구조 분해 할당은 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식이다.

아래와 같이 red, yellow, green이라는 개별 변수로 배열 값을 접근할 수 있는 것이다.

▶useState사용

아래의 형태는 state 초기값을 ''으로 넣어준 것이다.

배열 첫번째 원소인 message는 현재 상태를 나타내고

배열 두번째 원소인 setMessage는 상태를 바꿔주는 함수를 나타내며 세터함수라고 부른다.

    const [message,setMessage]=useState('');
import {useState} from 'react';

const Say=()=>{
    const [message,setMessage]=useState(''); //state값을 ''으로 초기화
    const onClickEnter=()=>setMessage('안녕하세요!'); //state 값을 안녕하세요로 변경
    const onClickLeave=()=>setMessage('안녕히 가세요!');
    return (<div>
        <button onClick={onClickEnter}>입장</button> {/*클릭하면 onClickEnter함수 호출*/}
        <button onClick={onClickLeave}>퇴장</button>
        <h1>{message}</h1>
    </div>);
}

export default Say;

▶useState여러번 사용

 

useState는 한 컴포넌트에 여러번 사용해도 상관없다.

다만 style을 usestate로 지정할 때는 배열의 첫번째 원소인 현재 상태를 CSS에 사용되는 키워드로 사용해야 하며 원래 CSS에서 font-size였던 것이 리액트 에서는 fontSize라고 표현해줘야한다. (카멜 표기+ -기호 제거)

import {useState} from 'react';

const Say=()=>{
    const [message,setMessage]=useState('');
    const onClickEnter=()=>setMessage('안녕하세요!');
    const onClickLeave=()=>setMessage('안녕히 가세요!');

    const [color,setColor]=useState('black');
    const [fontSize,setfontsize]=useState('');
    return (<div>
        <button onClick={onClickEnter}>입장</button>
        <button onClick={onClickLeave}>퇴장</button>
        <h1 style={{color,fontSize}}>{message}</h1>
        <button style={{color:'red'}} onClick={()=>setColor('red')}>빨간색</button>
        <button style={{color:'green'}} onClick={()=>setColor('green')}>초록색</button>
        <button style={{color:'blue'}} onClick={()=>setColor('blue')}>파란색</button>
        
        <button onClick={()=>setfontsize('50px')}>폰트증가</button>
        <button onClick={()=>setfontsize('20px')}>폰트감소</button>

    </div>);
}

export default Say;

 

props를 사용한다고 해서 값이 무조건 고정적이지는 않다. 부모 컴포넌트의 staste를 자식 컴포넌트의 props로 전달하고, 자식 컴포넌트에서 특정 이벤트가 발생할 때 부모 컴포넌트의 메서드를 호출하며 props도 유동적으로 사용할 수 있다.


출처

리액트를 다루는 기술- 김민준

 

목차

1. 화면을 그린 후 지우고 다시 출력하면 깜빡이는 문제점

2. 게임 프로그래밍에서의 버퍼 개념

3. 페이지 전환을 통해 깜빡이는 문제 해결하기


1. 화면을 그린 후 지우고 다시 출력하면 깜빡이는 문제점

C언어게임은 콘솔창이므로 콘솔창에서는 고속으로 화면을 지우고 그리게 하는 부분이 없어 지우고 다시 그리는 과정에서 깜빡임이 발생하게 된다.

 

아래 구조는 간단하게 구조체를 하나 만들고 방향키로 캐릭터가 움직이도록 구현하였다.

#include <stdio.h>
#include<Windows.h>
void gotoxy(int x, int y)   //gotoxy api함수

{
	COORD pos = { x,y };
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

typedef struct _PLAYER
{
	int x, y; 
}PLAYER;

PLAYER player;

void init() {
	player.x = 20;
	player.y = 10;
}
void update() {
}
void render()
{
	system("cls");
	gotoxy(player.x, player.y);
	printf("♀");
}

void release() {
}

int main(void) {
	int nKey;
    
	init();

	while (1) {
		if (_kbhit()) { //키보드가 눌렸는지 체크 
			nKey = _getch(); //눌린값 대입
			if (nKey == 'q') //q를 눌렀다면 break
				break;
			else if (nKey == 224 || nKey == 0) {
				nKey = _getch();
			switch (nKey) {
			case 75: //왼쪽 방향키를 눌렀다면 
				player.x--; 
				break;
			case 77:  //오른쪽 방향키를 눌렀다면
				player.x++; 
				break;
			
			case 72:  //위쪽 방향키를 눌렀다면
				player.y--; 
				break;
			
			case 80:  //아래쪽 방향키를 눌렀다면
				player.y++; 
				break;
		}
			}
		}
		update();
		render();
	}
	release();
	return 0;
}

이동하기 전 위치의 문자를 보이지 않게 하기 위해 system("cls")로 지우고 다시 새로운 위치에 문자를 출력시키기 때문에

어쩔수없이 화면이 지워졌다가 다시 그려짐으로 인해서 화면이 깜빡이게 된다.

 

그렇다고 system("cls")를 해주지 않으면 다음과 같이 잔상이 남게 된다

 

 

이런 화면깜빡임은 보는 사람에게 너무 피로감을 느끼게 한다.  이런 문제를 해결하는 방법을 알아보자.


2. 게임 프로그래밍에서의 버퍼 개념

먼저 해결하는 방법을 알기 위해서는 게임 프로그래밍에서 쓰는 버퍼 개념을 알아야한다.

 

1) 전위 버퍼(primary buffer)

전위 버퍼를 전위면이라고도 하는데 화면과 일대일 대응되는 메모리르 ㄹ말하며 그래픽 카드의 메인 메모리의 일부분이다.

현재 모니터의 해상도를 변경하면 전위 버퍼에 해당되는 메모리도 변경된다.

 

2) 후위 버퍼(back buffer)

전위 버퍼와 동일한 특성을 가진 메모리를 말한다.

전위 버퍼는 모니터와 일대일 대응되므로 컴퓨터와 동작함과 동시에 그래픽 카드에 생성이 되지만 후위 법퍼는 따로 생성이 된다.

 

후위 버퍼는 전위 버퍼와 특성이 같으므로 전위 버퍼와 연결하여 사용하며 주로 시스템 메모리 보다는 그래픽 카드 메모리에 생성하여 빠른 화면 전환을 하기 위해 사용된다.

 

3) 이중 버퍼링(double buffering)

이중 버퍼링은 두 개의 버퍼를 이용하여 화면을 전환하는 방법을 말한다.

사용되는 두 개의 버퍼는 전위 버퍼와 후위 버퍼를 말하며 후위 버퍼의 내용을 전위 버퍼에 복사하여 출력하는 것을 말한다.

 

4) 페이지 전환(Page flipping)

이중 버퍼링에도 문제가 있어 오늘날 모든 게임에서 사용되는 방식이 바로 페이지 전환 방식이다.

실제로 전위 버퍼와 후위 버퍼간의 메모리 복사가 아닌 화면과 일대일 대응하는 메모리의 시작주소를 바꾸는 방식이다.

 

즉, 전위 버퍼를 쓰고 있다가 메모리의 시작 주소를 후위 버퍼로 바꿔서 후위 버퍼를 보여줬다가 다시 시작 주소를 바꿔서 전위 버퍼를 보여줬다가 번갈아가며 출력하게 하는 것이다.


3. 페이지 전환을 통해 깜빡이는 문제 해결하기

위에 봤던 간단한 예제를 버퍼 예제로 바꿔보자.

 

일단 기본 구조는 다음과 같다.

잘 모르겠다면 아래 링크를 잠깐 갔다 오자.

C언어로 게임만들기 1탄 - 게임의 기본구조 :: 잡코딩 정보 블로그 (tistory.com)

 

일단 코드를 복붙하고 따라해보자.

총 3개의 파일이 필요하다

1) main.c

#include <stdio.h>
#include<Windows.h>
#include "Screen.h"

typedef struct _PLAYER
{
	int x, y; //출력기준좌표
}PLAYER;

PLAYER player;

void init() {
	player.x = 20;
	player.y = 10;
}
void update() {
}
void render()
{
	   ScreenClear(); //대기하고 있는 화면 버퍼를 지운다.
	  ScreenPrint(player.x, player.y, "♀"); //(player.x, player.y) 좌표에 문자를 출력한다.
		ScreenFlipping(); //활성화된 화면 버퍼와 비활성화된 화면 버퍼의 상태를 바꾼다
}

void release() {
}

int main(void) {
	int nKey, nRemain;

	ScreenInit();//버퍼를 2개 생성한다.
	init();

	while (1) {
		if (_kbhit()) { //키보드가 눌렸는지 체크 
			nKey = _getch(); //눌린값 대입
			if (nKey == 'q') //q를 눌렀다면 break
				break;
			else if (nKey == 224 || nKey == 0) {
				nKey = _getch();
			switch (nKey) {
			case 75: //왼쪽 방향키를 눌렀다면 
				player.x--; 
				break;
			case 77:  //오른쪽 방향키를 눌렀다면
				player.x++; 
				break;
			
			case 72:  //위쪽 방향키를 눌렀다면
				player.y--; 
				break;
			
			case 80:  //아래쪽 방향키를 눌렀다면
				player.y++; 
				break;
		}
			}
		}
		update();
		render();
	}


	release();
	ScreenRelease(); //화면 버퍼 초기화 함수에서 생성한 두 개의 화면 버퍼를 모두 해제한다.
	return 0;
}

 

2) Screen.c (작명은 아무렇게나 해도 상관없다)

#include <stdio.h>
#include<Windows.h>

static int g_nScreenIndex;
static HANDLE g_hScreen[2];

void ScreenInit()
{
    CONSOLE_CURSOR_INFO cci;

    //화면 버퍼 2개를 만든다.
    g_hScreen[0] = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
        0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    g_hScreen[1] = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
        0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);

    //커서 숨기기
    cci.dwSize = 1;
    cci.bVisible = FALSE;
    SetConsoleCursorInfo(g_hScreen[0], &cci);
    SetConsoleCursorInfo(g_hScreen[1], &cci);
}

void ScreenFlipping()
{
    SetConsoleActiveScreenBuffer(g_hScreen[g_nScreenIndex]);
    g_nScreenIndex = !g_nScreenIndex;
}

void ScreenClear()
{
    COORD Coor = { 0,0 };
    DWORD dw;
    FillConsoleOutputCharacter(g_hScreen[g_nScreenIndex], ' ', 80 * 25, Coor, &dw);
}

void ScreenRelease()
{
    CloseHandle(g_hScreen[0]);
    CloseHandle(g_hScreen[1]);
}

void ScreenPrint(int x, int y, char* string)
{
    DWORD dw;
    COORD CursorPosition = { x, y };
    SetConsoleCursorPosition(g_hScreen[g_nScreenIndex], CursorPosition);
    WriteFile(g_hScreen[g_nScreenIndex], string, strlen(string), &dw, NULL);

}

 

3) Screen.h (작명은 아무렇게나 해도 된다)

void ScreenInit();
void ScreenFlipping();
void ScreenClear();
void ScreenRelease();
void ScreenPrint(int x, int y, char* string);
void SetColor(unsigned short color);

 

위에 깜빡이는 예제와 거의 똑같은데 다른 것은 윈도우 API함수가 들어간 것이다.

파일이 준비돼었으니 차근차근 보도록하자.

 

Screen.c 코드는 이해할필요없다. 그냥 가져다 쓰면 된다.

 

<1> ScreenInit()로 전위 버퍼와 백 버퍼로 사용할 화면 버퍼를 두 개 생성한다.

 

<2> ScreenClear()로 하나의 화면 버퍼가 활성화되어 출력되고 있는 동안에 다음 장면을 위한 화면 버퍼는 지운다.

 

 

<3>  ScreenPrint()로 대기 화면 버퍼의 x, y 좌표에 문자열을 출력해준다.

전위버퍼/후위버퍼

 

<4> ScreenFlipping()로 활성화된 화면 버퍼와 비활성화된 화면 버퍼의 상태를 바꾼다.

전위버퍼/후위버퍼

 

아주 빠른 속도로 일어나서 그냥 이동하는 것 처럼 보이지만 이런식으로 빠르게 바꿔치기 돼서 화면에 보이게 된다.

이렇게 코드를 짜면 아래와 같이 깜빡이지 않는 편안함을 느낄 수 있다


참고문헌

C를 이용한 게임프로그래밍-이태성

 

 

 

목차

1. 게임의 기본구조


1. 게임의 기본구조

게임의 기본 구조는 크게 초기화, 데이터 갱신, 화면 출력, 해제로 나뉜다.

모든 게임이 이 구조로 돼있지는 않지만 대부분의 게임 구조가 이 구조로 되어있다.

사진 출저 : 아래 참조

1) 초기화

실제로 게임이 실행되기 이전에 게임에 필요한 기본 데이터를 읽고 각종 변수를 초기화한다.

초기화의 내용에는 캐릭터 초기화, 사운드 초기화, 패턴 도는 AI 초기화, 메모리 할당 등이 있다.

 

2) 데이터 갱신

말그대로 데이터가 갱신되는 것이다.

입력장치(주로 키보드나 마우스)에 의해 데이터가 갱신되거나

충돌등의 다양한 방식으로 데이터가 스스로 갱신된다.

 

3) 화면 출력

말그대로 출력하는 것이다.

 

4) 해제

동적으로 메모리를  해제하는 경우가 대부분이지만 초기화에서 생성한 객체를 해제하는 역할도 한다.

객체는 사운드 엔진, 물리 엔진, 그래픽 엔진등을 말한다.

 

 

다음은 게임 기본 구조에 사용할 함수들이며 주로 게임 엔진에 사용되는 함수명이다.

 

사진 출저 : 아래 참조

게임 프로그래밍을 하기 전에 이와 같은 구조를 만드는 것은 분업을 해야하기 때문이다.

사진 출처 : 아래참조

기본구조를 코드로 구현하면 다음과 같다.

 

4개의 함수가 각각 한번씩 실행되고 종료된다. 

#include <stdio.h>

void init() {

}

void update() {

}

void render() {

}

void release() {

}

int main(void) {
	init(); 
	update();
	render();
	release();
	return 0;
}

 

하지만 게임에서 데이터 갱신과 화면 출력은 계속돼야하므로 무한 반복하는 형태로 바꿔준다.

#include <stdio.h>

void init() {

}

void update() {

}

void render() {

}

void release() {

}

int main(void) {
	init();  //초기화
    
	while(1){
	update(); //데이터 갱신
	render(); //화면출력
	}
    
	release(); //해제
	return 0;
}

출처

1. C를 이용한 게임프로그래밍-이태성

2. 사진출처 :  3장. 게임의 기본 구조 (1/2) - C 게임 프로그래밍 - 나우캠퍼스 (daum.net)

 

+ Recent posts