본문 바로가기

Studying/정보처리기사

[정보처리기사 실기]_2024년_프로그래밍

[1회]

 

1. 다음은 Java 코드에서 알맞는 출력 값을 작성하시오.

class Connection {
	private static Connection _inst = null;
	private int count = 0;
	static public Connection get() {
		if(_inst == null) {
			_inst = new Connection();
			return _inst;
		}
		return _inst;
	}
	public void count() {
		count++;
	}
	public int getCount() {
		return count;
	}
}
public class Gisafist {
	public static void main(String[] args) {
		Connection conn1 = Connection.get();
		conn1.count();
		Connection conn2 = Connection.get();
		conn2.count();
		Connection conn3 = Connection.get();
		conn3.count();
		conn1.count();
		System.out.println(conn1.getCount());
	}
}

 


 

2. 다음 C언어 코드에서 알맞는 출력 값을 작성하시오.

#include<stdio.h>

int main() {
	int v1 = 0, v2 = 35, v3 = 29;

	if (v1 > v2 ? v2 : v1) {
		v2 = v2 << 2;
	}
	else {
		v3 = v3 << 2;
	}
	printf("%d", v2 + v3);
}

 

1) int v1 = 0, v2 = 35, v3 = 29;

 - 정수형 변수 v1, v2, v3 선언하면서 각각 0, 35, 29로 초기화.

 

2) if문

 - v1 > v2는 0 > 35 거짓이므로 else문 실행.

 - v3 = v3 << 2는 29 * 2^2이므로 29 * 4 = 116.

 

3) v2 + v3

 - v2 = 35, v3 = 116이몰 35 + 116 = 151을 출력.

 

▶ 오른쪽 시프트 연산자는 오른쪽으로 0을 추가하고, 왼쪽 시프트 연산자는 맨 오른쪽의 숫자부터 지운다고 생각.

 

[출력]

151

 

4. 다음은 C언어에 대한 문제이다. 알맞는 출력값을 작성하시오.

#include<stdio.h>
#include<string.h>

int main() {
	char str[] = "ABCDEFGH";
	char* fir_str;
	char* end_str;
	fir_str = &str[0];
	end_str = &str[strlen(str) - 1];
	while (fir_str < end_str) {
		char t = *fir_str;
		*fir_str = *end_str;
		*end_str = t;
		fir_str++;
		end_str--;
	}
	for (int i = 1; i < strlen(str); i += 2) {
		printf("%c", str[i]);
	}
}

 

1) char str[] = "ABCDEFGH";

 - 문자형 배열 변수 str 선언하면서 초기화.

 - str은 100번지로 가정.

str
(100)


0 1 2 3 4 5 6 7
A B C D E F G H
100 101 102 103 104 105 106 107

 

2) char* fir_str;, char* end_str;

 - 문자형 포인터 변수 fir_str, end_str 선언.

 

3) fir_str = &str[0];

 - fir_str은 str[0]의 주소값을 저장하므로 100번지를 가짐.

 

4) end_str = &str[strlen(str)-1];

 - strlen(str)은 str의 길이를 의미하므로 str의 길이는 8이고, -1하면 7을 의미.

 - 따라서 end_str은 str[7]의 주소값을 저장하므로 107번지를 가짐.

 

5) while문

 ① 첫 번째 반복문.

   - 조건보면 fir_str < end_str인데 현재 fir_str은 100번지, end_str은 107번지를 가리키므로 조건은 참.

   - char t = *fir_str은 문자형 변수 t에 fir_str의 값을 저장하므로 fir_str은 100번지를 가리키고 그 값인 'A'를 저장.

   - *fir_str = *end_str은 fir_str에 end_str의 값으로 변경하므로 end_str은 107번지고 그 값인 'H'를 저장.

   - *end_str = t는 end_str의 값을 t의 값으로 바꾸므로 t의 값인 'A'를 저장.

   - 따라서 100번지에는 'H'를, 107번지에는 'A'를 저장.

   - fir_str++은 현재 100번지에서 ++연산하여 101번지.

   - end_str--는 현재 107번지에서 --연산하면 106번지.

 ② 두 번째 반복문.

   - 조건보면 fir_str < end_str은 101 < 106번지이므로 조건은 참.

   - char t = *fir_str은 현재 fir_str이 101번지이고, 그 값인 'G'를 t에 저장.

   - *fir_str = *end_str은 end_str이 현재 106번지고, 그 값인 'B'를 fir_str에 저장.

   - *end_str = t는 t의 값인 'G'를 106번지의 값에다가 저장.

   - 따라서 101번지에는 'B'를, 106번지에는 'G'를 저장.

 

 이런식으로 진행하다보면 fir_str이 104번지, end_str이 103번지가 될 때 종료함. 최종적으로 str의 바뀐 배열은

str
(100)
0 1 2 3 4 5 6 7
H G F E D C B A
100 101 102 103 104 105 106 107

 

6) for문

 - i는 1부터 시작.

 - 범위는 strlen(str)인데 str의 길이는 8이므로 i < 8까지 반복.

 - i는 2씩 증가.

 - 따라서 i = 1, i = 3, i = 5, i = 7 일 때의 값을 출력하므로 GECA

 

[출력]

GECA

 

10. 아래 Java언어 코드의 실행순서를 중복 번호 없이 작성하시오.

class Parent {
    int x, y;
 
    Parent(int x, int y) { ①
        this.x=x;
        this y=y;
    }
 
    int getT() { ②
        return x*y;
    }
}
 
