정보처리기사 개념정리 목차

4과목 프로그래밍언어활용 ① — 언어

이 과목이 과락의 주범이다. 기출 160문항(과목4)에서 지문에 실제로 등장한 횟수를 세면 int(52) · main(23) · printf(19) · char(18) · for(24) · Java(15) · Python(11)코드를 직접 읽고 출력을 계산하는 문항이 회차당 3~6개이고 그 대부분이 이 과목에 몰려 있다.

이 과목은 절반이 언어, 절반이 운영체제·네트워크다. 분량이 커서 편을 나눴다 — 운영체제·네트워크는 다음 편에서 다룬다.

언어 문항은 외워서 풀리지 않는다. 종이에 변수 표를 그려 한 줄씩 굴리는 것이 유일한 방법이고, 이 편은 그 굴리는 절차를 예제마다 적었다.


0. 이 과목의 지형

언어 특성 활용     자료형 · 변수 · 연산자 · 제어문 · 함수      ← 코드 문항
C · Java · Python  문법과 출력 계산                            ← 코드 문항
모듈 구현          모듈화 · 결합도 · 응집도 · 재사용
라이브러리·예외    표준 라이브러리 · 예외 처리
운영체제 · 네트워크 (다음 편)

1. 언어 일반

언어의 분류

분류언어
절차적(명령형)C, FORTRAN, COBOL, PASCAL
객체지향Java, C++, C#, Smalltalk
함수형LISP, Haskell, Scala
논리형(선언형)PROLOG
스크립트JavaScript, Python, PHP, ASP, JSP, Ruby, Perl

함정 — PROLOG 는 논리형, LISP 는 함수형이다. 이 둘을 바꿔 낸 보기가 단골. 그리고 JSP·ASP·PHP 는 서버 측 스크립트, JavaScript 는 클라이언트 측에서 출발했다.

컴파일러와 인터프리터

컴파일러인터프리터
번역 단위전체를 한 번에한 행씩
목적 코드생성한다생성하지 않는다
실행 속도빠르다느리다
메모리목적 코드 공간 필요적게 든다
C, C++, FORTRANPython, JavaScript, BASIC

번역 과정

원시 코드 → 어휘 분석(토큰 분리) → 구문 분석(파싱·구문 트리) → 의미 분석
        → 최적화 → 목적 코드 생성 → 링커(라이브러리 결합) → 로더(메모리 적재) → 실행

함정링커는 목적 코드와 라이브러리를 묶어 실행 파일을 만들고, 로더는 그것을 메모리에 올린다. 순서와 역할을 바꿔 낸다.

변수와 식별자 (식별자 2회 · 예약어 2회)

식별자 규칙   영문자·숫자·밑줄(_) 사용 / 첫 글자에 숫자 불가 / 예약어 사용 불가
              대소문자 구분 / 공백·특수문자 불가

함정2sum(숫자로 시작), int(예약어), my var(공백), total-sum(하이픈)은 모두 부적합. _count, sum2, myVar 는 적합하다.

기억 클래스(C)

클래스저장 위치생존
auto스택블록을 벗어나면 소멸 (기본값)
static데이터 영역프로그램 종료까지 유지, 초기값 0
register레지스터빠른 접근 요청
extern데이터 영역다른 파일의 전역 변수를 참조

static 지역 변수는 함수를 다시 호출해도 값이 유지된다. 이 성질로 출력 계산 문항이 나온다.

스코프

지역(local)   선언된 블록 안에서만
전역(global)  파일 전체에서 (함수 밖에 선언)
같은 이름이면 안쪽(지역)이 우선한다

2. 연산자 — 우선순위가 계산의 출발점

우선순위 (높은 것부터)

①  ( )  [ ]  .  ->                    괄호·배열·멤버
②  !  ~  ++  --  (형변환)  *  &  sizeof   단항
③  *  /  %                            산술(곱·나눗셈)
④  +  -                               산술(덧셈·뺄셈)
⑤  <<  >>                             시프트
⑥  <  <=  >  >=                       관계
⑦  ==  !=                             등가
⑧  &  →  ^  →  |                      비트 AND → XOR → OR
⑨  &&  →  ||                          논리 AND → OR
⑩  ? :                                삼항
⑪  =  +=  -=  *=  /=  %=              대입 (오른쪽 → 왼쪽 결합)
⑫  ,                                  쉼표

