자격증 정복/임베디드기사(기능사)

임베디드기사 실기 12 — 프로그램 작성 (C 프로그래밍: 포인터·메모리·출력 결과 계산)

올드 IT직장인 2026. 11. 3. 05:15

임베디드기사 실기 12 — 프로그램 작성 (C 프로그래밍: 포인터·메모리·출력 결과 계산)

출제기준 4-2: 임베디드 프로그램 작성하기
코드를 읽고 출력 결과를 손으로 계산하는 문제가 해마다 나와요.
문제 수는 적어도 점수는 확실히 가져갈 수 있는 구간입니다.


📎 필기 시리즈의 프로그래밍 언어 활용 편과 함께 보면 좋아요. (링크 추가 예정)


실기 출제 포인트 ⭐⭐⭐

키워드 핵심 내용 빈도 기출
출력 결과 계산 포인터·반복문·서식 문자 혼합 ⭐⭐⭐ 2017 Q11 = 2021 Q8, 2018 Q6, 2018 Q9,
2021 Q13, 2025 Q16
포인터 / 구조체 *(s+2), p->멤버 = (*p).멤버 ⭐⭐ 2018 Q6, 2021 Q14 = 2022 Q5
메모리 할당·해제 malloc / free, 이중 해제 ⭐⭐⭐ 2018 Q2 = 2024 Q7 (free), 2023 Q8 (이중 해제)
공용체 union 멤버가 메모리를 공유 ⭐⭐ 2017 Q1 = 2023 Q17
제어문 break, continue ⭐ 2020 Q9
표준 입출력 stdin / stdout / stderr, gets → fgets ⭐ 2018 Q4, 2021 Q18
오버라이딩 / 오버로딩 재정의 vs 중복 정의 ⭐⭐ 2017 Q4 = 2024 Q3, (2016 Q5 Java 상속 출력)
정렬 / 트리 선택 정렬 중간 단계, 중위 순회 ⭐ 2020 Q7, 2025 Q16

 

 

키워드 박스 — 답안에 반드시 들어가야 할 단어

->            : 구조체 포인터의 멤버 접근 ( p->x == (*p).x )
free()        : malloc으로 할당한 메모리 해제 / 같은 주소를 두 번 free하면 이중 해제 오류
union         : 모든 멤버가 같은 메모리를 공유 (크기 = 가장 큰 멤버)
%X / %x       : 16진수 대문자 / 소문자
break         : 반복 즉시 종료 / continue : 이번 회차만 건너뜀
overriding    : 상속받은 메서드 재정의 / overloading : 같은 이름, 다른 매개변수

서식 문자와 출력 결과 계산 ⭐⭐⭐

기출 (2017 Q11 = 2021 Q8) 다음 C 코드의 실행 결과를 적으시오.

(printf의 %X로 10진수 15를 출력하는 코드)
→ F

서식 의미 예
%d 부호 있는 10진수 -1 → -1
%u 부호 없는 10진수  
%x 16진수 소문자 255 → ff
%X 16진수 대문자 255 → FF
%o 8진수 8 → 10
%c / %s 문자 / 문자열  
%p 포인터 주소  

위 표의 예시값은 컴파일해서 확인한 결과예요(%X 255 → FF, %o 8 → 10).

 

⚠️ 함정: 대소문자! %X면 F, %x면 f 입니다. 문제 코드의 서식 문자를 먼저 보세요.

 

삼항 연산자 계산

기출 (2021 Q13) 다음 C 코드의 출력 결과는?

(a = 31, b = 27, c = 19, 식: ((a = (a > b) ? a : b) ? a : c))
→ 31

1단계: (a > b) ? a : b  →  (31 > 27) ? 31 : 27  →  31
2단계: a = 31            (할당식의 값은 대입된 값 31)
3단계: (31) ? a : c      →  31은 0이 아니므로 참  →  a  →  31

규칙: 안쪽 조건부터 계산하고, 할당식의 값은 대입된 값이며, 0이 아니면 참이에요.


포인터와 구조체 ⭐⭐⭐

포인터 연산

기출 (2018 Q6) int data[] = {10, 20, 30, 40, 50}; int *s = data; 일 때 *(s+2)+10을 출력하면?
→ 40

s + 2     → &data[2] (int 2칸 이동)
*(s + 2)  → data[2] = 30
30 + 10   → 40

 

 

기출 (2018 Q9) int *s = malloc(sizeof(int)); *s = 10; printf("%d", *s); 의 출력은?
→ 10

표현 의미 위 배열 예
*(s+2) 2칸 뒤 원소의 값 30
*s+2 첫 원소 값에 2를 더함 12
*(s+2)+10 2칸 뒤 원소 값에 10을 더함 40

위 세 값은 직접 컴파일해서 확인했어요(30 / 12 / 40).

 

⚠️ 함정: *s+2와 *(s+2)는 우선순위가 달라 결과가 다릅니다. 괄호 위치를 꼭 확인하세요.

 

구조체 포인터 멤버 접근

기출 (2021 Q14 = 2022 Q5)