class Child extend Parent {
    int x;
 
    Child (int x) { ③
        super(x+1, x);
        this.x=x;
    }
 
    int getT(int n){ ④
        return super.getT()+n;
    }
}
 
class Main {
    public static void main(String[] args) { ⑤
        Parent parent = new Child(3); ⑥
        System.out.println(parent.getT()); ⑦
    }
}

 

: (5) → 6 3 1 7 2

 

⑤ : 먼저 main 함수 실행.

⑥ : main 함수에서 클래서 Child의 객체 parent 생성. Child(3)에서 매개변수 3을 던짐.

③ : Child 함수에서 매개변수 받는 Child의 생성자 실행.

     - super(x+1, x)에서 super는 부모클래스 생성자를 호출하는 것으로 매개변수 2개 던지는 Parent의 생성자를 실행.

① : 클래스 Parent의 Parent 생성자 실행.

⑦ : 모든 함수 끝나고 main 메서드의 출력함수 실행.

      - 출력함수에서 getT() 호출.

② : 클래스 Parent의 getT 메서드 실행. 

 

▶ Parent(int x, int y)는 생성자.

▶ getT()는 메서드.

▶ Child(int x)는 생성자.

▶ getT()는 메서드.

 

생성자는 클래스의 이름과 같은 것을 의미. 


 

11. 다음 C언어의 알맞는 출력값을 작성하시오. (추후 수정)

#include<stdio.h>

struct myACC {
	int accNum;
	double bal;
};

double sim_pov( double base, int year ){
	double r = 1.0;
	for (int i = 0; i < year; i++) {
		r = r * (1.0 + base);
	}
}
void intAcc(struct myACC* acc, int x, double y) {
	acc->accNum = x;
	acc->bal = y;
}
void test01(struct myACC* acc, double en) {
	if (en > 0 && en < acc->bal) {
		acc->bal -= en;
	}
	else {
		acc->bal += en;
	}
}
void test02(struct myACC* acc) {
	acc->bal = acc->bal * sim_pov(0.1, 3);
}
int main() {
	struct myACC myAcc;
	intAcc(&myAcc, 9981, 2200.0);
	test01(&myAcc, 100.0);
	test02(&myAcc);
	printf("%d and %0.2f", myAcc.accNum, myAcc.bal);
	return 0;
}

 


 

12. 다음 파이썬 코드에 대한 알맞는 출력 값을 작성하시오.

a = ["Seoul", "Kyeonggi", "Incheon", "Daejun", "Daegu", "Pusan"]
str = "S"

for i in a:
    str = str + i[1]

print(str)

 

1) a = ["Seoul", "Kyeonggi", "Incheon", "Daejun", "Daegu", "Pusan"]

 - a 리스트에는 6개의 도시 이름이 포함.

 

2) str = "S"

 - 초기 str의 값은 S로 설정.

 

3) for문

 - 리스트 a의 각 도시 이름에서 두번째 문자(i[1])을 추출하여 str에 추가.

 - Seoul의 e

 - Kyeoni의 y

 - Incheon이 n

 - Daejun의 a

 - Daegudml a

 - Pusan의 u

 

[출력]

Seynaau

 

17. 다음 Java 코드를 보고 알맞는 출력값을 작성하시오.

class classOne {
	int a, b;
	public classOne(int a, int b) {
		this.a = a;
		this.b = b;
	}
	public int getP() {
		return a + b;
	}
}

class classTwo extends classOne {
	int po = 3;
	public classTwo(int i) {
		super(i, i+1);
	}
	public int getP() {
		return po * po;
	}
}

public class Gisafist {
	public static void main(String[] args) {
		classOne a = new classTwo(10);
		System.out.println(a.getP());
	}
}

 

▶ 오버라이딩

   - 하위(자식) 클래스에서 상위(부모) 클래스의 메소드를 재정의하는 과정.

   - 하위클래스의 오버라이딩 메서드는 상위클래스 메서드보다 우선순위 높음.

 

1) main 함수

 ① classOne a = new classTwo(10);

   - 클래스 classTwo의 객체 a 생성. 객체를 생성하면 생성자가 반드시 실행.

   - 전달하는 값은 10이므로 클래스 classTwo의 생성자로 이동.

 

2) classTwo함수

 ① classTwo(int i) 생성자 실행.

   - 매개변수 10을 전달 받으면 int i = 10.

   - super(i, i+1)을 실행하면 super(10, 11). super는 상위클래스를 호출하는 예약어이므로 클래스 classOne으로 이동.

 

3) classOne 함수

 ① classOne(int a, int b) 생성자 실행.

   - 매개변수 10, 11을 전달 받으면 int a = 10, int b = 11.

 ② this.a = a; this.b = b;

   - this는 객체 자기 자신을 의미.

   - this.a에서의 a는 객체 변수 a (int a로 선언된 맨 첫 줄의 a)를 의미.

   - 이곳에 a 값(= a는 this.a = a에서 오른쪽 a)을 넣음.

   - 이 a 값을 단독으로 사용하면 변수사용의 우선순위에 따라서 자기 자신의 블록내에 있는 매개변수로 받은 int a가 우선순위가 높음.

   - 즉 매개변수로 받은 int a의 값 10을 객체 변수 a에 대입.

   - 부모 생성자를 다 실행했으면 호출 받은 곳으로 돌아감(자식 클래스의 생성자)

 

   -자식 클래스의 생성자도 다 실행하였으므로 main 함수로 돌아감.

 