가장 자주 쓰이는 함정&&|| 보다 먼저다. 그리고 관계 연산자가 등가 연산자보다 먼저다. a + b * ca + (b*c).

정수 나눗셈과 나머지

int a = 7, b = 2;
printf("%d %d %d", a/b, a%b, a*1.0/b);   // 3  1  3.5

정수끼리 나누면 소수점이 버려진다. 이 한 줄이 오답의 가장 큰 원인이다. 음수 나머지는 처리 방식이 언어마다 달라 시험에서는 잘 나오지 않는다.

비트 연산자

&  AND    둘 다 1이면 1        |  OR   하나라도 1이면 1
^  XOR    다르면 1             ~  NOT  비트 반전
<< 왼쪽 시프트 = ×2 씩         >> 오른쪽 시프트 = ÷2 씩
int a = 12;      // 0000 1100
printf("%d", a & 10);   // 0000 1010 → 0000 1000 = 8
printf("%d", a | 10);   //             → 0000 1110 = 14
printf("%d", a ^ 10);   //             → 0000 0110 = 6
printf("%d", a << 2);   // 12 × 4 = 48
printf("%d", a >> 2);   // 12 ÷ 4 = 3

계산 요령 — 2진수로 세로로 적어 놓고 비트를 맞춰 계산한다. 시프트는 곱하기·나누기로 바꿔 계산.

증감 연산자 — 전위와 후위

int i = 5, r;
r = i++;   // r = 5,  i = 6   (먼저 쓰고 나중에 증가)
i = 5;
r = ++i;   // r = 6,  i = 6   (먼저 증가하고 사용)

주의printf("%d %d", i++, ++i) 처럼 같은 식에서 같은 변수를 두 번 증감하는 형태는 C 표준이 결과를 정의하지 않는다. 기출은 대개 문장을 나눠 출제한다.


3. 제어문

if (조건) { } else if (조건) { } else { }

switch (값) {
  case 1: ... break;        // break 를 빼면 아래로 흘러 내려간다(fall-through)
  case 2: ... break;
  default: ...
}

for (초기식; 조건식; 증감식) { }
while (조건) { }
do { } while (조건);        // 조건이 거짓이어도 최소 한 번 실행
키워드동작
break반복문·switch 를 완전히 빠져나온다 (5회 출제)
continue이번 회차만 건너뛰고 다음 반복으로 (7회 출제)
goto지정 레이블로 점프 — 가독성 때문에 권장되지 않는다

함정 둘 — ① switch 에서 break 누락 시 다음 case 로 계속 실행된다. ② do-while조건과 무관하게 한 번은 실행된다.

반복 횟수 세기

for (i = 1; i <= 10; i += 3)   // i = 1, 4, 7, 10 → 4회
for (i = 0; i < 10; i++)       // 0~9 → 10회
for (i = 10; i > 0; i -= 2)    // 10,8,6,4,2 → 5회

4. C 언어

출력 서식

서식의미
%d10진 정수
%f실수 (기본 소수점 6자리)
%.2f소수점 2자리까지
%c문자 하나
%s문자열
%x %o16진 · 8진
%5d폭 5칸, 오른쪽 정렬
%-5d폭 5칸, 왼쪽 정렬

배열과 문자열

int a[5] = {1, 2, 3};      // 나머지는 0 으로 채워진다 → {1,2,3,0,0}
char s[] = "hello";        // 크기는 6 ('\0' 포함)

printf("%d", sizeof(s));   // 6
printf("%d", strlen(s));   // 5  ← 널 문자를 세지 않는다
함수기능
strlen(s)길이 (널 문자 제외)
strcpy(d, s)복사
strcat(d, s)이어 붙이기
strcmp(a, b)같으면 0, 사전순 앞이면 음수

함정sizeof널 문자를 포함, strlen제외한다. 이 차이가 그대로 문항이 된다. 2차원 배열 a[2][3] 의 원소 수는 6이고, a[i][j] 는 행 i, 열 j.

포인터

int a = 10;
int *p = &a;      // p 는 a 의 주소를 갖는다

