[42서울] ft_printf

jabae·2022년 3월 30일
0

42Seoul

목록 보기
4/20

🤔 Flow

  1. 고정인자를 읽어 % 를 만나기 전까지 출력
  2. % 를 만나면 서식지정자에 따라 분기
  3. 해당 서식지정자의 자료형에 맞게 참조, 출력
  4. 리턴값은? 출력된 문자열의 총 길이(공백 개행 등 escape sequence 포함), 에러시 -1

🤓 고려사항

  • 기본자료형 중에서 int보다 작은 자료형은 성능문제로 int크기로 저장하고 받는다.( intchar )
  • 포인터 자료형의 크기(int*, double*, char*) :
    32비트 시스템 → 4 byte
    64비트 시스템 → 8 byte
  • undefined behavior :
    가변인자%의 개수가 일치하지 않을 경우 : printf는 개수가 일치하지 않아도 길이를 반환하지만 나는 컴파일러에서 잡아주는 것(warning)을 생각해서 -1을 리턴하도록 했다.
  • 서식지정자의 길이

    표 출처: https://dojang.io/mod/page/view.php?id=736

🛠 구현하기

☑️ %c

  • 정수를 문자로 출력
  • 자료형의 크기 : int

☑️ %s

  • 정수를 문자열로 출력
  • 자료형의 크기 : char *

☑️ %p

  • 포인터가 참조하고 있는 메모리의 주소값 출력( 0x + 12자리 / 64비트 시스템)
  • 자료형의 크기 : void *unsigned long long
    // unsigned 정수형중 void * 의 사이즈보다 큰 자료형으로 맞춰주도록 하자.
    // sizeof(void*) ? 운영체제에 맞게 받을 수 있도록 해주면 어떨까 생각했지만 위처럼 큰 자료형을 맞춰주는 게 더 간단할 것 같다.
  • 어떤 크기로 담을까?
     printf("%p", ap);        // 0x7ff7b12f4560 : 2 + 12
     printf("%p", (void *)-1); // 0xffffffffffffffff : 2 + 16
    • 일반적으로 8바이트(=64비트=16진수 16자리) 중 48비트만 사용해서 16진수 12자리가 출력됨 → 앞의 사용하지 않은 4자리는 0이므로 자동 생략
    • 음수는 8바이트 기준으로 언더플로우 (-1일 때 8바이트 맥스)가 되므로 16자리가 모두 채워짐
    → 따라서 16자리 배열에 담도록 하자.

☑️ %d %i

  • 부호 있는 10진 정수 출력
  • 자료형의 크기 : int
  • int 범위가 넘어가면 에러
    test.c:7:18: warning: format specifies type 'int' but the argument has type 'long' [-Wformat]
        printf("%i", 2147483648);
                ~~   ^~~~~~~~~~
                %li
    
    test.c:7:18: warning: format specifies type 'unsigned int' but the argument has type 'long' [-Wformat]
        printf("%u", -2147483649);
                ~~   ^~~~~~~~~~~
                %ld
  • diprintf 에서는 기본적으로 같으나, scanf에서 역할이 다름
    d : 10진수 입력받음
    i : 10/8/16진수 입력 받음

☑️ %u

  • 부호 없는 10진 정수 출력
  • 자료형의 크기 : unsigned intint (4바이트)
  • 서식지정자의 길이는 unsigned int지만 int값을 넘어가면 에러
    test.c:7:18: warning: format specifies type 'unsigned int' but the argument has type 'long' [-Wformat]
    printf("%u", 2147483648); // int 범위 +1
    				~~   ^~~~~~~~~~
    				%ld
  • 값이 음수일 경우를 고려해 long long으로 넘겨 받음
    printf("%u", -1); // 4294967295 (unsigned int 범위에서 언더플로우)

☑️ %x %X

  • 부호 없는 16진 정수로(소문자, 대문자) 출력
  • 자료형의 크기 : unsigned intint (4바이트)
  • 위와 마찬가지.
    test.c:7:18: warning: format specifies type 'unsigned int' but the argument has type 'long' [-Wformat]
    printf("%x", 2147483648);
    				~~   ^~~~~~~~~~
    				%lx

☑️ %%

  • '%' 출력
profile
it's me!:)

1개의 댓글

comment-user-thumbnail
2022년 4월 12일

이걸 하루만에 할 수 있을까요!? 우쒸...

답글 달기