4) main 함수

 ① a.getP()

   - 객체 a의 getP() 메서드를 호출하여 반환값을 출력.

   - getP() 메서는 부모, 자식 둘 다 가지고 있음.

   - 하지만 오버라이딩 메서드이므로 우선순위가 높은 자식 클래스의 메서드를 실행.

 

5) classTwo 함수

 ① getP() 메서드 실행

   - return po * po에서 po는 classTwo에서 3이므로 3 * 3 = 9를 반환하여 출력.

 

[출력]

9

 

20. 다음 C언어 코드의 알맞는 출력값을 작성하시오.

#include<stdio.h>
#include<string.h>

void isUpper(char* str);
void isLower(char* str);
void isNum(char* str);
char str[] = "It is 8";
int main() {
	int i = 0;
	while (i < strlen(str)) {
		char ch = str[i];
		if (ch >= 'A' && ch <= 'Z') {
			isUpper(&str[i]);
		}
		else if (ch >= 'a' && ch <= 'z') {
			isLower(&str[i]);
		}
		else if(ch >= '0' && ch <= '9') {
			isNum(&str[i]);
		}
		i++;
	}
	printf("%s", str);
}

void isUpper(char* str) {
	*str = (*str - 'A' + 5) % 26 + 'A';
}
void isLower(char* str) {
	*str = (*str - 'a' + 10) % 26 + 'a';
}
void isNum(char* str) {
	*str = (*str - '0' + 3) % 10 + '0';
}

 

▶ 시저 암호 알고리즘(= 카이사르 암호 알고리즘) : 문자를 일정한 거리만큼 밀어서 평문을 암호화하는 알고리즘.

아스키코드

 

1) 함수

 ① isUpper() : 대문자

 ② isLower() : 소문자

 ③ isNum() : 숫자

 

2) 전역변수

 - char str[] = "It is 8"

str
(100)
0 1 2 3 4 5 6 7
I t   i s   8 \0

 

3) main 함수

 - int i  = 0;

     - 정수형 변수 i 선언하면서 0으로 초기화.

 - char ch = str[i];

     - 문자형 변수 ch 선언하면서 str[i]로 초기화.

 ① i = 0 일 때

     - while문 조건 보면 i < strlen(str)에서 strlen(str)은 str의 길이 7을 의미하므로 0 < 7은 참이기 때문에 내부 실행.

     - char ch = str[i]는 str[0]을 ch에 대입하므로 char ch = 'I'를 저장.

     - if문 조건보면 ch >= 'A' && ch <= 'Z'에서 ch는 현재 'I'를 저장하고, 'I'는 아스키코드에서 73, 'A'는 65, 'Z'는 90이므로 조건 참.

     - isUpper() 함수 실행.

     ㄱ. isUpper(char *str)

          - 매개변수 전달할 때 &str[0]은 100번지를 의미하므로 100번지를 전달받아 str에 저장.

          - *str = (*str - 'A' + 5) % 26 + 'A'에서 *str은100번지의 값인 'I'(73), 'A'는 65.

          - 계산하면 (73 - 65 + 5) % 26 + 65 = 13 % 26 + 65 = 13 + 65 = 78의 값이 나오고, 78은 아스키코드에서 'N'을 의미.

          - 따라서 *str에 'N'을 저장하므로 100번지에는 'N'을 저장.

 ② i = 1 일 때

     - 함수 다 실행하고 호출한 곳으로 넘어와 if문 종료하면 i++ 실행하여 i = 1로 증가.

     - while문 조건 보면 i < 7 = 1 < 7은 참이므로 내부 실행.

     - char ch = str[i]는 str[1]을 ch에 대입하므로 char ch = 't'를 저장.

     - if문 조건 보면 대문자 일 때 조건이므로 else if인 다음 구문 실행.

     - else if문 조건 보면 ch >= 'a' && ch <= 'z'에서 ch는 현재 't'를 저장하고, 't'는 아스키코드에서 116, 'a'는 97, 'z'는 122이므로 조건 참.

     - isLow() 함수 실행.

     ㄱ. isLower(char *str)

          - 매개변수 전달할 때 &str[1]은 101번지를 의미하므로 101번지를 전달받아 str에 저장.

          - *str = (*str - 'a' + 10) % 26 + 'a'에서 *str은 101번지의 값인 't'(116), 'a'는 97.

          - 계산하면 (116 - 97 + 10) % 26 + 97 = 29 % 26 + 97 = 3 + 97 = 100의 값이 나오고, 100은 아스키코드에서 'd를 의미.

          - 따라서 *str에 'd'를 저장하므로 101번지에는 'd'를 저장.

 ③ i = 2 일 때

     - 함수 다 실행하고 호출한 곳으로 넘어와 else if문 종료하면 i++ 실행하여 i = 2로 증가.

     - while문 조건 보면 i < 7 = 2 < 7은 참이므로 내부 실행.

     - char ch = str[i]는 str[2]을 ch에 대입하므로 char ch = NULL을 저장.

     - NULL은 if문 조건식에서 해당하는 구문이 없으므로 실행하지 않고 i++로 바로 실행.

 ④ i = 3 일 때

     - while문 조건보면 3 < 7은 참이므로 내부 실행.

     - char ch = str[3]에서 str[3]은 'i'이므로 char ch = 'i'를 저장.

     - if문 조건 보면 소문자일 때 함수 실행하는 else if문인 두 번째문 실행.

     - isLower() 함수 실행.

     ㄱ. isLower(char *str)

          - 매개변수 &str[3]을 전달받으므로 *str에는 주소값 103번지를 저장.

          - *str = (*str - 'a' + 10) % 26 + 'a'에서 *str은 103번지의 값인 'i'(105), 'a'는 97.

          - 계산하면 (105 - 97 + 10) % 26 + 97 = 18 % 26 + 97 = 18 + 97 = 115의 값이 나오고, 115는 아스키코드에서 's'를 의미.

          - 따라서 *str에 's'를 저장하므로 103번지에는 's'를 저장.

 ⑤ i = 4 일 때

     - while문 조건 보면 4 < 7은 참이므로 내부 실행.

     - char ch = str[4]에서 str[4]는 's'이므로 char ch = 's'를 저장.

     - if문 조건 보면 소문자일 때 함수 실행하는 else if문인 두 번째문 실행.

     - isLower() 함수 실행.

     ㄱ. isLower(char *str)

          - 매개변수 &str[4]를 전달받으므로 *str에는 주소값 104번지를 저장.

          - *str = (*str - 'a' + 10) % 26 + 'a'에서 *str은 104번지의 값인 's'(115), 'a'는 97.

          - 계산하면 (115 - 97 + 10) % 26 + 97 = 28 % 26 + 97 = 2 + 97 = 99의 값이 나오고, 99는 아스키코드에서 'c'를 의미.

          - 따라서 *str에 'c'를 저장하므로 104번지에는'c'를 저장.

 ⑥ i = 5 일 때 빈 문자열이므로 i++ 실행하여 i = 6으로 증가.

 ⑦ i = 6 일 때 

     - while문 조건 보면 6 < 7은 참이므로 내부 실행.

     - char ch = str[6]에서 str[6]은 8이므로 char ch = '8'을 저장.

     - if문 조건 보면 숫자일 때 함수 실행하는 else if문인 세 번째문 실행.

     - isNum() 함수 실행.

     ㄱ. isNum(char *str)

          - 매개변수 &str[6]을 전달받으므로 *str에는 주소값 106번지를 저장.

          - *str = (*str - '0' + 3) %10 + '0'에서 *str은 106번지의 값인 '8'(56), '0'은 48.

          - 계산하면 (56 - 48 + 3) % 10 + 48 = 11 % 10 + 48 = 1 + 48 = 49의 값이 나오고, 49는 아스키코드에서 '1'을 의미.

          - 따라서 *str에 '1'을 저장하므로 106번지에는 '1'을 저장.

 ⑧ i = 7 일 때 while문 조건 성립하지 않으므로 while문 빠져나와 출력하게 됨.

 

