Home ft_printf ② 배경 지식
Post
Cancel

ft_printf ② 배경 지식

printf 함수

printf manual

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

반환값

  • 출력한 문자수 (끝의 널문자 제외)
  • 음수값 (output or encoding error 발생 시)

서식 문자열

printf의 f는 formatted의 약자로, 서식화된 출력을 지원한다는 의미이다.

%[flag][width][.precision][length]specifier

  • format specifier (형식 지정자)

    서식 지정자설명
    d, i부호 있는 10진 정수
    u부호 없는 10진 정수
    o부호 없는 8진 정수
    x부호 없는 16진 정수(소문자)
    X부호 없는 16진 정수(대문자)
    f실수를 소수점으로 표기(소문자)
    F실수를 소수점으로 표기(대문자)
    e실수 지수 표기법 사용(소문자)
    E실수 지수 표기법 사용(대문자)
    g%f와 %e 중에서 짧은 것을 사용(소문자)
    G%F와 %E 중에서 짧은 것을 사용(대문자)
    a실수를 16진법으로 표기(소문자)
    A실수를 16진법으로 표기(대문자)
    c문자
    s문자열
    p포인터의 메모리 주소
    %% 기호 출력
    • 형식 지정자 d와 i의 차이점
      output 함수(ex. printf 등)에서는 차이 없다.
      input 함수(ex. scanf 등)에서는 받는 값이 다름
      • %d : signed 10진수 정수를 입력 받는다.
      • %i : 8진수/10진수/16진수 입력 받는다.

      예시 코드

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      
        #include <stdio.h>
              
        int main()
        {
        	int oct;
        	int dec;
        	int hex;
        	int num;
              
        	scanf("%i, %i, %i", &oct, &dec, &hex);
        	scanf("%d", &num);
              
        	printf("oct: %d, dec: %d, hex: %d, num: %d\n", oct, dec, hex, num);
        	printf("oct: %i, dec: %i, hex: %i, num: %i", oct, dec, hex, num);
        }
      

      출력결과

      1
      2
      3
      4
      
        011, 11, 0x11
        011
        oct: 9, dec: 11, hex: 17, num: 11
        oct: 9, dec: 11, hex: 17, num: 11
      

      보다시피 printf함수에서는 d와 i가 모두 같은 값인 10진수 값을 출력한다.
      하지만 scanf함수에서는 i로 지정한 부분은 input의 prefix에 따라 8진수(0), 10진수, 16진수(0x)로 다르게 입력받는다.

가변 인자 함수 (Variadic Function)

매개변수의 개수가 정해지지 않은채 사용하는 함수

1
2
3
반환값자료형 함수이름(자료형 고정매개변수, ...)
{
}

#include <stdarg.h> : 가변인자 매크로가 정의되어 있다.

가변인자 매크로 (Variadic Macro)

1
2
3
4
5
va_list   // 가변 인자 목록
va_start  // 가변 인자 시작 주소를 참조하는 포인터를 설정한다.
va_arg    // 가변인자의 값을 역참조하고, 자료형의 크기만큼 포인터를 밀어준다.
va_end    // 포인터를 NULL로 초기화한다.
va_copy   // 가변 인자 목록을 복사한다.

va_start: 첫번째 가변인자 주소로 ap를 설정한다.

va_arg: ap를 type에 맞게 읽고 다음 가변인자로 포인터를 움직여준다.

  • 가변 인자 포인터 ap를 인자로 넘기는 경우
    • void func(va_list *ap); : 매개변수를 포인터로 설정하고
    • func(&ap) : 주소를 넘겨줘야 한다.

예시 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdarg.h>

void print_num(int count, ...)
{
    va_list ap;
	int		num;
	int		i;

    va_start(ap, count);
    for (i = 1; i <= count; i++)
    {
        num = va_arg(ap, int);
		printf("%d x %d = %d\n", i, num, i * num);
    }
    va_end(ap);
}

int main(void)
{
    print_num(3, 2, 4, 6);
    return (0);
}

출력결과

1
2
3
1 x 2 = 2
2 x 4 = 8
3 x 6 = 18

Ref.

https://dojang.io/mod/page/view.php?id=736
https://kirkim.github.io/42seoul/2021/03/03/a_formatted.html
https://dojang.io/mod/page/view.php?id=577
https://hashcode.co.kr/questions/934/형식지정자-i-d-차이
https://jungpaeng.tistory.com/33
https://waintman.tistory.com/55
https://velog.io/@24siefil/ftprintf-Variadic-Arguments

This post is licensed under CC BY 4.0 by the author.

ft_printf ① Subject

ft_printf ③ 구현 과정 (Mandatory part)