포인터 기초 활용 및 표준 라이브러리 이해

기초 개념 복습: 포인터의 핵심 원리

C 언어에서 포인터는 메모리 주소를 저장하는 변수로, 직접 메모리에 접근할 수 있는 강력한 도구입니다. 이는 데이터의 위치를 참조하고, 동적 메모리 할당, 배열 처리, 함수 인자 전달 등 다양한 시나리오에서 필수적으로 사용됩니다.

다음은 간단한 포인터 사용 예제입니다:

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

int main(void) {
    int index;
    int *ptr;
    
    // 동적 메모리 할당
    ptr = (int*)malloc(sizeof(int));
    if (ptr == NULL) return 1;

    // 정적 배열 초기화
    int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 배열 요소 출력
    for (index = 0; index < 10; index++) {
        printf("%d ", numbers[index]);
    }

    // 할당된 메모리 해제
    free(ptr);
    
    // 프로그램 일시 정지 (디버깅용)
    system("pause");
    return 0;
}

주요 헤더 파일 설명

  • <stdlib.h>: 표준 라이브러리 헤더로, malloc, calloc, free 등의 동적 메모리 관리 함수와 rand, exit, system 등을 포함합니다. 또한 size_t, div_t 등의 타입과 EXIT_SUCCESS, RAND_MAX 같은 매크로도 정의되어 있습니다.

  • <string.h>: 문자열 조작 함수를 제공합니다. strcpy, strlen, strcmp, memset 등이 있으며, 이 헤더는 문자열을 char* 기반으로 다룹니다. 단, string이라는 타입은 존재하지 않습니다.

  • <stdio.h>: 표준 입력/출력 관련 함수를 포함합니다. printf, scanf, fopen, fclose 등이 있으며, 특히 printf는 내부적으로 포인터 기반의 가변 인자 처리 방식을 사용합니다.

  • <stdint.h>: C99부터 도입된 정밀한 정수 타입 지원을 위한 헤더입니다. 고정 크기 정수 타입을 선언할 수 있도록 합니다:

  • int8_t, uint16_t, int32_t 등: 정확한 비트 너비를 갖는 정수 타입.

  • INT8_MIN, UINT16_MAX, INT_FAST32_MAX 등: 각 타입의 최대/최소값을 나타내는 상수.

이 헤더는 하드웨어 레벨에서의 정확한 데이터 표현을 필요로 하는 시스템 프로그래밍에 매우 유용합니다.

printf의 내부 구현 원리

printf 함수는 내부적으로 가변 인자 리스트를 처리하며, 포인터를 통해 인자들을 순차적으로 읽습니다. 다음은 stdio.h 내부에서 정의된 함수 원형 예시입니다:

extern int printf(const char *format, ...);

이 함수는 __attribute__((__nonnull__(1))) 특성으로, 첫 번째 인자(포맷 문자열)가 반드시 유효한 포인터임을 보장합니다. 실제 출력은 fputc 함수를 통해 수행되며, 이 함수는 특정 스트림에 한 문자씩 쓰는 역할을 합니다.

예시:

int fputc(int ch, FILE *stream) {
    while (!(USART1->SR & 0x40));  // 전송 준비 완료 대기
    USART1->DR = (unsigned char)ch;
    return ch;
}

printf의 출력 장치 재지정 (예: UART)

STM32와 같은 마이크로컨트롤러 환경에서는 printf 출력을 기본 출력 장치(예: 디버그 콘솔)가 아닌 시리얼 통신(예: UART1)로 리디렉션할 수 있습니다. 이를 위해 fputc 함수를 오버라이드하여, printf 출력을 실시간으로 시리얼 포트로 전송하도록 구성합니다.

이 방법은 빌드 시 연결 단계에서 자동으로 적용되며, 코드 변경 없이도 모든 printf 호출이 새로운 출력 장치로 전달됩니다.

태그: 포인터 동적 메모리 stdio.h string.h stdlib.h

7월 13일 16:13에 게시됨