printf("%d", *p);    // 10   (역참조 = 그 주소의 값)
*p = 20;             // a 가 20 이 된다
printf("%d", a);     // 20

배열과 포인터는 같은 것을 다르게 쓴 것이다.

int arr[3] = {10, 20, 30};
int *p = arr;              // 배열 이름은 첫 원소의 주소

arr[1] == *(arr + 1) == p[1] == *(p + 1)   // 모두 20

포인터 연산의 핵심p + 11 바이트가 아니라 자료형 크기만큼 이동한다. int* 라면 4바이트 뒤. 이 성질을 묻는 문항이 나온다.

함수의 값 호출과 참조 호출

void swapWrong(int x, int y) { int t = x; x = y; y = t; }   // 값 호출 — 원본 안 바뀜
void swapRight(int *x, int *y) { int t = *x; *x = *y; *y = t; }  // 주소를 넘겨야 바뀐다

int a = 1, b = 2;
swapWrong(a, b);       // a=1, b=2  그대로
swapRight(&a, &b);     // a=2, b=1  바뀐다

이 예제가 그대로 출제된다. 값 호출(call by value)은 복사본을 넘기므로 원본이 안 바뀐다.

구조체와 공용체

struct Point { int x; int y; };       // 멤버가 각자 공간을 갖는다
union  Data  { int i; char c; };      // 멤버가 같은 공간을 공유 → 크기 = 가장 큰 멤버

struct Point p = {3, 4};
printf("%d", p.x);          // 3
struct Point *pp = &p;
printf("%d", pp->y);        // 4   (포인터는 -> 로 접근)

동적 메모리

int *p = (int*)malloc(sizeof(int) * 5);   // 힙에 정수 5개 공간
free(p);                                  // 반드시 해제 (안 하면 메모리 누수)

calloc 은 0으로 초기화하고, realloc 은 크기를 바꾼다.

전처리기 — 매크로 함정

#define SQ(x) x * x
printf("%d", SQ(2 + 3));    // 2 + 3 * 2 + 3 = 11  ← 25 가 아니다!

#define SQ2(x) ((x) * (x))
printf("%d", SQ2(2 + 3));   // 25  ← 괄호를 씌워야 한다

매크로는 함수가 아니라 문자열 치환이다. 괄호가 없으면 우선순위가 어긋난다.


5. Java

클래스와 객체

class Person {
    private String name;              // 필드
    Person(String name) { this.name = name; }   // 생성자
    public String getName() { return name; }
}
Person p = new Person("홍길동");

접근 제어자 — 좁은 것부터

private  <  default(생략)  <  protected  <  public
같은 클래스   같은 패키지     +상속 자식     전부

상속·오버라이딩·오버로딩

class Animal { void sound() { System.out.println("..."); } }
class Dog extends Animal {
    @Override void sound() { System.out.println("멍멍"); }   // 오버라이딩 (재정의)
}

Animal a = new Dog();
a.sound();      // "멍멍"  ← 실제 객체 타입의 메서드가 실행된다(다형성)
오버로딩(Overloading)오버라이딩(Overriding)
무엇같은 이름, 다른 매개변수부모 메서드를 재정의
결정 시점컴파일 시실행 시
조건매개변수 타입·개수가 달라야이름·매개변수·반환형이 같아야

함정반환형만 다른 것은 오버로딩이 아니다. 그리고 오버라이딩은 접근 제어자를 더 좁게 만들 수 없다.

static · final · this · super

static   객체 없이 클래스 이름으로 접근. 모든 객체가 공유
final    변수 = 상수, 메서드 = 재정의 금지, 클래스 = 상속 금지
this     자기 객체 참조 / this(...) 는 자기 생성자 호출
super    부모 객체 참조 / super(...) 는 부모 생성자 호출

추상 클래스와 인터페이스

추상 클래스인터페이스
키워드abstract classinterface
상속단일 상속다중 구현 가능
구현일반 메서드도 가질 수 있다추상 메서드 중심(+default)
목적공통 구현을 물려준다규약을 정한다

예외 처리

