[Printf 구현해보기]

......·2023년 7월 13일

42서울

목록 보기
4/7

주요 개념

  • 가변인자
  • 가변인자를 사용하기 위한 함수

Printf 구현을 위한 전체적인 그림

  • 가변인자를 처리해주기 위한 로직 작성
  • 각 가변인자의 자료구조에 따라서 처리해주는 함수 작성
    --> c(캐릭터), s(문자열), p(주소), d(정수), i(정수), u(자연수), x(16진수-소문자), X(16진수-대문자)
  • 각 자료형에 따라서 처리된 값을 표준출력(STDOUT)으로 출력
  • Printf의 자료형이 int형으로 반환값은 출력한 문자열의 전체적인 길이를 의미 -> 만약 int형의 범위를 벗어날경우, 아무것도 출력하지않고 -1값을 반환

가변인자

  • 인자를 받을 때, 정해진 자료형 및 개수가 정해지지 않은 인자를 뜻함
  • 개수 및 자료형이 정해지지 않은 인자

가변인자 처리 함수

va_start(va_list ap, last)

  • 가변인자를 사용하기 위해서 초기화의 개념을 가지고 있는 함수
  • 가변인자인 ap를 가장 처음으로 돌리고, last는 가변 인자 목록 전의 마지막 인자, 즉 호출 함수에서 타입을 알고 있는 마지막 인자의 이름

va_end(va_list ap)

  • va_start를 통해서 가변인자를 사용한 후, 가변인자의 사용 종료를 선언하는 함수

va_copy(va_list dest, va_list src)

  • 가변인자를 복사하기 위한 함수로, dest에 src의 인자를 복사해서 생성

va_arg(va_list ap, type)

  • va_start를 한 후, 직후에 사용하면 해당 시작지점의 가변인자를 뜻하고, va_arg가 한번 호출 된 후, 그 다음의 ap는 그 다음의 가변인자를 의미

  • type에는 각 가변인자에서 사용된 type를 명시해주면 되며, 일반적으로는 마지막에 사용된 가변인자의 type을 반환하게 됨

Printf 구현하기(플래그는 구현 X)

1. Printf의 프로토타입

int printf(const char *arr, ...)
-> 가변인자의 입력 전에 입력받은 배열이 있을경우, 그 배열이 arr을 의미
-> ... 이 부분이 가변인자를 사용한다는것을 의미

2.va_start함수 사용

va_list	temp;
va_start(temp, arr);
-> 가변인자의 자료형인 va_list를 시작위치로 옮겨주고, 마지막에 명시되었던 arr을 명시해줌으로
-> 가변인자를 사용하겠다는 의미

3. %기준 파싱

-> 예시. 만일 printf("hello everyone, my number is %d"); 입력이 들어오게 될 경우
-> %이전의 값은 그대로 출력을 해주고 %뒤의 문자에 따라서 타입을 결정해서 처리

4. 자료구조 별 처리함수

-> c의 경우, 문자 그대로 출력을 해주고 1의 길이를 반환
-> s의 경우, 문자열을 그대로 출력해주고, 문자열의 길이만큼 반환
-> p의 경우, 주소값을 출력해주며, 주소값의 길이를 반환
-> d, i의 경우, 정수값을 출력해주며, 정수의 길이를 반환
-> u의 경우, 자연수값을 출력해주며, 자연수의 길이를 반환
-> x의 경우, 16진수(소문자)를 출력해주며, 16진수의 길이를 반환
-> X의 경우, 16진수(대문자)를 출력해주며, 16진수의 길이를 반환

4-1. c 처리 로직

  • c = va_arg(temp, int)를 통해서 가변인자를 사용한 뒤, 다음 가변인자로 이동을 시켜줌
  • write(1, &c, 1); 등 처리함수를 통해서 출력한 후 1의 값 반환

4-2. s 처리 로직

  • *s = a_arg(temp, char *)를 통해서 가변인자를 사용한 뒤, 다음 가변인자로 이동
  • write(1, s, strlen(s)); 등 처리함수를 통해 출력한 후, strlen(s)를 반환

4-3. p 처리 로직

  • p의 경우 0x가 출력이 되기 때문에 먼저 0x를 출력을 시킨 후, 16진수를 출력
  • p = va_arg(temp, void *)를 통해서 가변인자 사용
  • 받은 값을 각 자릿수별로 16진수로 변환한 뒤 출력한 후, 16진수의 길이 + 2를 반환

4-4. d,i 처리 로직

  • d = va_arg(temp, int)를 통해 가변인자 사용
  • p와 비슷하게 각 자릿수 별로 10진수값 출력한 후, 정수값의 자릿수 반환

4-5. u 처리 로직

  • u = va_arg(temp, unsigned int)를 통해 가변인자 사용
  • d,i와 비슷하게 처리를 하나, 자연수이므로 부호를 신경쓰지 않음

4-6. x, X 처리로직

  • x = va_arg(temp, void *)를 통해 가변인자 사용
  • x는 소문자, X는 대문자로 16진수를 사용하며 나머지는 p와 비슷하게 처리

길이 합산 및 반환

  • 반환된 전체길이를 변수에 담아두고 이를 return 해주면 됨

0개의 댓글