struct student *p = &s; 일 때 printf("%d %s %c", ( )) 의 빈칸에 들어갈 수 있는 것을 모두 고르시오.

보기 표현 판정
(A) p.number, p.name, p.grade ❌ 포인터에는 . 사용 불가
(B) p->number, p->name, p->grade ⭕
(C) (*p).number, (*p).name, (*p).grade ⭕
(D) (*p->number), (*p->name), (*p->grade) ❌

→ (B), (C)

struct student { int number; char name[20]; char grade; };
struct student s = {2024001, "홍길동", 'A'};
struct student *p = &s;
p->number    ==  (*p).number      /* 두 표현은 동일 */

동적 메모리: malloc / free ⭐⭐⭐

기출 (2018 Q2 = 2024 Q7) malloc()으로 할당받은 메모리를 해제하는 함수는?
→ free()

 

기출 (2023 Q8) 다음 C 코드에서 오류가 발생하는 부분을 찾고 이유를 설명하시오.

ptr1 = malloc(512);    /* 메모리 A 할당 */
ptr2 = malloc(512);    /* 메모리 B 할당 */
ptr2 = ptr1;           /* ptr2가 가리키던 B의 주소를 잃음 → 메모리 누수 */
free(ptr2);            /* A 해제 */
free(ptr1);            /* A를 다시 해제 → 이중 해제(Double Free) 오류 */

→ 정리본 답: 오류 행은 ptr2 = ptr1; 과 free(ptr1); (이중 해제), 그리고 ptr2 = ptr1; 때문에 B 주소를 잃어 메모리 누수도 발생

 

메모리 상태
처음  : ptr1 → [A]    ptr2 → [B]
대입  : ptr1 → [A]    ptr2 → [A]     [B]는 아무도 가리키지 않음 (누수)
free(ptr2) 후 : [A] 해제됨
free(ptr1)     : 이미 해제된 [A]를 또 해제 → 오류

 

⚠️ 함정: 이중 해제를 묻는 기출은 2023 Q8 입니다.

2018 Q2 = 2024 Q7은 "해제 함수 이름(free)"만 묻는 단답이에요.

정리 자료에 두 가지가 한꺼번에 묶여 있어서 헷갈리기 쉬워요.


공용체 (union) ⭐⭐

기출 (2017 Q1 = 2023 Q17) C 언어에서 공용체를 나타내는 키워드는?
→ union

구분 struct union
메모리 멤버마다 별도 공간 모든 멤버가 같은 공간 공유
크기 멤버 크기의 합 (+ 정렬 패딩) 가장 큰 멤버의 크기
값 모든 멤버 동시에 유효 마지막에 쓴 멤버만 유효
union  U { char c; int i; double d; };   /* sizeof = 8  (가장 큰 double) */
struct S { char c; int i; double d; };   /* sizeof = 16 (패딩 포함) */

위 크기(8 / 16)는 64비트 환경에서 직접 컴파일해 확인한 값이에요.
구조체 크기는 컴파일러·정렬 규칙에 따라 달라질 수 있습니다.


제어문과 표준 입출력 ⭐

break / continue

기출 (2020 Q9) for, while, do while 의 반복 과정을 중단시킬 수 있는 명령어는?
→ break

명령 동작
break 반복문을 즉시 종료
continue 현재 회차만 건너뛰고 다음 회차 진행
return 함수 자체를 종료
for (int i = 0; i < 6; i++) {
    if (i == 2) continue;   /* 2만 건너뜀 */
    if (i == 4) break;      /* 4에서 종료 */
    printf("%d ", i);
}
/* 출력: 0 1 3  (직접 실행해 확인한 결과) */

 

표준 입출력

기출 (2018 Q4) ① 공백을 포함한 한 줄을 입력받는 함수, ② 문자 하나를 입력받는 함수는?
→ 정리본 답: ① gets() (→ fgets() 권장), ② getchar()

 

⚠️ 함정: gets()는 버퍼 오버플로 위험 때문에 C11 표준에서 삭제됐어요.

시험 정답은 gets로 적혀 있지만, fgets(str, size, stdin)가 안전한 방법이라는 점도 함께 기억해두세요.

 

 

기출 (2021 Q18) 표준 입출력 3가지 / 임베디드에서 표준 입출력을 구현하는 방식은?
→ stdin / stdout / stderr, 구현은 UART(직렬 통신) (4편의 UART와 연결)


객체지향: 오버라이딩 vs 오버로딩 ⭐⭐

기출 (2017 Q4 = 2024 Q3) 자식 클래스가 부모에게서 상속받은 메서드를 자신에 맞게 재정의하는 기법은?
→ 오버라이딩 (Overriding)

구분 오버라이딩 오버로딩
의미 상속받은 메서드를 재정의 같은 이름을 매개변수를 달리해 중복 정의
관계 부모 - 자식 (상속) 같은 클래스 안
시그니처 이름·매개변수·반환형 동일 매개변수 수/타입이 다름
결정 시점 실행 시(동적 바인딩) 컴파일 시

 

