1. ft_printf

zinnnn37·2022년 9월 17일
0

42 SEOUL

목록 보기
2/9

0. Makefile

0.1. Implicit Rules

  • ARFLAGS는 프로그램의 매개변수로 사용자가 따로 정의하지 않을 시 기본값으로 rv를 가진다

Makefile 작성 과정에서 $(AR) = ar src로 정의하고 $(AR) $(ARFLAG)를 사용해서 rv파일이 나온 것.

0.2. addprefix & addsuffix

  • addprifix: 접두사를 붙이는 함수
    $(addprefix prefix, string)의 형태로 사용한다.
    - e.g. &(addprefix src/, ft_printf.c) => src/ft_printf.c
  • addsuffix: 접미사를 붙이는 함수
    $(addsuffix suffix, string)의 형태로 사용한다.
    - e.g. $(addsuffix .c, ft_printf) => ft_printf.c

0.3. -C 옵션

  • -C 옵션은 디렉토리 이동 옵션으로, make -C dir의 형태로 사용한다.

0.4 아카이브 파일을 이용해 컴파일하기

	gcc (실행파일) -L(디렉토리) -l(파일 이름)
    gcc main.c -L. -lftprintf
  • -L 옵션: 아카이브 파일이 위치하고 있는 디렉토리
  • -l 옵션: 아카이브 파일의 이름. 단, 아카이브 파일은 lib.a를 빼고 인식한다.
    - e.g. libftprintf.a -> ftprintf

⚠️ 공백 없이 이어쓰기⚠️


1. 가변인자

  • 함수 중에는 printf, scanf와 같이 매개변수의 개수가 정해져있지 않은 함수가 존재한다. 이렇게 매번 개수가 바뀌는 매개변수를 가변인자라고 한다.
  • 함수에서 가변인자를 정의할 대는 고정 매개변수가 한 개 이상 있어야 하며, 고정매개변수 뒤에 ...를 작성하여 매개변수의 개수가 정해지지 않았다는 표시를 한다.
// 반환값자료형 함수이름(자료형 고정매개변수, ...)의 형태
	int printf(const char *format, ...)

⚠️ ... 뒤에는 다른 매개변수를 지정할 수 없다 ⚠️

  • 가변인자 매크로는 stdarg.h에 정의되어 있다.

1.0. va_list

	va_list ap;
  • 함수로 전달되는 매개변수는 스택에 저장되고, 함수는 이 스택에서 인수를 꺼내어 쓴다. 이렇게 인수를 꺼내 읽을 때, 현재 읽고 있는 인수의 위치를 기억하기 위해 va_list형의 포인터 변수를 이용한다. 관습적으로 ap라는 이름을 사용한다.

1.1. va_start

가변인자의 첫 번째 인수를 가리키도록 초기화한다.

	va_start(ap, format);
  • 매개변수로 va_list 인스턴스(ap)마지막 고정 매개변수를 받는다. va_list의 주소값고정 매개변수의 크기를 더한 위치로 ap를 초기화시키기 때문에 마지막으로 입력된 고정 매개변수가 필요하다.

1.2. va_arg

ap 포인터가 위치한 부분의 데이터를 읽어 반환한다.

	va_arg(ap, 자료형);
  • 읽고자 하는 변수의 자료형에 따라 두 번째 매개변수를 다르게 주어야 한다. 예를 들어 현재 읽고자 하는 변수가 정수형인 경우 va_arg(ap, int)의 형태로 사용한다. ap 포인터가 입력받은 자료형의 크기만큼 이동하기 때문에 그 다음 변수에 접근할 수 있다.

1.3. va_end

va_list 타입을 null로 초기화한다.

	va_end(ap)

2. Byte Padding

한 번의 연산에 하나의 들어가게끔 클래스(구조체)에 바이트를 추가하여 CPU 접근에 부하를 덜어주는 것이다.

	class A
    {
    	char	c;
    	int		i;
	};
  • 단순하게 생각했을 때 두 변수의 총 크기는 1byte + 4byte = 5byte이다. 그러나 결과는 8byte이다.
  • 32bit CPU라고 가정할 때, CPU는 한 번에 32bit, 즉 4byte씩 가져와서 연산한다. 그렇기 때문에 1bytechar 변수 바로 뒤에 int 변수를 저장하는 경우, int 변수를 읽어들일 때 두 번의 연산이 필요하다.(char 뒤 3byte + 새로 시작하는 1byte) 때문에 char 변수 뒤에 3byte의 패딩을 추가하여 한 번의 연산으로 int 변수에 접근할 수 있도록 하는 것이다. 단, 메모리가 낭비된다.

  • va_arg의 원형을 살펴보면 _INTSIZEOF를 사용함을 알 수 있다. 이는 위와 같은 이유로 변수의 크기 단위가 4byte로 맞추어졌기 때문이다.
    -> 따라서 char 변수를 읽을 때 va_argchar가 아닌 int를 전달해야 한다.

0개의 댓글