배열 str의 값을 문자열 형식으로 출력하면 Nd sc 1,

최종적으로 str 배열에 저장된 값은

str
(100)
0 1 2 3 4 5 6 7
N d   s c   1 \0

 

[출력]

Nd sc 1

 

[2회]

 

1. 다음은 Java 코드에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.

public class Main {
	public static void main(String[] args) {
		int[] a = new int[] {1, 2, 3, 4};
		int[] b = new int[] {1, 2, 3, 4};
		int[] c = new int[] {1, 2, 3};
		
		check(a, b);
		check(a, c);
		check(b, c);
	}
	public static void check(int[] x, int[] y) {
		if(a == b) {
			System.out.print("O" + " ");
		} else {
			System.out.print("N" + " ");
		}
	}
}

 

[출력]

 

N N N

 

[풀이]

 

- == 연산자는 참조 주소를 비교하는 연산자.

- Stack 영역에는 변수가 저장되고, new를 통해서 배열 객체를 생성하면서 배열 객체의 저장된 값을 Heap 영역에 저장. (주소값을 저장)

- 배열이 값을 사용하기 위해서 인덱스를 사용하면, 먼저 Stack 영역 변수에 접근한 뒤, Heqp 영역에는 메모리 주소가 저장되어 있으므로 그곳의 값을 가지고 오는 순서임.

- 배열 a의 Heap 영역에는 100번지, 배열 b의 Heap 영역에는 200번지, 배열 c의 Heap 영역에는 300번지라고 가정하자.

 

① check(a, b)

 - check 함수를 호출하면서 매개변수 a, b값을 던지고 그 값을 check 함수에서 배열 x, 배열 y로 저장.

 - if문 조건식을 보면 == 연산자는 참조 주소를 비교하므로 a는 100번지, b는 200번지로 서로 다르기 때문에 'N'을 출력.

② check(a, c)

 - check 함수를 호출하면서 매개변수 a, c값을 던지고 그 값을 check 함수에서 배열 x, 배열 y로 저장.

 - if문 조건식을 보면 a는 100번지, c는 300번지로 서로 다르기 때문에 'N'을 출력.

③ check(b, c)

 - check 함수를 호출하면서 매개변수 b, c값을 던지고 그 값을 check 함수에서 배열 x, 배열 y로 저장.

 - if문 조건식을 보면 b는 200번지, c는 300번지로 서로 다르기 때문에 'N'을 출력.


 

8. 다음은 Python에 대한 문제이다. 아래 코드를 읽고 알맞는 출력 값을 작성하시오.

def cnt(str, p) :
    result = 0
    for i in range(len(str) - len(p) + 1):
        sub = str[i : i + len(p)]
        if sub == p:
            result += 1
    return result
str = "abdcabcabca"
p1 = "ca"
p2 = "ab"
print(f'ab{cnt(str,p1)}'f'ca{cnt(str,p2)}')

 

 

[문자열 포매팅(String Formatting)]

 

① format : 문자열에 중괄호 { }를 사용해 값을 삽입.