기출 (2016 Q5) Java 상속 코드의 출력 결과를 쓰는 문제

(정리본 답: p.x = 100 / Child Method / c.x = 200 / Child Method)

규칙: 필드(변수)  → 참조 변수의 "선언 타입"을 따름   (Parent p 이면 Parent의 x)
      메서드      → 실제 "인스턴스 타입"을 따름     (오버라이딩된 Child의 메서드 실행)

코드 본문은 정리본에 빠져 있어서, 위는 정리본이 설명한 규칙과 정답 위주로 정리했어요.


정렬과 트리 ⭐

기출 (2020 Q7) 3 2 1 5 4를 선택 정렬할 때 마지막 단계를 수행하기 직전의 결과는?
→ 1 2 3 5 4

선택 정렬(오름차순): 매 단계마다 남은 구간의 최솟값을 찾아 맨 앞과 교환 (n개면 n-1단계)
초기   : 3 2 1 5 4
1단계  : 1 2 3 5 4   (1과 3 교환)
2단계  : 1 2 3 5 4   (교환 없음)
3단계  : 1 2 3 5 4   (교환 없음)
4단계  : 1 2 3 4 5   (5와 4 교환 = 마지막 단계)
→ 마지막(4단계) 직전 = 1 2 3 5 4

위 단계별 결과는 직접 코드로 돌려 확인했어요.

 

기출 (2025 Q16) 이진 트리를 생성하고, 배열로 바꿔 정렬한 뒤 다시 트리로 만들어 중위 순회 결과를 출력하는 C 코드의 출력은?
→ 정리본 정답: 1234567

 

⚠️ 함정: 이 문항은 정리본에 코드가 생략돼 있어 답을 직접 검증할 수 없어요.

원리만 기억하세요 — 정렬된 이진 탐색 트리(BST)를 중위 순회하면 오름차순으로 나옵니다.

 

📌 개념 보강 — 트리 순회 (기출 직접 문항 없음)

전위(Pre-order)  : Root → Left → Right
중위(In-order)   : Left → Root → Right    ← BST에서는 오름차순
후위(Post-order) : Left → Right → Root

기출 문제 모음

Q. printf("%X", 15) 의 출력은? (2017·2021)
A. F

 

Q. int data[]={10,20,30,40,50}; int *s=data; 일 때 *(s+2)+10 은? (2018 Q6)
A. 40

 

Q. 구조체 포인터 p로 멤버에 접근하는 올바른 방법은? (2021·2022)
A. p->number, (*p).number

 

Q. malloc으로 할당한 메모리를 해제하는 함수는? (2018·2024)
A. free()

 

Q. ptr2 = ptr1; 후 free(ptr2); free(ptr1); 의 문제는? (2023 Q8)
A. 이중 해제(Double Free), 그리고 ptr2가 가리키던 메모리의 누수

 

Q. 모든 멤버가 같은 메모리를 공유하는 C의 키워드는? (2017·2023)
A. union

 

Q. 상속받은 메서드를 재정의하는 것은? (2017·2024)
A. 오버라이딩


💡 실무에서는?

  • 이중 해제·메모리 누수 — 임베디드에서는 메모리가 작아서 누수가 곧 장애로 이어져요.
    valgrind 같은 도구로 확인하거나, 할당·해제를 쌍으로 묶는 규칙을 코딩 표준에 넣는 게 일반적입니다.
  • gets() 사용 금지 — 보안 점검에서 가장 먼저 걸리는 함수예요.
    정보보안 쪽 시큐어 코딩 점검 항목(버퍼 오버플로)과 그대로 연결됩니다.
  • union — 레지스터 값을 비트 필드와 정수로 번갈아 보거나, 바이트 단위로 쪼개 볼 때 쓰입니다.
    다만 엔디안에 따라 결과가 달라질 수 있어 이식성에 주의해야 해요.
  • 출력 결과 계산 — 실무에서 코드 리뷰할 때 하는 "머릿속 실행"과 같은 훈련이에요.

핵심 정리

✅ %X = 16진수 대문자 (15 → F), %x = 소문자 (15 → f)
✅ *(s+2) = 2칸 뒤 값 / *s+2 = 첫 값 + 2 → 괄호 주의
✅ p->x == (*p).x  (p.x 는 오류)
✅ free() = malloc 해제 / 같은 주소 두 번 free = 이중 해제 (2023 Q8)
✅ union = 같은 메모리 공유, 크기는 가장 큰 멤버
✅ break = 즉시 종료 / continue = 이번 회차만 건너뜀
✅ gets 대신 fgets (표준 입출력은 stdin / stdout / stderr)
✅ 오버라이딩 = 재정의 / 오버로딩 = 매개변수만 다르게
✅ 선택 정렬은 n-1단계, BST 중위 순회는 오름차순

 

다음 편에서는 개발도구 및 테스팅 기법(출제기준 4-3)으로 이어갑니다!

 

궁금한 점은 댓글로 남겨주세요!

반응형
개인정보처리방침  |  블로그 소개