ft_seoul
[c] ft_printf 과제

ft_print

  • 해당 과제는 stdio.h헤더에 존재하는 printf()함수를 구현하는 과제이다.
    • 최근 과제 업데이트로 인해 난이도가 많이 너프되었다...
      • 필수구현 항목이 서식지정자(csdiupxX%) + 플래그(-0.*)에서 서식지정자(csdiupxX%)로 줄어들었다. (나는 보너스항목인 -0.까지 구현했다.)

필요한 지식

c에서 가변인자 사용하는법

  • c언어에서는 함수를 선언 후 사용할 때 인자의 갯수와 타입을 맞추지 않으면 컴파일이 되지않는다. 가변인자는 인자의 갯수가 변할 수 있는 함수를 작성 위해 사용된다.
  • 함수에서 인자를 작성하는 부분에 ...파라미터를 사용하면 args뒤로 여러개의 인자를 받을 수 있다. 단, ... 뒤에는 아무것도 올 수 없다.
#include <stdio.h>
 
// args는 고정 매개변수
void printNumbers(int args, ...)
{
    printf("%d ", args);
}
 
int main()
{
    printNumbers(1, 10);
    printNumbers(2, 10, 20);
    printNumbers(3, 10, 20, 30);
    printNumbers(4, 10, 20, 30, 40);
 
    return 0;
}

javascript에서 rest parameter (opens in a new tab)...로 쓰이는 이유가 이런데에서 영향을 받아서이지 않을까?

헤더파일 <stdarg.h>

  • va_start(va_list arg_ptr, prev_param)

    • 가변인자를 받을 포인터가 첫번째 가변인자를 가르키도록 초기화한다.
  • va_arg(va_list arg_ptr, type)

    • 가변인수를 읽고, 전달받은 타입으로 변환하여 해당 값을 반환한다. 읽어진 arg_ptr은 다음 가변인수 위치로 주소값이 바뀌게된다.
    • 실제함수가 아닌 매크로함수이기 때문에 타입을 매개변수로 받을 수 있다.
  • va_end(va_list arg_ptr)

    • 실제로 내부에선 아무것도 하지않는다.
    • 이후 다른 플랫폼에서 중요한 역할을 할 수도 있어서 관례적으로 넣는다고 한다.
  • va_copy(va_list dest, va_list src)

    • destsrc를 복사한다. srcva_end로 초기화된 포인터이면 안된다.

printf 기본적인 사용법

  • 기본적인 서식지정자 (필수구현 항목만 구현하는 경우)

    // 정수
    printf("%u\n", 10);      //  10: 부호 없는 10진 정수
    printf("%d\n", -20);     // -20: 부호 있는 10진 정수
    printf("%i\n", -20);     // -20: 부호 있는 10진 정수
    printf("%x\n", 10);      //  a: 부호 있는 16진수 (소문자)
    printf("%X\n", 10);      //  A: 부호 있는 16진수 (대문자)
    // 문자, 문자열
    printf("%c\n", 'a');    // a: 문자
    printf("%s\n", "Hello, world!");    // Hello, world!: 문자열
    // 포인터
    int num1;
    void *ptr = &num1;
    printf("%p\n", ptr);    // 008BFB6C: 포인터의 메모리 주소
                            // 0x8bfb6c: 리눅스, OS X에서는 앞에 0x가 붙고, A~F는 소문자로 출력
                            // 높은 자릿수의 0은 생략
     
    // % 기호
    printf("%%\n");    // %: % 기호 출력
  • 플래그 (보너스하는 경우)

    • -
      • 결과를 왼쪽 정렬
      • 너비에 의존성을 갖는다. 의존성이 없으면 작동안함
    • {너비}
      • 출력할 너비를 결정함. 변수값의 출력물이 너비보다 큰 경우 아무일도 일어나지 않음
    • 0
      • 출력하고 남는 공간을 0으로 채움
    • .
      • .{n} n 만큼 출력
  • 기본 서식 지정자에 플래그, 폭, 정밀도, 길이를 조합해서 사용함

    • %[플래그][폭][.정밀도][길이]서식지정자

    • %[플래그(flag)][폭(width)][.정밀도][크기(length)]서식 문자(specifier)

      // %d의 출력 폭을 6칸으로 지정
      // 출력할 값의 길이가 폭보다 짧은 경우 공백으로 채워진다.
      printf("%6d\n", 20);
      printf("%6d\n", 2000);
       
          20
        2000
       
      // %d의 출력 폭을 6칸으로 지정, 남는 공간은 0으로 채움
      // 출력할 값의 길이가 폭보다 짧은 경우 0으로 채워진다.
      printf("%06d\n", 20);
      printf("%06d\n", 2000);
       
      000020
      002000
       
      // %d의 출력 폭을 6칸으로 지정, 좌측정렬
      printf("%[-6d]\n", 20);
      printf("%[-6d]\n", 2000);
       
      [20    ]
      [2000  ]
       
      // %d의 정밀도를 6으로 지정, 이때 정밀도에 의한 패딩으로 인해 남은 공간은 0으로 채워진다.
      printf("%.6d\n", 20);
      printf("%.6d\n", 2000);
       
      000020
      002000

참고한 링크들