year = 2024
subject = '프로그래밍'
text = '{0}, 서이쌤의 {1}'.format(year, subject)
print(text)

# 2024, 서이쌤의 프로그래밍

 

② f-string : 문자열 앞에 f 또는 F를 붙이고 따옴표 안의 중괄호 { } 안에 값을 삽입.

year = 2024
subject = '프로그래밍'
text = f'{year}, 서이쌤의 {subject}'
print(text)

# 2024, 서이쌤의 프로그래밍

 

[출력]

ab3ca3

[풀이]

 

- 함수가 선언되어 있고, 문자열 str 선언.

- 함수는 호출을 통해 실행하므로 str 코드 먼저 실행.

 

1) str = "abdcabcabca"

 - 문자열 str 선언하면서 초기화.

 

2) p1 = "ca"

 - 문자열 p1 선언하면서 ca로 초기화.

 

3) p2 = "ab"

 - 문자열 p2 선언하면서 ab로 초기화.

 

4) print(f'ab{cnt(str,p1)}'f'ca{cnt(str,p2)}')

 ① f'ab{cnt(str, p1)}'

   - { } 중괄호를 만나면 변수의 값을 출력하므로 그전까지 앞에 ab는 그대로 출력.

   - 함수 실행

       - i의 범위는 len(str) - len(p) + 1이고, str의 길이는 11, p의 길이는 2이므로 11 - 2 + 1 = 10이므로 0 ~ 9까지 실행.

       ㄱ. i = 0 일 때 sub = str[0:0+2] = str[0:2]이고, str의 0번부터 1번까지의 값을 sub에 저장하므로 sub = "ab"

                             if문 조건 확인하면 sub == p는 "ab" == "ca" 거짓이므로 다음 구문 실행.

       ㄴ. i = 1 일 때 sub = str[1:1+2] = str[1:3]이고, str의 1번부터 32번까지의 값을 sub에 저장하므로 sub = "bd"

                             if문 조건 확인하면 sub == p는 "bd" == "ca"거짓이므로 다음 구문 실행.

이런식으로 계속 반복하다 보면 p의 값인 ab랑 같은 결괏값은 총 3번이 나오므로 result = 3을 반환함.

p2의 결괏값도 result = 3을 반환하므로 출력값은 ab3ca3임.


 

10. 다음은 C언어에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.

#include<stdio.h>

int main() {
	int a[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	int* pa[2] = { a[1], a[2] };
	printf("%d", pa[1][1] + *(pa[1] + 2) + **pa);
}

 

1) int a[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

 - 이차원 정수형 배열 a 선언

a
100
a[0]
100
1
100
2
101
3
102
a[1]
103
4
103
5
104
6
105
a[2]
106
7
106
8
107
9
108

 

2) int* pa[2] = { a[1], a[2] };

 - 포인터 정수형 배열 pa 선언하면서 a[1], a[2]의 주소값을 가짐.

pa

pa[0] pa1]
&a[1] &a[2]

 

3) 결과

 ① pa[1][1]

     - pa[1]은 a[2]의 주소값을 참조하고, a 배열로 가서 a[2][1]을 찾으면 값은 8을 출력.

 ② *(pa[1] + 2)

     - pa[1]은 a[2]의 주소값을 참조하고, a[2] 주소값은 106에 +2를 하면 108번지의 값인 9를 출력.

 ③ **pa

     - pa는 a[1]을 참조하고, a[1]의 값(*a[1])은 103번지를 의미하며, 103번지의 값(*103번지)은 4이므로 4를 출력.

 

따라서 8 + 9 + 4 = 21

 

[출력]

21

 

11. 다음은 C언어에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.

#include<stdio.h>

void swap(int a, int b) {
	int t = a;
	a = b;
	b = t;
}
int main() {
	int a = 11;
	int b = 19;
	swap(a, b);
	switch (a) {
	case 1: b += 1;
	case 11: b += 2;
	default: b += 3;
		break;
	}
	printf("%d", a - b);
}

 

▶ 전역변수, 지역변수, 함수 안에서의 변수 범위 확인해서 풀어야 함.

 

1) swap 함수

 - int a, int b를 매개변수로 받고, int t를 선언하면서 a와 b의 값을 바꿈.

 - 하지만 return 값이 없으므로 함수를 호출받아도 a와 b의 바꾼 값을 반환하지 않음.

 

2) main 함수

 ① int a = 11; int b = 19;

     - 정수형 변수 a, b 선언하면서 a = 11, b = 19로 초기화.

 ② swap(a, b);

     - swap 함수 호출하여 a, b를 전달하지만 정작 swap 함수에서는 return 값이 없으므로 의미가 없음.

 ③ switch구문

     - a의 값에 딸 case를 실행하므로 현재 main함수에서 a의 값은 11이므로 case 11로 이동.

     - case 11은 b += 2이므로 main함수에서 b의 값은 19이므로 b = b + 2 = 19 + 2 = 21. 따라서 b = 21.

     - break 구문이 없으므로 default도 실행하면 b = b + 3 = 21 + 3 = 24. 따라서 b = 24.

 ④ 출력하면 a - b의 값을 정수로 출력하므로 a = 11, b = 24이므로 11 - 24 = -13을 출력.

 

[출력]

-13

 

12. 다음은 C언어에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.

#include<stdio.h>

