printf 01

gfs0101·2022년 9월 19일
0

printf

목록 보기
1/2

01. 개요

c언어를 처음 배우면 마주하게되는 printf, 정말 편리한 함수라고 생각을 하였다
근데 그 편리함을 다 구현하려고 해보니 정말 머리가 미쳐버릴거 같다
이전까지의 과제들은 정리를 안하고 머리속으로만 구현할 수 있었지만 프엡부터는 도저히 불가능 할거 같아서 글로 정리를 해가며 구현해볼것이다


02. 함수의 사용법

printf
int printf("출력할 데이터와 서식", 변수1, 변수2 ....)
int printf(const char *format, ...)

첫번째 인자는 출력할 데이터를 넣는 공간이다
여기서 데이터를 넣을때 변수를 넣을수 있는데 "%()" %와 해당하는 옵션을 이용하여서 두번째 인자를 불러오는식으로 구성되어있다

데이터 안쪽에서 %의 개수가 들어오는만큼 변수의 개수도 늘어나게되는데 이런식으로 매개변수의 개수가 바뀌는것을 가변인자라고 합니다


03. 가변인자

가변인자
매번 함수에 들어가는 인수(argument)의 개수가 변하는 것을 가변 인자(가변 인수, variable argument)라고 합니다

반환값 자료형 함수명(자료형 고정매개변수, ...)

가변인자를 사용할때는 고정 매개변수가 한 개 이상 있어야 하며 고정 매개변수 뒤에 ...을 붙여 매개변수의 개수가 정해지지 않았다는 표시를 해줍니다

#include <stdio.h>
#include <stdarg.h> // va_list, va_start, va_arg, va_end 가 정의된 헤더

void	printNum(int args, ...)
{
	va_list	ap; // 가변 인자 목록 포인터

	va_start(ap, args);	// 가변 인자 목록 포인터 설정
	for (int i = 0; i < args; i++) // 가변 인자 개수만큼 반복
	{
		int	num = va_arg(ap, int); // int 크기만큼 가변 인자 목록 포인터에서 값을 가져옴
        						   // ap를 int 크기만큼 순방향으로 이동
		printf("%d ", num); // 가변 인자 값 출력
	}
	va_end(ap); // 가변 인자 목록 포인터를 NULL로 초기화

	printf("\n");
}

int main()
{
	printNum(1, 10);
	printNum(2, 10, 20);
	printNum(3, 10, 20, 30);
	printNum(4, 10, 20, 30, 40);
	return (0);
}

실행결과
10
10 20
10 20 30
10 20 30 40

가변인자를 사용하려면 strarg.h 헤더 파일에 정의된 매크로를 이용해야합니다

  • va_list : 가변 인자 목록. 가변 인자의 메모리 주소를 저장하는 포인터입니다.
  • va_start : 가변 인자를 가져올 수 있도록 포인터를 설정합니다.
  • va_arg : 가변 인자 포인터에서 특정 자료형 크기만큼 값을 가져옵니다.
  • va_end : 가변 인자 처리가 끝났을 때 포인터를 NULL로 초기화합니다.

va_list의 구조

va_start를 사용하여 가변 인자의 첫 번째 매개변수의 값으로 초기화 시키고

va_arg를 이용하여 가변 인자 포인터에서 특정 자료형 크기만큼 값을 가지고 온다
va_arg는 기본 자료형 인자들은 자료형 승격이 일어난다

  • 모든 정수형은 int 형으로
  • 모든 부동소수점은 double형으로

va_end를 사용하여 가변 인자 처리가 끝났을 때 포인터를 NULL로 초기화 시킨다


04. 서식 문자열 형식

%[flag][wide][.precision]type

원래는 정밀도 다음 크기를 지정하는 옵션도 있지만 과제에서 요구하는 옵션만 구현하려고 해서 제외시켰다

1) 플래그(flag)

플래그는 기본출력에서 여러가지 형태에 대해 좀 더 자세하게 지정할 수 있게 해준다.

flagexplanation
-결과를 좌측 정렬합니다
+출력값의 부호를 출력합니디(+, - 둘다 출력)
(공백)앞에 부호가 붙지 않는다면 한 칸을 띄어서 출력한다
#o, x, X 포맷으로 사용되면, # 플래그는 0(영)이 아닌 출력 값 앞에 0, 0x 또는 0X를 추가합니다
0오른쪽 정렬일 때 공백을 0으로 채운다

플래그는 여러게 동시에 적용할 수 있다

  • -0이 조합되면 0이 무시가 된다

2) 폭(width)

출력되는 데이터의 폭을 지정해준다. 출력값이 너비보다 작으면 공백으로 출력, 기본적으로 오른쪽 정렬

  • 출력할 값이 지정한 폭보다 크면 width 옵션은 무시
  • width에 음수가 할당되면 -플래그(좌측정렬)로 간주한다

3) 정밀도 (precision)

마침표 앞에 오는 음수가 아닌 십진 정수로, 출력될 문자의 수나 소수 자리의 수를 지정합니다.

  • 정수일 경우 출력될 숫자의 최솟값을 지정합니다 인수에서 숫자의 수가 정밀도 보다 작으면, 출력 값은 왼쪽이 0으로 채워집니다

  • 부동소수점은 다음에 출력될 자릿수를 지정합니다. 출력된 마지막 숫자는 반올림됩니다

  • 정밀도에 음수가 들어가면 무시한다

  • 정밀도가 0이거나 숫자 없이 표시되는 경우 1로 설정된다

4) 서식지정자(type)

type출력예시
c문자A
s문자열ABC
p포인터값(주소)0x10fbeb025
d부호있는 십진법 정수-111 or 111
i부호있는 십진법 정수(여기선 d랑 똑같음)111
u부호없는 십진법 정수111
o부호없는 8진수(-경우 오버플로우)35
x, X부호없는 16진수(소문자, 대문자)5a, 5A
%%출력%

5) 정리

typewideprecisionplusminuszeroblankcross
coxxoxxx
sooxoxxx
poxxoxxx
doooooox
uooxooxx
xooxoxxo
profile
열심히살자

0개의 댓글