try {
    int r = 10 / 0;                       // ArithmeticException
} catch (ArithmeticException e) {
    System.out.println("0으로 나눔");
} finally {
    System.out.println("항상 실행");       // 예외가 나든 안 나든 실행된다
}
Throwable ┬ Error       — 복구 불가 (OutOfMemoryError)
          └ Exception ┬ RuntimeException — 컴파일러가 강제하지 않음(unchecked)
                      └ 그 외          — try-catch 또는 throws 필수(checked)

함정finallyreturn 이 있어도 실행된다. NullPointerException·ArrayIndexOutOfBoundsException·ArithmeticExceptionunchecked, IOException·ClassNotFoundExceptionchecked 다.

문자열

String a = "hello";
String b = "hello";
String c = new String("hello");

a == b        // true  ← 문자열 상수 풀에서 같은 객체를 공유
a == c        // false ← new 는 새 객체
a.equals(c)   // true  ← 값 비교는 equals

String s = "a";
s += "b";     // 새 객체가 만들어진다 (String 은 불변)
클래스가변동기화
String불변
StringBuilder가변없음 (빠름)
StringBuffer가변있음 (스레드 안전)

배열과 출력 계산 예제

int[] arr = {3, 1, 4, 1, 5};
int sum = 0;
for (int i = 0; i < arr.length; i++) {
    if (arr[i] % 2 == 1) sum += arr[i];
}
System.out.println(sum);      // 3 + 1 + 1 + 5 = 10

굴리는 절차 — 변수 표를 만들고 한 회차씩 적는다.

i=0  arr[0]=3  홀수  sum=3
i=1  arr[1]=1  홀수  sum=4
i=2  arr[2]=4  짝수  sum=4
i=3  arr[3]=1  홀수  sum=5
i=4  arr[4]=5  홀수  sum=10

6. Python

자료형 네 개의 성격

자료형표기순서변경중복
리스트(list)[1,2,3]
튜플(tuple)(1,2,3)불변
딕셔너리(dict){'a':1}(삽입 순)유일
집합(set){1,2,3}중복 제거

함정튜플은 원소를 바꿀 수 없다(t[0]=9 는 오류). 집합은 중복이 자동 제거되고 순서가 없다.

인덱싱과 슬라이싱 — 계산 문항 단골

a = [10, 20, 30, 40, 50]

a[0]      # 10
a[-1]     # 50    음수는 뒤에서부터
a[1:3]    # [20, 30]      ← 끝 인덱스는 제외한다
a[:3]     # [10, 20, 30]
a[2:]     # [30, 40, 50]
a[::2]    # [10, 30, 50]  간격 2
a[::-1]   # [50, 40, 30, 20, 10]  역순

핵심 함정 — 슬라이싱의 끝 인덱스는 포함되지 않는다. a[1:3] 은 2개다. 문자열도 같은 규칙이 적용된다: "python"[1:4]"yth".

range 와 반복

range(5)        # 0 1 2 3 4
range(1, 5)     # 1 2 3 4
range(1, 10, 2) # 1 3 5 7 9
range(5, 0, -1) # 5 4 3 2 1

for i in range(3):
    print(i, end=' ')       # 0 1 2

함수와 람다

def add(a, b=10):           # 기본값 매개변수
    return a + b
add(5)                      # 15

f = lambda x: x * 2
list(map(lambda x: x*2, [1,2,3]))       # [2, 4, 6]
list(filter(lambda x: x%2==0, [1,2,3,4])) # [2, 4]

문자열·기타

s = "Hello World"
s.upper()        # 'HELLO WORLD'
s.split()        # ['Hello', 'World']
s.replace('l','L')
len(s)           # 11
'-'.join(['a','b'])   # 'a-b'

a, b = 1, 2
a, b = b, a      # 스왑이 한 줄로 된다

들여쓰기가 문법이다. 블록을 중괄호가 아니라 들여쓰기로 구분하므로, 들여쓰기가 어긋나면 IndentationError 가 난다.

출력 계산 예제

a = [1, 2, 3, 4, 5]
r = 0
for x in a:
    if x % 2 == 0:
        continue          # 짝수는 건너뛴다
    r += x
print(r)                  # 1 + 3 + 5 = 9

7. 모듈 구현 — 이 과목에서도 결합도·응집도가 나온다

기출에서 결합도 13회 · 응집도 11회가 과목4 범위에서 등장했다. 자세한 표는 1과목 6절에 있고, 여기서는 결론만 다시 붙인다.