void func(char* d, char* s) {
	while (*s != NULL) {
		*d = *s;
		d++;
		s++;
	}
	*d = '\0';
}
int main() {
	char* str1 = "first";
	char str2[50] = "teststring";
	int result = 0;
	func(str2, str1);
	for (int i = 0; str2[i] != '\0'; i++) {
		result += i;
	}
	printf("%d", result);
}

 

1) main 함수

 - C언어에서 문자열을 저장하는 방법은 배열을 이용하거나 포인터를 이용함.

 ① char* str1 = "first";

     - 문자열 str1 포인터 변수 선언하면서 초기화. (시작주소를 100번지로 가정.)

 ② char str2[50] = "teststring";

     - 길이가 50인 문자 배열 str2 선언하면서 초기화. (시작주소를 200번지로 가정.)

str1
100
0 1 2 3 4 5
f i r s t \0
str2
200
0 1 2 3 4 5 6 7 8 9 10 ... 49
t e s t s t r i n g \0 ...  

 

 ③ int result = 0;

     - 정수형 변수 result 선언하면서 0으로 초기화.

 ④ func(str2, str1);

     - func 함수 호출하면서 str2와 str1을 전달.

 

2) func 함수

 - func 함수의 매개변수는 문자형 포인터 변수를 받음. 포인터로 받기 때문에 *d, *s에는 주소를 저장.

 - main 함수에서 str2는 200번지를, str1은 100번지를 전달함.

 - 따라서 d는 200번지를, s는 100번지를 전달받음.

 ① while문

     - *s != null은 100번지에 저장된 값이 null인가를 물음. 조건은 참이므로 아래 문장 실행.

     ㄱ. *d = *s는 200번지의 값을 100번지의 값으로 변경하라는 의미로, 200번지의 값인 t가 100번지의 값인 f로 변경.

     ㄴ. d++는 d가 현재 주소값을 저장하고 있는 변수이므로 현재 주소값인 200번지에서 ++연산하면 201번지를 가리킴.

     ㄷ. s++는 s가 현재 주소값을 저장하고 있는 변수이므로 현재 주소값인 100번지에서 ++연산하면 101번지를 가리킴.

     ㄹ. 다시 반복문을 실행하면 *d = *s는 201번지의 값을 101번지의 값으로 변경하는 것으로 201번지의 값인 e가 101번지의 값인 i로 변경.

 

이런 식으로 진행하다 보면 str2의 값이 str1의 널까지의 값으로 변경이 됨.

str2
200
0 1 2 3 4 5 6 7 8 9 10 ... 49
f i r s t \0 r i n g \0 ...  

 

     ㅁ. s의 주소값의 값이 null을 만나면 while문을 종료하고, *d = '\0'은 205번지의 값을 \0로 저장하라는 의미.

 

3) main 함수

 - 다시 main 함수로 돌아와 for문 실행.

 - i는 0부터 시작해서 str2의 문자가 널 만나기 전까지 실행하니까 i < 5.

 ① i = 0 일 때 result = result + i = 0 + 0 = 0.

 ② i = 1 일 때 result = result + i = 0 + 1 = 1.

 ③ i = 2 일 때 result = result + i = 1 + 2 = 3.

 ④ i = 3 일 때 result = result + i = 3 + 3 = 6.

 ⑤ i = 4 일 때 result = result + i = 6 + 4 = 10.

 ⑥ i = 5 일 때 조건 맞지 않으므로 반복문 빠져나옴.

 

[출력]

10

 

13. 다음은 Java 언어에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.

interface Number {
	int sum(int[] a, boolean odd);
}
public class Gisafist {
	public static void main(String[] args) {
		int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
		OENumber OE = new OENumber();
		System.out.println(OE.sum(a, true) + ", " + OE.sum(a, false));
	}
}
class OENumber implements Number {
	public int sum(int[] a, boolean odd) {
		int result = 0;
		for(int i=0; i<a.length; i++) {
			if(odd && a[i] % 2 != 0 || (!odd && a[i] % 2 == 0))
				result += a[i];
		}
		return result;
	}
}

 

▶ 인터페이스 : 클래스를 작성할 때 기본이 되는 틀을 제공하는 일종의 추상클래스.

▶ 추상클래스 : 클래스들의 공통되는 속성과 메서드를 정의한 구체적이지 않은 클래스 (extends 키워드 사용)

 

1) main 함수

 ① int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

     - 정수형 배열 a 선언하면서 초기화.

 ② OENumber OE = new OENumber();

     - 클래스 OENumber의 객체 OE 생성.

 ③ System.out.println(OE.sum(a, true) + ", " + OE.sum(a, false));

     - 출력하기 전 함수 실행

 

2) OENumber 함수

 ① OE.sum(a, true)

  - OE 객체는 클래스 OENumber의 sum 메서드를 호출하는데 a, true 매개변수를 던짐.

  - sum 메서드의 매개변수를 보면, a는 배열 a를 의미하고, boolean odd는 true 값을 저장함.

  ㄱ. for문 실행.

     - 는 0부터 시작하고 a.length는 9이므로 9전까지 실행.

     ⓐ i = 0 일 때 if문 조건 확인하면

          odd && a[0] % 2 != 0은 true && 1 % 2 != 0이므로 결과는 참.

          단락회로 평가로 인해 뒤에 문장은 실행하지 않고 다음 문장 실행함 (뒤에는 ||이어서 둘 중 하나가 참이면 참이기 때문.)

          result = result + a[0] = 0 + 1 = 1. 따라서 result = 1.

     ⓑ i = 1 일 때 if문 조건 확인하면

          odd && a[1] % 2 != 0은 true && 2 % 2 !=0이므로 결과는 거짓.

          뒤에 문장 실행하면 !odd && a[1] % 2 == 0은 앞에 조건이 거짓이므로 다음 반복문 실행.

     이런식으로 진행하다 보면 i는 짝수일 때 result 값이 계산되므로 result = 25를 출력.

     간단하게 정리하면

     i = 0 일 때 result = 0 + 1 = 1.

     i = 2 일 때 result = 1 + 3 = 4.

     i = 4 일 때 result = 4 + 5 = 9.

     i = 6 일 때 result = 9 + 7 = 16.

     i = 8 일 때 result = 16 + 9 = 25.

 

 ② OE.sum(a, false)

   - OE 객체는 클래스 OENumber의 sum 메서드를 호출하는데 a, false 매개변수를 던짐.

   - sum 메서드의 매개변수는 a는 배열 a를 의미하고, boolean odd는 false 값을 저장함.

   ㄱ. for문 실행.

     - i는 0부터 시작하고 a.length는 9이므로 9전까지 실행.

     ⓐ i = 0 일 때 if문 조건 확인하면

          odd는 이미 false이므로 앞에 조건은 거짓.

          뒤에 문장 실행하면 !odd && a[0] % 2 == 0은 true && 1 % 2 == 0은 거짓이므로 다음 반복문 실행.

     ⓑ i = 1 일 때 if문 조건 확인하면

          odd는 이미 false이므로 앞에 조건은 거짓.

          뒤에 문장 실행하면 !odd && a[1] % 2 == 0은 true && 2 % 2 == 0은 참이므로 result = 0 + 2 = 2.

     이런 식으로 진행하다 보면 i는 홀수 일 때 result 값이 계산되므로 result = 20을 출력.

     간단하게 정리하면

     i = 1 일 때 result = 0 + 2 = 2.

     i = 3 일 때 result = 2 + 4 = 6.

     i = 5 일 때 result = 6 + 6 = 12.

     i = 7 일 때 result = 12 + 8 = 20

 

[출력]

25, 20

 

18. 다음은 Java에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.

public class Gisafist {
	public static String rf(String str, int index, boolean[] seen) {
		if(index < 0) return "";
		char c = str.charAt(index);
		String result = rf(str, index-1, seen);
		if(!seen[c]) {
			seen[c] = true;
			return c + result;
		}
		return result;
	}
	public static void main(String[] args) {
		String str = "abacbcd";
		int lentgh = str.length();
		boolean[] seen = new boolean[256];
		System.out.print(rf(str, lentgh-1, seen));
	}
}

 

1) main 함수

 ① String str = "abacbcd";

    - 문자열 변수 str 선언하면서 초기화.

 ② int lentgh = str.length();

    - 정수형 변수 length 선언하는데 str.length()의 값을 대입. str.length()는 8이므로 int length = 8.

 ③ boolean[] seen = new boolean[256];

    - 데이터 타입이 boolean이고, 크기가 256인 배열 seen을 생성.

    - boolean은 true, false 값만 들어올 수 있음.

    - 0부터 255까지의 인덱스를 가지는 배열 안에는 true, false의 값만 가진다는 것을 알 수 있음.

 ④ System.out.print(rf(str, lentgh-1, seen));

    - 출력하기 전 rf 함수 실행하고 그의 값을 반환하여 출력.

 

2) rf 함수

 ① rf(str, 7, seen)

  - main 함수에서 rf(str, length-1, seen)을 전달하였으므로 rf 함수에서 받음.

  - String str은 str = "abacbcd"이고, length-1은 7이므로 int idex의 값은 7이며, boolean[] seen은 seen으로 받음.

  - if문 조건 확인하면 index < 0은 index는 현재 7이므로 조건은 거짓이므로 다음 문장 실행.

str 0 1 2 3 4 5 6 7
a b a c a b c d

 

  - char c = str.charAt(index);은 index는 현재 7이므로 그의 해당하는 값인 'd'를 c에 저장.

  - 여기서 charAt은 String으로 저장된 문자열 중에서 한 글자만 선택해서 char 타입으로 변환해 줌.

  - String result = rf(str, index-1, seen);은 rf(str, 6, seen)이므로 한 번 더 rf를 실행함.

 

② rf(str, 6, seen)

  - if문 조건 확인하면 index < 0은 6 < 0 거짓이므로 다음 문장 실행.

  - char c = str.charAt(index)에서 index는 6이므로 그의 해당하는 값인 'c'를 c에 저장.

  - String result = rf(str, index-1, seen)에서 rf 함수 다시 호출.

 

③ rf(str, 5, seen)

  - if문 조건 확인하면 index < 0은 5 < 0은 거짓이므로 다음 문장 실행.

  - char c = str.charAt(index)에서 index는 5이므로 그의 해당하는 값인 'b'를 c에 저장.

  - String result = rf(str, index-1, seen)에서 rf 함수 다시 호출.

 