결합도  자료 < 스탬프 < 제어 < 외부 < 공통 < 내용        (낮을수록 좋다)
응집도  기능적 > 순차적 > 통신적 > 절차적 > 시간적 > 논리적 > 우연적   (높을수록 좋다)

모듈화의 목적 — 재사용성·유지보수성 향상, 복잡도 감소, 오류 파급 최소화. 팬인은 높게, 팬아웃은 낮게.


8. 라이브러리와 예외 처리

표준 라이브러리   언어가 기본 제공 (C: stdio.h·stdlib.h·string.h·math.h / Java: java.lang·util)
외부 라이브러리   따로 설치해 사용
C 헤더담긴 것
stdio.h입출력 — printf, scanf, fopen
stdlib.h형변환·동적 메모리 — atoi, malloc, rand
string.h문자열 — strlen, strcpy, strcmp
math.h수학 — sqrt, pow, abs

예외 처리의 원칙 — 예외를 무시하지 않는다, 구체적인 예외를 먼저 잡는다, 자원은 finally(또는 try-with-resources)에서 해제한다.


9. 코드 문항 대처법

① 변수 표를 그린다            변수 이름을 가로로 적고, 회차마다 한 줄씩 값을 적는다
② 반복 횟수를 먼저 센다        for 문의 시작·끝·증감으로 몇 번 도는지 확정
③ 정수 나눗셈을 표시한다        / 가 나오면 소수점 버림 여부를 즉시 확인
④ 전위·후위를 동그라미로       ++i 와 i++ 를 헷갈리면 전부 틀린다
⑤ 배열 인덱스는 0부터          길이 n 이면 마지막 인덱스는 n-1
⑥ Python 슬라이싱은 끝 제외
⑦ 값 호출인지 참조 호출인지    포인터·주소(&)가 있으면 원본이 바뀐다

시간이 부족할 때 — 코드 문항은 회차당 3~6개(전체의 3~6%)다. 계산이 오래 걸리면 표시하고 넘어간 뒤, 용어 문항을 먼저 확보하고 돌아온다. 다만 과목4 안에서는 20문항 중 3~5문항이라 통째로 버리면 과락 위험이 커진다.


10. 함정 정리

정수 / 정수 = 정수. 7/2 는 3이다.

sizeof 는 널 문자 포함, strlen 은 제외.

값 호출은 원본을 바꾸지 못한다. 주소(&)를 넘겨야 바뀐다.

매크로는 문자열 치환이다. #define SQ(x) x*x2+3 을 넣으면 11.

switchbreak 누락 → 아래 case 로 흘러간다.

do-while 은 최소 한 번 실행.

Java String 은 불변이고 == 는 참조 비교, equals 가 값 비교.

오버로딩은 반환형만 달라서는 성립하지 않는다.

finallyreturn 이 있어도 실행된다.

Python 슬라이싱 끝 인덱스는 제외. a[1:3] 은 2개.

튜플은 불변, 집합은 중복 제거.

PROLOG 는 논리형, LISP 는 함수형.

링커는 실행 파일을 만들고 로더는 메모리에 올린다.


한눈에 정리

  • 이 과목은 코드를 굴려야 점수가 나온다. 변수 표를 그리는 습관이 곧 실력이다
  • 계산 오답의 최대 원인 셋 — 정수 나눗셈, 전위/후위 증감, Python 슬라이싱 끝 제외
  • C 는 포인터와 값/참조 호출, Java 는 문자열·오버라이딩·예외, Python 은 자료형 성격과 슬라이싱
  • 연산자 우선순위는 단항 → 산술 → 시프트 → 관계 → 등가 → 비트 → 논리 → 삼항 → 대입
  • 언어 분류는 PROLOG(논리) · LISP(함수) · JSP·PHP(서버 스크립트) 를 짝지어 둔다
  • 모듈화 문항도 이 과목에서 나온다 — 결합도 낮게, 응집도 높게, 팬인 ↑ 팬아웃 ↓
  • 운영체제와 네트워크는 다음 편에서 — 이 과목 20문항의 절반이 거기서 나온다
3과목 데이터베이스구축4과목 프로그래밍언어활용 ② 운영체제·네트워크