...

 

 ⑧ rf(str, 0, seen)

   - if문 조건 확인하면 0 < 0은 거짓이므로 다음 문장 실행.

   - char c= str.charAt(index)에서 index는 0이므로 그의 해당하는 값인 'a'를 c에 저장.

   - String result = rf(str, index-1, seen)에서 rf 함수 다시 호출.

 

 ⑨ rf(str, -1, seen)

   - if문 조건 확인하면 -1 < 0은 참이므로 return "" 실행하는데 ""는 아무것도 저장하지 않은 문자열을 반환.

   - 즉 빈칸에 문자열을 반환한다는 의미. 따라서 index가 -1인 함수는 종료되고, 이 함수를 호출한 곳으로 빈칸의 문자열을 반환함.

   - index가 -1인 함수를 호출한 곳은 index가 0인 함수이므로 이 함수의 result값을 구할 수 있게 됨.

   - 따라서 index가 0인 함수의 result값을 구하려면 result 다음 문장부터 실행하면 됨.

   - if문 조건 확인하면 !seen[c]인데 현재 boolean[] seen에서 seen은 boolean타입으로 기본값은 false임.

   - if문으로 돌아가면 seen[c]에서 c는 현재 index 0에서 'a'의 값을 저장하고 있음.

   - index에는 숫자가 저장되어야 하기 때문에 a를 아스키코드로 변환하면 97이라는 숫자를 가짐.

   - 그러면 seen[97] = false이고, !false는 true이므로 안에 문장을 실행하게 됨. (현재 배열 c는 false로 초기화되어 있기 때문.)

   - seen[c] = true;에서 seen[97] = true로 바뀜.

   - return c + reusult에서 현재 c의 값인 a와 result의 값인 0을 더하면 a의 값이 반환됨.

   - 즉 반환된 a의 값은 이 함수를 호출한 index가 1인 곳으로 이동.

   - 이동하다가 index가 2인 곳으로 이동해서 코드 실행해보면 index가 2일 때 c의 값은 'a'를 저장하고 있음.

   - if문 조건에서 !seen[c] = seen[97]은 위에서 true라는 값을 가지게 되고, 앞에 !를 만나 false가 되므로 안에 문장은 실행하지 않음.

   - 실행하지 않고 return result로 가서 result를 보내주면 되는데 반환값이 ba이므로 ba를 호출한 곳으로 이동.

 

   이렇게 호출한 곳으로 이동하면서 result의 값을 구하면 dcba를 출력하게 됨.

 

[출력]

dcba

 

19. 다음은 C언어의 구조체에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.

#include<stdio.h>

struct node {
	int n1;
	struct node* n2;
};
int main() {
	struct node* head = NULL;
	struct node a = { 10, 0 };
	struct node b = { 20, 0 };
	struct node c = { 30, 0 };
	head = &a;
	a.n2 = &b;
	b.n2 = &c;
	printf("%d", head->n2->n1);
}

 

1) 구조체 node

 ① int n1; 

   - 정수형 변수 n1 선언.

 ② struct node* n2;

   - 구조체 node의 주소값을 저장하는 변수 n2 선언. (포인터 변수)

 

2) main 함수

 ① struct node* head = NULL;

    - 구조체 node의 데이터 타입을 가지는 포인터 변수 head 선언하면서 NULL로 초기화.

 ② struct node a = { 10, 0 };

    -  구조체 node의 데이터 타입을 가지는 변수 a를 선언하면서 10과 0을 저장.

    - 그러면 int n1에는 10을, struct node* n2에는 0을 저장.

구조체 a
(100번지)
n1 10
n2 0

 

 ③ struct node b = { 20, 0 };

    - 구조체 node의 데이터 타입을 가지는 변수 b를 선언하면서 20과 0을 저장.

    - 그러면 int n1에는 20을, struct node* n2에는 0을 저장.

구조체 b
(200번지)
n1 20
n2 0

 

 ④ struct node c = { 30, 0 };

    - 구조체 node의 데이터 타입을 가지는 변수 c를 선언하면서 30과 0을 저장.

    - 그러면 int n1에는 30을, struct node* n2에는 0을 저장.

구조체 c
(300번지)
n1 30
n2 0

 

 ⑤ head = &a;

    - head에는 a의 주소값을 저장하므로 100번지.

 

 ⑥ a.n2 = &b;

    - a.n2에는 b의 주소값을 저장하므로 200번지.

 

 ⑦ b.n2 = &c;

    - b.n2에는 c의 주소값을 저장하므로 300번지.

 

구조체a
(100번지)
n1 10 구조체b
(200번지)
n1 20 구조체c
(300번지)
n1 30
n2 200 n2 300 n2  

 

 ⑧ head->n2->n1

    - ->는 저장된 주소로 가서 그 구조체 변수에 접근할 수 있음.

    - 따라서 head는 100번지이고 100번지의 n2는 200번지며, 200번지의 n1의 값은 20이므로 20을 출력하게 됨.

 

[출력]

20

 

20. 다음은 Java에 대한 문제이다. 아래 코드를 확인하여 알맞는 출력 값을 작성하시오.

public class Gisafist {
	public static void main(String[] args) {
		String str = "ITISTESTSTRING";
		String[] result = str.split("T");
		System.out.println(result[3]);
	}
}

 

▶ split은 나누다라는 의미.

▶ 대상문자열.split(구분자) : 구분자를 기준으로 문자열을 분할하여 배열로 반환하는 메서드.

▶ 구분자는 한 개가 아닌 여러 개로 구분 가능.

 

1) String str = "ITISTESTSTRING"

   - 문자열 str 선언하면서 초기화.

 

2) String[] result = str.split("T");

   - T를 기준으로 문자열을 분할.

   - I / T / IS / T / ES / T / S / T / RING

   - T를 기준으로 나눈 나머지 문자열을 배열로 저장하는데, 구분자는 포함하지 않고 배열에 저장함.

result 0 1 2 3 4
I IS ES S RING

 

3) System.out.println(result[3]);

   - 따라서 result[3]에는 S가 저장되어 있으므로 S를 출력.

 

[출력]

S