Search
πŸ–¨οΈ

ft_printf

Created
2021/03/22
tag
42μ„œμšΈ
42Seoul
printf
ft_printf
Variable Argument
Format Specifier

Subjects

1. ν”„λ‘œμ νŠΈ κ°œμš”

이번 ν”„λ‘œμ νŠΈλŠ” stdio.h κΈ°λ³Έ λΌμ΄λΈŒλŸ¬λ¦¬μ— ν¬ν•¨λ˜μ–΄ μžˆλŠ” printf ν•¨μˆ˜μ˜ 일뢀 κΈ°λŠ₯듀을 직접 κ΅¬ν˜„ν•˜λŠ” 것이닀.
printf의 fλŠ” formatted의 μ•½μžμ΄λ©°, μ„œμ‹ν™”λœ 좜λ ₯을 μ§€μ›ν•œλ‹€λŠ” μ˜λ―Έμ΄λ‹€.
printf의 λ§Žμ€ ν•„λ“œ μ€‘μ—μ„œ flag ν•„λ“œμ˜ -, 0, ., * 그리고 width 및 .precision ν•„λ“œ, type ν•„λ“œμ˜ c, s, p, d, i, u, x, X, %만 κ΅¬ν˜„ ν•˜λ©΄λœλ‹€.
μ‹€μ œ printf의 ν•¨μˆ˜μ™€ λΉ„κ΅ν•˜λ©΄μ„œ κ΅¬ν˜„ν•œλ‹€.

2. Printf Format Placeholder

printf ν•¨μˆ˜μ˜ 인자둜 μ£Όμ–΄μ§€λŠ” 일반적인 λ¬Έμžμ—΄μ€ 좜λ ₯ μŠ€νŠΈλ¦Όμ— κ·ΈλŒ€λ‘œ μ „λ‹¬λ˜μ–΄ 좜λ ₯을 ν•˜κ²Œ λ˜μ§€λ§Œ, %둜 μ‹œμž‘ν•˜λŠ” Format Tag(ν˜•μ‹ νƒœκ·Έ)λŠ” μΆ”κ°€ 인자λ₯Ό λ°›μ•„ 좜λ ₯ μŠ€νŠΈλ¦Όμ— μ–΄λ–»κ²Œ 좜λ ₯ν•΄μ•Ό 할지 κ°€μ΄λ“œλ₯Ό μ œκ³΅ν•œλ‹€. ν˜•μ‹ νƒœκ·ΈλŠ” %와 Format Specifier (μ„œμ‹ μ§€μ •μž)둜 κ΅¬μ„±λ˜μ–΄ μ„œμ‹ μ§€μ •μžμ— 따라 λ‹€μ–‘ν•œ 해석 방식을 λ‚˜νƒ€λ‚Έλ‹€.
μ•„λž˜ μ˜ˆμ‹œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄, %λ₯Ό μ œμ™Έν•œ λ¬Έμžμ—΄λ“€μ€ κ·ΈλŒ€λ‘œ 좜λ ₯λœλ‹€.
pritnf("Color %s, Number %d, Float %4.2f", "red", 123456, 3.14);
C
볡사

1) Printf Format Placeholder Syntax

printf ν•¨μˆ˜μ˜ Format Placeholder Syntax(μ„œμ‹ ν‘œκΈ° ꡬ문)은 %둜 μ‹œμž‘ν•˜λŠ” ν˜•μ‹ νƒœκ·Έλ‘œ ν‘œκΈ° 되며, κ·Έ ꡬ문은 μ•„λž˜μ™€ κ°™λ‹€.
%[parameter][flags][width][.precision][length]type
C
볡사
% 뒀에 λ‚˜νƒ€λ‚˜λŠ” μ„œμ‹ μ§€μ •μžλŠ” parameter, flags λ“± ν•„λ“œμ— λŒ€ν•œ λ‹€μ–‘ν•œ μ˜΅μ…˜μ„ λ°›κ³  type을 λ°›λŠ” ν˜•νƒœμ΄λ‹€. μ•„λž˜μ— ν•„λ“œμ— λŒ€ν•œ μ˜΅μ…˜λ“€μ˜ μ„€λͺ…을 ν™•μΈν•˜μž.

2) parameter (optional)

parameter ν•„λ“œλŠ” POSIXμ—μ„œμ˜ C μ–Έμ–΄μ—μ„œλ§Œ 이용 κ°€λŠ₯ν•˜κ³ , C99μ—μ„œμ˜ C μ–Έμ–΄μ—μ„œλŠ” 이용이 λΆˆκ°€λŠ₯ν•œ ν•„λ“œμ΄λ‹€. ν•„λ“œμ— 주어진 μ˜΅μ…˜ 값을 톡해 ν•¨μˆ˜ ν˜ΈμΆœμ— λ„˜κ²¨ 받은 μΈμžλ“€ 쀑 λ¬Έμžμ—΄μ„ μ œμ™Έν•œ 맀개 λ³€μˆ˜λ₯Ό μ‘°μ’…ν•  수 μžˆλ‹€. parameter의 값은 1λΆ€ν„° μ΄μš©ν•  수 μžˆλ‹€. 0λΆ€ν„° μ΄μš©ν•˜λ €κ³  ν•˜λ©΄ μ•„λž˜μ™€ 같은 였λ₯˜κ°€ λ°œμƒν•œλ‹€.
Search
[option]
Character
Description
nn은 숫자λ₯Ό μ˜λ―Έν•˜λ©°, λŒ€μ²΄ν•  맀개 λ³€μˆ˜μ˜ 번호λ₯Ό μ˜λ―Έν•œλ‹€. 제곡된 맀개 λ³€μˆ˜λ₯Ό n$꼴의 ν˜•νƒœλ‘œ λ‚˜νƒ€λ‚΄μ–΄, 맀개 λ³€μˆ˜λ₯Ό λ‹€λ₯Έ μˆœμ„œλ‘œ μ—¬λŸ¬ 번 좜λ ₯ν•  수 μžˆλ‹€.
μ•„λž˜μ˜ n$λ₯Ό μ‚¬μš©ν•œ μ˜ˆμ‹œλ₯Ό 보고 μ΄ν•΄ν•΄λ³΄μž.
#include <stdio.h> int main(void) { printf("%2$d %2$#x; %1$d %1$#x", 16, 17); return (0); }
C
볡사
μ½”λ“œλ₯Ό μ‹€ν–‰μ‹œν‚€λ©΄ μœ„μ™€ 같은 κ²°κ³Όκ°€ λ‚˜μ˜¨λ‹€.
μš°λ¦¬λŠ” 맀개 λ³€μˆ˜λ₯Ό 2개만 λ°›μ•˜μŒμ—λ„ 4개의 좜λ ₯을 λ§Œλ“€μ–΄ λ‚Ό 수 μžˆλ‹€. μœ„μ˜ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ μ•ž λΆ€λΆ„μ˜ %2$dμ—μ„œ $λΌλŠ” μ˜΅μ…˜μ„ μ΄μš©ν•΄μ„œ 2번째 맀개 λ³€μˆ˜λ₯Ό λ°›μ•„μ˜€κ² λ‹€κ³  ν‘œμ‹œν•œ 것이닀. κ·Έλž˜μ„œ μš°λ¦¬λŠ” 맀개 λ³€μˆ˜λ₯Ό 16, 17의 ν˜•νƒœλ‘œ λ°›μ•˜μ§€λ§Œ, λ‚˜μ€‘μ— 받은 맀개 λ³€μˆ˜λ₯Ό λ¨Όμ € μ‚¬μš©ν•˜λ“― μˆœμ„œμ— 상관없이 이 λ³€μˆ˜λ“€μ„ μ‚¬μš©ν•  수 μžˆλŠ” 것이닀. λ˜ν•œ ν• λ‹Ήλœ 맀개 λ³€μˆ˜μ— λŒ€ν•΄ μ€‘λ³΅μ‚¬μš©λ„ κ°€λŠ₯ν•˜λ‹€. n$ μ˜΅μ…˜μ„ μ΄μš©ν•˜μ—¬ 좜λ ₯ ν•  λ•Œ μ‚¬μš©ν•˜μ§€ μ•Šμ€ 맀개 λ³€μˆ˜κ°€ μžˆμ–΄μ„œ μ•ˆ λœλ‹€λŠ” 점을 μœ μ˜ν•΄μ•Ό ν•œλ‹€.

3) flags (optional)

λ‹€μ–‘ν•œ ν•„λ“œ 쀑 κ°€μž₯ μ•žμ— λ‚˜μ˜€λŠ” flagsλŠ”(parameter ν•„λ“œλŠ” POSIXμ—μ„œλ§Œ λ™μž‘ν•˜λ―€λ‘œ λŒ€μ²΄μ μœΌλ‘œ flags ν•„λ“œκ°€ κ°€μž₯ μ•žμ— λ‚˜μ˜¨λ‹€κ³  λ³Έλ‹€.) 좜λ ₯의 전체 λ°©ν–₯을 μ„€μ •ν•œλ‹€. μ„œμ‹ μ§€μ •μžμ— flags λ‹¨λ…μœΌλ‘œ μ‚¬μš©λ˜λŠ” κ²½μš°λ„ 있고 λ‹€λ₯Έ ν•„λ“œμ™€ ν•¨κ»˜ μ‚¬μš©λ˜λŠ” κ²½μš°λ„ μžˆλŠ”λ°, λ‹€λ₯Έ ν•„λ“œμ™€ ν•¨κ»˜ μ‚¬μš©λ˜λŠ” 경우 flags의 μ˜΅μ…˜μ΄ 영ν–₯을 λ°›λŠ” κ²½μš°κ°€ μžˆλ‹€. λ˜ν•œ flags ν•„λ“œμ—λŠ” μ—¬λŸ¬ μ˜΅μ…˜μ„ λ™μ‹œμ— μ‚¬μš©ν•  수 μžˆλ‹€.
Search
Character
Description
Default
쒌츑 정렬을 μˆ˜ν–‰ν•œλ‹€.
우츑 μ •λ ¬
μ–‘μˆ˜μΌ λ–„λŠ” +, 음수일 λ•ŒλŠ” - ν‘œμ‹œν•œλ‹€.
음수만 λΆ€ν˜Έν‘œμ‹œ
μ–‘μˆ˜μΌ λ•ŒλŠ” λΆ€ν˜Έλ₯Ό μƒλž΅ν•˜κ³  곡백으둜 ν‘œμ‹œν•œλ‹€. 단, 음수일 λ•ŒλŠ” -λ₯Ό ν‘œμ‹œν•œλ‹€.
width ν•„λ“œμ— 주어진 μ˜΅μ…˜μžλ¦¬μ— 맞좰 빈 μžλ¦¬μ— 0을 μΆ”κ°€ν•˜κ³ , - (minus)와 μ‚¬μš©λ  경우 쒌츑 정렬을 ν•˜κΈ° λ•Œλ¬Έμ— λ¬΄μ‹œν•˜κ²Œ λœλ‹€. type ν•„λ“œμ˜ 수λ₯Ό ν‘œκΈ°ν•˜λŠ” d, i, o, u, x, Xλ₯Ό μ‚¬μš©ν•  λ•Œ .preicison ν•„λ“œλ„ ν•¨κ»˜ 이용되면, 주어진 μ˜΅μ…˜λ§ŒνΌ 빈 자리λ₯Ό 0으둜 μ±„μš΄λ‹€.
μ •μˆ˜μ™€ μ§€μˆ˜μ— 천 λ‹¨μœ„ κ΅¬λΆ„μžλ₯Ό ν‘œμ‹œν•œλ‹€. ex) 1,000
각 진법과 ν˜•μ‹μ— 맞게 0, 0x, 0Xλ₯Ό μΆ”κ°€ν•œλ‹€. .precision ν•„λ“œμ˜ e, E, f, a, A μ˜΅μ…˜κ³Ό μ‚¬μš©λ  경우 μ†Œμˆ˜μ μ— 영ν–₯을 μ€€λ‹€. .preicison ν•„λ“œμ˜ g, G μ˜΅μ…˜λ„ λ§ˆμ°¬κ°€μ§€λ‘œ μ†Œμˆ˜μ μ— 영ν–₯을 μ£Όκ³ , 0이 μž˜λ¦¬λŠ” ν˜„μƒμ„ λ°©μ§€ν•œλ‹€. type ν•„λ“œμ˜ c, s, d, i, uμ˜΅μ…˜κ³Ό μ‚¬μš©λ˜λ©΄ #λ₯Ό λ¬΄μ‹œν•œλ‹€.

4) width (optional)

width ν•„λ“œλŠ” 단어 뜻 κ·ΈλŒ€λ‘œ 좜λ ₯ λ„ˆλΉ„λ₯Ό μ„€μ •ν•œλ‹€. .precision ν•„λ“œμ˜ μ˜΅μ…˜κ³Ό μ‚¬μš©λ˜λ©΄ μ˜΅μ…˜ 값을 κ³ λ €ν•˜μ—¬ λ„ˆλΉ„ 값을 μ μš©ν•œλ‹€. (.precisionμ—μ„œ μžμ„Ένžˆ μ‚΄νŽ΄λ³΄μž.)
Search
Character
Description
nn은 숫자λ₯Ό μ˜λ―Έν•˜λ©°, μ–‘μˆ˜λ§Œ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€. 음수λ₯Ό μ‚¬μš©ν•˜λ©΄ λΆ€ν˜Έ - λ₯Ό flags ν•„λ“œμ˜ - (minus)둜 μΈμ‹ν•œλ‹€.
λ„ˆλΉ„ 값을 인자둜 λ°›μ•„μ„œ μ‚¬μš©ν•œλ‹€. * (asterisk)에 할당될 인자둜 받은 값보닀 μ„œμ‹ μ§€μ •μžμ— 따라 λŒ€μΉ˜λ  인자둜 더 κΈ΄ 값이 λ“€μ–΄μ˜€λ©΄ μ›λž˜ 길이만큼 좜λ ₯ν•œλ‹€.
μ˜΅μ…˜μœΌλ‘œ μž…λ ₯ν•œ 숫자만큼 λ„ˆλΉ„λ₯Ό 가진닀. * 기호λ₯Ό μ‚¬μš©ν•˜λ©΄ 인자둜 λ„ˆλΉ„λ₯Ό μ£Όμ–΄μ•Ό ν•œλ‹€. μ•„λž˜μ˜ 두 μ½”λ“œλŠ” 같은 좜λ ₯을 λ‚˜νƒ€λ‚Έλ‹€.
printf("%*d", 5, 42); printf("%5d", 42);
C
볡사

λ„ˆλΉ„ κ°’ < 주어진 κ°’μ˜ 길이

#include <stdio.h> int main(void) { printf("%*d", 2, 100); return (0); }
C
볡사
μœ„ μ½”λ“œλŠ” 주어진 λ„ˆλΉ„ κ°’ 2λ₯Ό λ¬΄μ‹œν•˜κ³  μ›λž˜ κ°’ 100을 좜λ ₯ν•œλ‹€.

λ„ˆλΉ„ κ°’ β‰₯ 주어진 κ°’μ˜ 길이

#include <stdio.h> int main(void) { printf("%*d", 2, 1); return (0); }
C
볡사
반면 μœ„ μ½”λ“œλŠ” λ„ˆλΉ„ 값에 맞좰 우츑 정렬을 μˆ˜ν–‰ν•œλ‹€.

5) .precision (optional)

.precision은 좜λ ₯ν•˜λŠ” κ°’μ˜ 정확도 ν‘œκΈ°λ₯Ό μœ„ν•œ ν•„λ“œμ΄λ‹€. λ„ˆλΉ„λ₯Ό λ‚˜νƒ€λ‚΄λŠ” width ν•„λ“œ λ‹€μŒμœΌλ‘œ λ‚˜νƒ€λ‚˜λŠ” ν•„λ“œμ΄κΈ° λ•Œλ¬Έμ— ꡬ뢄을 μœ„ν•΄μ„œ .은 ν•„μˆ˜μ μœΌλ‘œ μš”κ΅¬λœλ‹€. λ‹¨λ…μœΌλ‘œ . 이 μ΄μš©λ˜κΈ°λ„ ν•˜λ©° .κ³Ό 숫자λ₯Ό μ‘°ν•©ν•˜μ—¬ μ‚¬μš©λ˜κΈ°λ„ ν•˜λŠ”λ°, 각 κ²½μš°μ—λŠ” λ°”λ‘œ 뒀에 μ΄μ–΄μ§€λŠ” type ν•„λ“œμ˜ μ˜΅μ…˜μ— λ”°λΌμ„œ 좜λ ₯이 바뀐닀. (μœ„μ—μ„œ 밝힌 것과 같이 width ν•„λ“œμ˜ 값에도 영ν–₯을 λ°›κΈ° λ•Œλ¬Έμ—, width둜 주어진 κ°’κ³Ό .precision에 주어진 값을 μœ μ˜ν•΄μ•Όν•˜κ³ , .precision 뒀에 주어진 type ν•„λ“œμ˜ μ˜΅μ…˜μ΄ 무엇인지에도 μœ μ˜ν•΄μ•Ό ν•œλ‹€.)
Search
ꡬ뢄
Character
Description
type
λ‹¨λ…μœΌλ‘œ .만 μ‚¬μš©λœ 경우λ₯Ό λ§ν•œλ‹€. μ•„λž˜λŠ” 단독 μ‚¬μš©λœ . 이후에 μ΄μ–΄μ§€λŠ” type μ˜΅μ…˜μ— λ”°λ₯Έ 좜λ ₯ μ„€λͺ…이닀.
c, p
정확도λ₯Ό λ¬΄μ‹œν•˜κ³ , type μ˜΅μ…˜μ— λ”°λ₯Έ 값을 좜λ ₯ν•œλ‹€.
d, i, o, u, x, X
flags ν•„λ“œλ‘œ 0이 주어지면, μ˜΅μ…˜ 0을 λ¬΄μ‹œν•˜κ³  μ²˜λ¦¬ν•œλ‹€.
f, e, E, g, G, a, A
μ†Œμˆ˜μ  μ•„λž˜λ₯Ό 좜λ ₯ν•˜μ§€ μ•ŠλŠ”λ‹€. λ§ˆμ§€λ§‰ μˆ«μžλŠ” λ°˜μ˜¬λ¦Όν•˜μ—¬ μ²˜λ¦¬ν•œλ‹€. (μ‹€μˆ˜ 좜λ ₯을 μœ„ν•œ type ν•„λ“œ μ˜΅μ…˜ κ°’μ˜ 정확도λ₯Ό 주지 μ•Šμ€ Default 역할은 μ†Œμˆ˜μ  μ΄ν•˜ 6μžλ¦¬κΉŒμ§€ 좜λ ₯이닀.)
s
λ¬Έμžμ—΄μ„ 좜λ ₯ν•˜μ§€ μ•ŠλŠ”λ‹€.
*s
좜λ ₯ν•  μ΅œλŒ€ 길이λ₯Ό 인자둜 λ„˜κ²¨ λ°›μ•„, ν•΄λ‹Ή 길이만큼 λ¬Έμžμ—΄μ„ 좜λ ₯ν•œλ‹€.
type
nn은 숫자λ₯Ό μ˜λ―Έν•˜λ©°, μ–‘μˆ˜λ§Œ μ‚¬μš©ν•  수 μžˆλ‹€. (음수λ₯Ό μ‚¬μš©ν•˜λ©΄ width의 μ˜΅μ…˜ 값을 λ¬΄μ‹œν•˜κ³ , .precision의 κ°’μœΌλ‘œ λ“€μ–΄μ˜¨ 음수 nnλ§ŒνΌμ„ width의 μ˜΅μ…˜ κ°’μœΌλ‘œ μΈμ‹ν•œλ‹€. widthμ—μ„œμ˜ 음수 처리 방식을 λ”°λ₯΄λ―€λ‘œ 쒌츑 정렬을 μˆ˜ν–‰ν•œλ‹€.)
c
정확도λ₯Ό λ¬΄μ‹œν•˜κ³ , type μ˜΅μ…˜μ— 띠λ₯Έ 값을 좜λ ₯ν•œλ‹€.
d, i, o, u, x, X
좜λ ₯ν•  μ΅œλŒ€ 자릿수λ₯Ό μ§€μ •ν•˜κ²Œ λœλ‹€. μžλ¦Ώμˆ˜μ—μ„œ 좜λ ₯ν•  κ°’μ˜ 길이λ₯Ό λΊ€ 남은 곡간은 기본적으둜 0으둜 좜λ ₯ν•˜κ²Œ λœλ‹€. μ •μˆ˜ 값이 0으둜 λ“€μ–΄μ™”λŠ”λ° nn이 0이라면 좜λ ₯ 값이 μ—†λ‹€.
f, e, E, g, G, a, A
좜λ ₯ν•  μ†Œμˆ˜μ  자릿수λ₯Ό μ§€μ •ν•˜κ²Œ λœλ‹€. 좜λ ₯ν•  자리 μ§ν›„μ˜ 숫자λ₯Ό λ°˜μ˜¬λ¦Όν•˜μ—¬ 자릿수 내에 좜λ ₯ν•  수 μžˆλ„λ‘ ν•œλ‹€. μ‹€μˆ˜ κ°’μœΌλ‘œ 0.0이 λ“€μ–΄μ™”λŠ”λ° nn이 0이라면 0을 좜λ ₯ν•œλ‹€.
s
λ¬Έμžμ—΄μ—μ„œ 좜λ ₯ν•  μ΅œλŒ€ 길이λ₯Ό μ§€μ •ν•˜κ²Œ λœλ‹€. μ„€μ •ν•œ 길이가 λ¬Έμžμ—΄λ³΄λ‹€ 크닀면 μ›λž˜ 길이의 λ¬Έμžμ—΄μ„ 좜λ ₯ν•œλ‹€.
p
0x λ₯Ό μ œμ™Έν•˜κ³  총 길이λ₯Ό 주어진 nn에 맞좰 좜λ ₯ν•œλ‹€.
COUNT12

.이 λ‹¨λ…μœΌλ‘œ μ‚¬μš©λ˜μ–΄ type을 받은 μ˜ˆμ‹œ

c, p
d, i, o, u, x, X
f, e, E, g, G, a, A
s, *s

.에 숫자λ₯Ό λͺ…μ‹œν•˜μ—¬ type을 받은 μ˜ˆμ‹œ

c, p
d, i, o, u, x, X
f, e, E, g, G, a, A
s

6) length (optional)

length ν•„λ“œμ˜ 경우 type ν•„λ“œ μ•žμ— λΆ™μ–΄ μ„œμ‹μ— λŒ€ν•œ 자료의 ν˜•μ„ μ§€μ •ν•˜λ„λ‘ ν•˜κ³ , μ§€μ •ν•œ 자료의 ν˜•μ„ 톡해 μΈμžμ— λŒ€ν•œ μ μ ˆν•œ ν˜• λ³€ν™˜μ„ μˆ˜ν–‰ν•  수 μžˆλ„λ‘ ν•΄μ€€λ‹€.
Search
Character
d i
u o x X
f F e E g G a A
c
s
p
n
int
unsigned int
double
int
char *
void *
int *
signed char
unsigned char
signed char *
short int
unsigned short int
short int *
long int
unsigned long int
wint_t
wchar_t *
long int *
long long int
unsigned long long int
long long int *
intmax_t
uintmax_t
intmax_t *
size_t
size_t
size_t *
ptrdiff_t
ptrdiff_t
ptrdiff_t *
long double
COUNT9
μœ„μ˜ ν‘œμ— 주어진 것과 같이 type ν•„λ“œ μ•žμ— μ‚¬μš©λœ μ˜΅μ…˜μ— λ”°λΌμ„œ 받을 수 μžˆλŠ” 인자 νƒ€μž… (ν•΄μ„λ˜λŠ” νƒ€μž…)이 달라진닀. μ•„λž˜μ˜ 예λ₯Ό μ‚΄νŽ΄λ³΄μž.
type ν•„λ“œμ˜ d μ˜΅μ…˜ μ•žμ— hhλΌλŠ” length μ˜΅μ…˜μ΄ λΆ™μœΌλ©΄ signed char둜 μΈμ‹ν•˜κ²Œ λœλ‹€. ν•˜μ§€λ§Œ signed char λ²”μœ„ 내에 μžˆλŠ” 값을 printf의 κ°€λ³€ μΈμžμ— λ„£μ–΄μ£Όλ©΄ μ•„λž˜μ™€ 같이 κ²½κ³ κ°€ λ°œμƒν•˜λŠ” 것을 μ•Œ 수 μžˆλ‹€. (컴파일 μ‹œ κ²½κ³  ν—ˆμš©μ„ ν•˜μ§€ μ•ŠμœΌλ©΄ 컴파일이 λ˜μ§€ μ•ŠλŠ”λ‹€.)
μ΄λŠ” 였λ₯˜κ°€ λ°œμƒν•œ λΆ€λΆ„μ˜ λ¦¬ν„°λŸ΄μ„ μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ νƒ€μž…μ„ μΆ”μΈ‘ν•˜μ—¬ int둜 ν•΄μ„ν•˜κ³ , intλ₯Ό signed char에 ν• λ‹Ήν•˜λ € ν•΄μ„œ μƒκΈ°λŠ” 경고이닀. λ”°λΌμ„œ μ•„λž˜ μ½”λ“œλ₯Ό μ΄μš©ν•˜λ©΄ μ •μƒμ μœΌλ‘œ 좜λ ₯ 값을 확인할 수 μžˆλ‹€.
#include <stdio.h> int main(void) { char ch; ch = 99; printf("%3.2hhd", ch); return (0); }
C
볡사
length의 λ‚˜λ¨Έμ§€ μ˜΅μ…˜λ“€ μ—­μ‹œ μœ„μ™€ 같이 μž‘μš©ν•˜κ²Œ λœλ‹€. 주어진 각 νƒ€μž…μ— λŒ€ν•΄ 이해가 μ•ˆ κ°€λŠ” 것이 μžˆλ‹€λ©΄ λ³„λ„λ‘œ 찾아보도둝 ν•˜μž. (intmax_t, uintmax_t, ptrdiff_t λ“±)

7) type (required)

ν˜•μ‹ λ¬Έμžμ—΄μ—λŠ” 일반 λ¬Έμžμ—΄μ„ ν¬ν•¨ν•˜μ—¬ μ—¬λŸ¬ ν˜•μ‹ νƒœκ·Έλ“€λ‘œ 이뀄져 있으며, ν˜•μ‹ νƒœκ·ΈλŠ” %와 μ„œμ‹ μ§€μ •μžλ‘œ κ΅¬μ„±λœλ‹€. %λ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ ν•„λ“œλ“€μ„ λͺ¨λ‘ ν¬ν•¨ν•˜μ—¬ μ„œμ‹ μ§€μ •μžλΌκ³  ν•˜λŠ”λ°, type ν•„λ“œλŠ” %와 λ”λΆˆμ–΄ ν˜•μ‹ νƒœκ·Έμ— μ—†μ–΄μ„œλŠ” μ•ˆ λ˜λŠ” ν•„λ“œμ΄λ―€λ‘œ type ν•„λ“œλ₯Ό μ„œμ‹ μ§€μ •μžλ‘œ 보기도 ν•œλ‹€.
printf둜 좜λ ₯ν•  μ–΄λ–€ 값이 μ£Όμ–΄μ‘Œμ„ λ•Œ, type ν•„λ“œμ— 주어진 μ˜΅μ…˜μ— λ”°λΌμ„œ κ·Έ 값을 μ–΄λ–»κ²Œ 해석할지 달라진닀.
μ •μˆ˜λ₯Ό 좜λ ₯ν•  λ•ŒλŠ” %d둜, μ‹€μˆ˜λ₯Ό 좜λ ₯ν•  λ•ŒλŠ” %f둜 좜λ ₯을 ν–ˆλ˜ κΈ°μ–΅ 덕에 type ν•„λ“œλŠ” 자료의 νƒ€μž…κ³Ό 관련이 μžˆλ‹€κ³  μƒκ°ν•˜λŠ” κ²½μš°κ°€ λ§Žλ‹€. ν•˜μ§€λ§Œ length ν•„λ“œμ— λŒ€ν•œ μ„€λͺ…을 ν†΅ν•΄μ„œ μ•Œ 수 μžˆλ“―μ΄ 자료의 νƒ€μž…μ€ length ν•„λ“œμ™€ 관련이 μžˆλ‹€. length ν•„λ“œλ₯Ό λΉ„μ›Œλ‘κ³  %d, %fλ₯Ό μ΄μš©ν–ˆμŒμ—λ„ μ •μˆ˜, μ‹€μˆ˜λ₯Ό νƒ€μž…μ— 따라 μ œλŒ€λ‘œ 좜λ ₯ν•  수 μžˆλŠ” μ΄μœ λŠ” type ν•„λ“œ μ•žμ— length μ˜΅μ…˜μ΄ 주어지지 μ•Šμ„ κ²½μš°μ— 각 type μ˜΅μ…˜μ— λŒ€ν•œ κΈ°λ³Έ μ„€μ • κ°’μœΌλ‘œ κ·Έ ν˜•μ‹μ„ ν•΄μ„ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. 이λ₯Ό 톡해 μ•Œ 수 μžˆλŠ” 것은 type ν•„λ“œλŠ” 자료의 νƒ€μž…μ— λŒ€ν•œ 해석이 μ•„λ‹ˆλΌ 좜λ ₯ ν˜•μ‹μ— λŒ€ν•œ 해석을 μˆ˜ν–‰ν•œλ‹€λŠ” 것이닀.
예λ₯Ό λ“€μ–΄, 10μ΄λΌλŠ” 값을 10μ§„μˆ˜λ‘œ ν•΄μ„ν•˜λ©΄ 10, 8μ§„μˆ˜λ‘œ ν•΄μ„ν•˜λ©΄ 012, 16μ§„μˆ˜λ‘œ ν•΄μ„ν•˜λ©΄ 0xA와 같은데 이와 같이 ν•΄μ„ν•˜μ—¬ 좜λ ₯ν•˜λŠ” 것을 printf의 type ν•„λ“œκ°€ 도와쀀닀.
Search
Character
Description
Abbreviation
λΆ€ν˜Έ μžˆλŠ” 10진 μ •μˆ˜λ‘œ 해석
Signed Decimal Integer
λΆ€ν˜Έ μžˆλŠ” 10진 μ •μˆ˜λ‘œ 해석
Signed Decimal Integer
λΆ€ν˜Έ μ—†λŠ” 10진 μ •μˆ˜λ‘œ 해석
Signed Decimal Integer
λΆ€ν˜Έ μ—†λŠ” 8진 μ •μˆ˜λ‘œ 해석
Unsigned Octal
λΆ€ν˜Έ μ—†λŠ” 16진 μ •μˆ˜λ‘œ 해석 (μ†Œλ¬Έμž)
Unsigned Hexadecimal Integer (Lowercase)
λΆ€ν˜Έ μ—†λŠ” 16진 μ •μˆ˜λ‘œ 해석(λŒ€λ¬Έμž)
Unsigned Hexadecimal Integer (Uppercase)
μ‹€μˆ˜λ₯Ό 10μ§„μˆ˜ ν‘œκΈ°λ²•μ„ μ‚¬μš©ν•˜μ—¬ 해석 (μ†Œλ¬Έμž)
Decimal Floating Point (Lowercase)
μ‹€μˆ˜λ₯Ό 10μ§„μˆ˜ ν‘œκΈ°λ²•μ„ μ‚¬μš©ν•˜μ—¬ 해석 (λŒ€λ¬Έμž)
Decimal Floating Point (Uppercase)
μ‹€μˆ˜λ₯Ό 과학적 κΈ°μˆ˜λ²•μ„ μ‚¬μš©ν•˜μ—¬ 해석 (μ†Œλ¬Έμž)
Scientific Notation (Lowercase)
μ‹€μˆ˜λ₯Ό 과학적 κΈ°μˆ˜λ²•μ„ μ‚¬μš©ν•˜μ—¬ 해석 (λŒ€λ¬Έμž)
Scientific Notation (Uppercase)
f와 eΒ μ€‘μ—μ„œ 짧은 것을 μ‚¬μš© (μ†Œλ¬Έμž)
F와 EΒ μ€‘μ—μ„œ 짧은 것을 μ‚¬μš© (λŒ€λ¬Έμž)
μ‹€μˆ˜λ₯Ό 16μ§„λ²•μœΌλ‘œ ν‘œκΈ° (μ†Œλ¬Έμž)
Hexadecimal Floating Point (Lowercase)
μ‹€μˆ˜λ₯Ό 16μ§„λ²•μœΌλ‘œ ν‘œκΈ° (λŒ€λ¬Έμž)
Hexadecimal Floating Point (Uppercase)
μ •μˆ˜λ₯Ό 문자둜 해석
Character
μ •μˆ˜λ₯Ό λ¬Έμžμ—΄λ‘œ 해석
String of Characters
포인터가 μ°Έμ‘°ν•˜κ³  μžˆλŠ” λ©”λͺ¨λ¦¬μ˜ μ£Όμ†Œ κ°’ (8자리의 16μ§„μˆ˜)
Pointer Address
ν•΄λ‹Ή μ˜΅μ…˜ μ „κΉŒμ§€ printfλ₯Ό μ΄μš©ν•˜μ—¬ 좜λ ₯ν•œ 문자의 수λ₯Ό 인자둜 받은 λ³€μˆ˜μ— ν• λ‹Ή
Nothing Printed
%에 뒀이은 %λ₯Ό μ΄μš©ν•˜μ—¬ 좜λ ₯ μŠ€νŠΈλ¦Όμ— % 기호λ₯Ό 씀
%

d μ˜΅μ…˜κ³Ό i μ˜΅μ…˜μ˜ 차이

d μ˜΅μ…˜κ³Ό i μ˜΅μ…˜μ€ λͺ¨λ‘ Signed Decimal Integer둜 λΆ€ν˜ΈμžˆλŠ” 10진 μ •μˆ˜λ‘œ ν•΄μ„ν•œλ‹€. 두 μ˜΅μ…˜μ— λŒ€ν•΄μ„  printfλ₯Ό μ΄μš©ν•œ 좜λ ₯μ—μ„œλŠ” 차이가 μ—†λ‹€λŠ” 것을 μ•„λž˜ μ½”λ“œλ₯Ό 톡해 이해할 수 μžˆλ‹€.
#include <stdio.h> int main(void) { printf("%d\n", -42); printf("%d\n", -052); printf("%d\n", -0x2a); printf("%d\n", -0x2A); printf("%i\n", -42); printf("%i\n", -052); printf("%i\n", -0x2a); printf("%i\n", -0x2A); return (0); }
C
볡사
ν•˜μ§€λ§Œ 두 μ˜΅μ…˜μ€ scanfλ₯Ό μ΄μš©ν•œ μž…λ ₯μ—μ„œ 차이가 μžˆλ‹€. scanfμ—μ„œμ˜ d μ˜΅μ…˜μ€ λΆ€ν˜Έκ°€ μžˆλŠ” 10진 μ •μˆ˜λ₯Ό μž…λ ₯으둜 λ°›μ§€λ§Œ, scanfμ—μ„œμ˜ i μ˜΅μ…˜μ€ λΆ€ν˜Έκ°€ μžˆλŠ” 8진, 10진, 16진 μ •μˆ˜λ₯Ό μž…λ ₯으둜 받을 수 μžˆλ‹€. 단, i μ˜΅μ…˜μœΌλ‘œ μž…λ ₯을 받을 λ•ŒλŠ” νŠΉμ • ν˜•μ‹μ„ λ§žμΆ°μ£Όμ–΄μ•Ό ν•œλ‹€. μ•„λž˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•΄μ„œ λ™μΌν•œ 숫자λ₯Ό μ§„μˆ˜ ν˜•μ‹μ— λ§žμΆ°μ„œ 싀행해보면 d μ˜΅μ…˜κ³Ό i μ˜΅μ…˜μ˜ κ²°κ³Όκ°€ λ‹€λ₯Έ 것을 μ•Œ 수 μžˆλ‹€.
hyeonsokλ‹˜ κ°μ‚¬ν•©λ‹ˆλ‹€
#include <stdio.h> int main(void) { int num; printf("=== test %%d ===\n"); printf("10μ§„μˆ˜: "); scanf("%d", &num); printf("%d\n", num); printf("8μ§„μˆ˜ : "); scanf("%d", &num); printf("%d\n", num); printf("16μ§„μˆ˜: "); scanf("%d", &num); printf("%d\n", num); while (getchar() != '\n') continue ; printf("=== test %%i ===\n"); printf("10μ§„μˆ˜: "); scanf("%i", &num); printf("%i\n", num); printf("8μ§„μˆ˜ : "); scanf("%i", &num); printf("%i\n", num); printf("16μ§„μˆ˜: "); scanf("%i", &num); printf("%i\n", num); return (0); }
C
볡사

f μ˜΅μ…˜κ³Ό F μ˜΅μ…˜μ˜ 차이

f μ˜΅μ…˜κ³Ό F μ˜΅μ…˜μ€ ν• λ‹Ήλœ 값을 10μ§„μˆ˜ ν‘œκΈ°λ²•μ„ μ‚¬μš©ν•œ μ‹€μˆ˜λ‘œ ν•΄μ„ν•œλ‹€. 이에 λŒ€ν•΄ μ–΄μ°¨ν”Ό 숫자둜만 ν•΄μ„ν•˜κ²Œ λ˜μ–΄ μžˆλŠ”λ° μ˜΅μ…˜μ— λŒ€λ¬Έμž μ†Œλ¬Έμž ꡬ뢄을 λ‘˜ ν•„μš”κ°€ μžˆλŠ”μ§€ 의문이 λ“€ 수 μžˆλ‹€.
#include <stdio.h> int main(void) { printf("val : %f\n", -123.456); printf("val : %F\n", -123.456); return (0); }
C
볡사
μœ„ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ λŒ€λ¬Έμžμ™€ μ†Œλ¬Έμž μ˜΅μ…˜ ꡬ뢄 없이 λ™μΌν•œ 값이 좜λ ₯λ˜λŠ” 것을 λ³Ό 수 μžˆλŠ”λ°, κ·Έλ ‡λ‹€λ©΄ μ‹€μˆ˜μ— λŒ€ν•œ 10μ§„μˆ˜ ν‘œκΈ°λ₯Ό μ–΄μ§Έμ„œ f와 F둜 ꡬ뢄을 ν•΄λ‘μ—ˆμ„κΉŒ?
Linux Manual에 λ”°λ₯΄λ©΄ μ•„λž˜μ™€ 같이 두 μ˜΅μ…˜μ— λŒ€ν•œ 차이λ₯Ό μ„€λͺ…ν•΄λ‘” 것을 λ³Ό 수 μžˆλ‹€.
SUSv2 does not know about F and says that character string representations for infinity and NaN may be made available. SUSv3 adds a specification for F. The C99 standard specifies "[-]inf" or "[-]infinity" for infinity, and a string starting with "nan" for NaN, in the case of f conversion, and "[-]INF" or "[-]INFINITY" or "NAN" in the case of F conversion.
즉, ν‘œν˜„ κ°€λŠ₯ν•œ λ²”μœ„ λ°–μ˜ μˆ˜λ“€μ„ ν‘œν˜„ κ°€λŠ₯ν•œ μˆ˜λ“€λ‘œ μ •μ˜ν•˜μ—¬ ν•΄λ‹Ή 값을 좜λ ₯ν•˜λ € ν•  λ•Œ μ•ŒνŒŒλ²³μœΌλ‘œ 좜λ ₯ν•˜κΈ° λ•Œλ¬Έμ— μ˜΅μ…˜μ— λŒ€μ†Œλ¬Έμž 차이λ₯Ό λ‘” 것이라고 λ³Ό 수 μžˆλ‹€. 각 μ˜΅μ…˜μ„ μ΄μš©ν–ˆμ„ λ•ŒλŠ” μ•„λž˜μ™€ 같이 좜λ ₯되며, λŒ€κ΄„ν˜Έμ˜ μ˜λ―ΈλŠ” Optionalν•˜λ‹€λŠ” μ˜λ―Έμ΄λ‹€.
f μ˜΅μ…˜ : [βˆ’]inf[-] inf, [βˆ’]infinity[-] infinity, nannan
F μ˜΅μ…˜ : [βˆ’]INF[-]INF, [βˆ’]INFINITY[-]INFINITY, NANNAN
ν•˜μ§€λ§Œ Visual Studio와 Dev C++μ—μ„œλŠ” type ν•„λ“œμ˜ F μ˜΅μ…˜μ„ ν—ˆμš©ν•˜μ§€ μ•ŠλŠ”λ‹€κ³  ν•œλ‹€.
ν‘œν˜„ κ°€λŠ₯ λ²”μœ„ λ°–μ˜ μˆ˜λ“€ ν‘œν˜„ κ°€λŠ₯ λ²”μœ„ λ°–μ˜ μˆ˜λ“€μ€ 3가지가 μžˆλ‹€. 1. Denormalized Number 2. Infinity 3. NaN (Not a Number)
각 μˆ˜λ“€μ΄ μ™œ μ‘΄μž¬ν•˜λŠ”μ§€, μ–΄λ–»κ²Œ μ§€μˆ˜λΆ€μ™€ κ°€μˆ˜λΆ€λ₯Ό κ΅¬μ„±ν•˜μ—¬ λ©”λͺ¨λ¦¬μ— μ˜¬λΌκ°€λŠ”μ§€ κΆκΈˆν•˜λ‹€λ©΄ μ•„λž˜ 링크λ₯Ό μ°Έκ³ ν•˜μž.
과학적 κΈ°μˆ˜λ²• (Scientific Notation)μ΄λž€? 과학적 κΈ°μˆ˜λ²•μ΄λΌκ³  ν•˜λŠ” Scientific Notation은 μ§€μˆ˜ ν‘œκΈ°λ²• (Exponent Notation), κ°€μˆ˜ ν‘œκΈ°λ²• (Mantissa Notation)κ³Ό λ™μ˜μ–΄μ΄λ‹€. 10의 배수둜 λ§Žμ€ 0을 ν‘œκΈ° ν•΄μ•Όν•˜λŠ” 경우, κ·Έ ν‘œκΈ°κ°€ κΉŒλ‹€λ‘­κΈ° λ•Œλ¬Έμ— μ§€μˆ˜ (e)λ₯Ό μ‚¬μš©ν•˜μ—¬ ν‘œκΈ°ν•˜λŠ” 방식을 λ§ν•œλ‹€. ex) 100,000=1Γ—105=1.0e+05100,000 = 1 \times 10^5 = 1.0e+05

n μ˜΅μ…˜

n μ˜΅μ…˜μ˜ 경우 μ—¬λŸ¬ μ˜΅μ…˜ λ“€ 쀑에 κ°€μž₯ νŠΉμ΄ν•˜κ²Œ λ™μž‘ν•œλ‹€. n μ˜΅μ…˜μ€ n μ˜΅μ…˜μ΄ 적용되기 μ „κΉŒμ§€μ˜ 좜λ ₯된 문자 길이λ₯Ό μΈ‘μ •ν•˜μ—¬ κ°€λ³€ μΈμžμ— 주어진 λ³€μˆ˜μ— ν• λ‹Ήν•˜κ²Œ λœλ‹€. 즉, 일반적으둜 좜λ ₯에 μ‚¬μš©λ˜λŠ” μ˜΅μ…˜μ΄ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— λ‹€λ₯Έ μ˜΅μ…˜λ“€κ³Ό 차이가 μžˆμŒμ„ μ•Œ 수 μžˆλ‹€. μ•„λž˜μ˜ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄μž.
n μ˜΅μ…˜μ˜ κΈ°λ³Έ ν• λ‹Ή νƒ€μž…μ€ int *μ΄λ―€λ‘œ int λ³€μˆ˜μ˜ μ£Όμ†Œλ₯Ό λ„˜κΈ΄ 것을 확인할 수 μžˆλ‹€. 만일 λ‹€λ₯Έ νƒ€μž…μ˜ λ³€μˆ˜μ˜ μ£Όμ†Œλ₯Ό λ„˜κ²¨ ν• λ‹Ή λ°›κ³  μ‹Άλ‹€λ©΄, ν•΄μ„μ‹œν‚€κ³  싢은 length의 μ˜΅μ…˜μ„ n μ˜΅μ…˜ μ•žμ— ν‘œκΈ°ν•˜λ„λ‘ ν•œλ‹€.
#include <stdio.h> int main(void) { char len; printf("hello init 6!%hhn\n", &len); printf("length : %hhd", len); return (0); }
C
볡사

% 기호 좜λ ₯

ν˜•μ‹ λ¬Έμžμ—΄μ„ μ΄μš©ν•  λ•ŒλŠ” % 기호λ₯Ό μ΄μš©ν•˜μ—¬ ν˜•μ‹ νƒœκ·Έμ˜ μ‹œμž‘μž„μ„ μ•Œλ¦¬κ²Œ λœλ‹€. λ”°λΌμ„œ %λŠ” 일반적인 λ¬Έμžκ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ—, λ‹¨μˆœνžˆ printfλ₯Ό μ΄μš©ν•˜μ—¬ 기호λ₯Ό 좜λ ₯ν•˜λ € ν•˜λ©΄ μ•„λž˜μ™€ 같이 κ²½κ³  문ꡬλ₯Ό λ„μš°λ©΄μ„œ 컴파일이 λ˜μ§€ μ•ŠλŠ” 것을 λ³Ό 수 μžˆλ‹€.
일반적으둜 νŠΉμˆ˜ν•œ λ¬Έμžλ“€μ€ Escape Sequence라고 ν•˜μ—¬ \λ₯Ό μ΄μš©ν•˜μ—¬ 좜λ ₯ν•˜κ³€ ν•˜λŠ”λ°, % κΈ°ν˜Έλ„ \λ₯Ό μ΄μš©ν•˜μ—¬ 좜λ ₯ν•  수 μžˆλŠ”μ§€ ν™•μΈν•΄λ³΄μž. μ•„λž˜ 그림을 보면 μ—¬μ „νžˆ κ²½κ³  문ꡬλ₯Ό λ„μš°λ©΄μ„œ μ»΄νŒŒμΌμ„ λ§‰λŠ” λͺ¨μŠ΅μ„ 확인할 수 μžˆλ‹€.
% 기호λ₯Ό 좜λ ₯ν•˜κΈ° μœ„ν•΄μ„  \λ‘œλŠ” 좜λ ₯ν•  수 μ—†κ³  μ˜€λ‘œμ§€ % 기호λ₯Ό μ΄μš©ν•΄μ„œλ§Œ 좜λ ₯ν• μˆ˜ μžˆλ‹€. % 기호 좜λ ₯을 μœ„ν•΄ % 기호λ₯Ό μ΄μš©ν•œλ‹€λŠ” 것은 % 기호 μ•žμ—λ„ μ—¬λŸ¬ ν•„λ“œλ“€μ˜ λ‹€μ–‘ν•œ μ˜΅μ…˜μ„ μ‚¬μš©ν•  수 μžˆλ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€.
μ•„λž˜μ™€ 같이 flag의 μ˜΅μ…˜μœΌλ‘œ 0을 μ£Όκ³  width의 μ˜΅μ…˜μœΌλ‘œ 5λΌλŠ” 값을 μ£Όλ©΄ 5자리의 λ„ˆλΉ„λ‘œ %λ₯Ό 좜λ ₯ν•˜κ³  빈 μžλ¦¬λŠ” 0을 μ±„μš°λŠ” 것을 확인할 수 μžˆλ‹€.
#include <stdio.h> int main(void) { printf("%05%"); return (0); }
C
볡사
κ·Έλ ‡λ‹€λ©΄ 잠깐 μ†Œκ°œλ˜μ—ˆλ˜ \둜 좜λ ₯ν•  수 μžˆλŠ” λ¬Έμžλ“€μ€ μ–΄λ–€ λ¬Έμžλ“€μ΄ μžˆμ„κΉŒ? λ‹€μŒ ν•­λͺ©μ—μ„œ Escape Sequence에 λŒ€ν•΄ μ•Œμ•„λ³΄μž.

8) Escape sequence (Not a Field, String of Characters)

일반적으둜 νŠΉμˆ˜ν•œ λ¬Έμžλ“€μ€ Escape Sequence라고 ν•˜μ—¬ \λ₯Ό μ΄μš©ν•˜μ—¬ 좜λ ₯ν•˜κ²Œ λœλ‹€. \λ₯Ό ν¬ν•¨ν•œ λ¬ΈμžλŠ” printf ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ 좜λ ₯ν•  λ•Œ νŠΉμ • 문자λ₯Ό μ§€μΉ­ν•˜κ±°λ‚˜ νŠΉμ • κΈ°λŠ₯을 μˆ˜ν–‰ν•˜κ²Œ λœλ‹€.
Search
Character
Description
Representation
μž‘μ€ λ”°μ˜΄ν‘œ
'
큰 λ”°μ˜΄ν‘œ
"
λ¬ΌμŒν‘œ
?
λ°± μŠ¬λž˜μ‹œ
\
경고음 λ°œμƒ
Beep Sound
백 슀페이슀 (곡백 문자)
Backspace
쀄 λ°”κΏˆ (곡백 문자)
Newline
캐리지 리턴 (곡백 문자)
Carriage Return
μˆ˜ν‰ νƒ­ (곡백 문자)
Horizontal Tab
수직 νƒ­ (곡백 문자)
Vertical Tab
폼 ν”Όλ“œ (곡백 문자)
Form Feed

3. Variable Argument

1) Variable Argument (κ°€λ³€ 인자)λž€?

C μ–Έμ–΄μ—μ„œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ‹€λ³΄λ©΄ 맀개 λ³€μˆ˜μ˜ κ°œμˆ˜κ°€ μ •ν•΄μ Έμžˆμ§€ μ•Šμ€ ν•¨μˆ˜κ°€ μžˆλ‹€. μœ„μ—μ„œ 배운 printf도 상황에 따라 μ›ν•˜λŠ” 만큼의 인자λ₯Ό λ°›μ•„μ„œ μ‚¬μš©ν•  수 μžˆλ‹€. μ΄λ ‡κ²Œ 상황에 따라 ν•¨μˆ˜μ— 인자의 κ°œμˆ˜κ°€ λ‹€λ₯΄κ²Œ ν• λ‹Ήλ˜μ–΄λ„ μ²˜λ¦¬ν•  수 있게 ν•΄μ£ΌλŠ” 것이 κ°€λ³€ μΈμžμ΄λ‹€.
맀크둜 ν•¨μˆ˜λž€? 일반 ν•¨μˆ˜μ™€λŠ” 달리 λ‹¨μˆœ ν…μŠ€νŠΈ μΉ˜ν™˜λ§Œμ„ ν•΄μ€€λ‹€. λ”°λΌμ„œ μ—¬λŸ¬ λͺ…령문을 λ™μ‹œμ— 포함할 수 μžˆλ‹€. ν•¨μˆ˜ 호좜 ꡬ문과 λΉ„μŠ·ν•˜κ²Œ μž‘μ„±ν•˜λ”λΌλ„ μ‹€μ œλ‘œλŠ” ν•¨μˆ˜ ν˜ΈμΆœμ„ ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ ν•¨μˆ˜ 호좜 ꡬ문과 λΉ„κ΅ν–ˆμ„ λ•ŒλŠ” μ„±λŠ₯이 쑰금 더 쒋은 νŽΈμ΄λ‹€. ν•˜μ§€λ§Œ 맀크둜 ν•¨μˆ˜μ—μ„œλŠ” 인자의 νƒ€μž…μ„ κ³ λ €ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ˜λ„ν•˜μ§€ μ•Šμ€ μ—¬λŸ¬ 였λ₯˜κ°€ λ°œμƒν•  μˆ˜λ„ μžˆμ–΄ μ£Όμ˜ν•˜μ—¬ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

2) Variadic Function Format

κ°„λ‹¨ν•œ 예둜 κ°€λ³€ 인자λ₯Ό κ°€μ§€λŠ” ν•¨μˆ˜ μ›ν˜•κ³Ό 호좜 방법은 μ•„λž˜μ™€ κ°™λ‹€.
#include <stdarg.h> void function(int args, ...) { //fuction body } int main(void) { function(42, /* μ›ν•˜λŠ” 만큼 인자 μž…λ ₯ */); return (0); }
C
볡사
κ°€λ³€ 인자λ₯Ό ν¬ν•¨ν•œ ν•¨μˆ˜μ—λŠ” 두 μ’…λ₯˜μ˜ μΈμžκ°€ μš”κ΅¬λœλ‹€.
β€’
ν•„μˆ˜ 인자
β€’
선택적 인자
μ—¬κΈ°μ„œ λ§ν•œ 선택적 μΈμžλŠ” κ°€λ³€ 인자인데, κ°€λ³€ 인자λ₯Ό λ°›κΈ° μœ„ν•΄μ„  사전에 ν•„μˆ˜ μΈμžκ°€ 무쑰건 μš”κ΅¬λœλ‹€. 선택적 인자인 κ°€λ³€ μΈμžλŠ” 말 κ·ΈλŒ€λ‘œ 인자의 μˆ˜κ°€ μ •ν•΄μ Έ μžˆμ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 선택적 인자λ₯Ό λ¨Όμ € λ°›κ²Œ 되면 ν•¨μˆ˜μ˜ μ›ν˜•μ—μ„œ μ–΄λŠ 인자λ₯Ό ν•„μˆ˜ 인자둜 받은 것인지 μ•Œ 수 μ—†κΈ° λ•Œλ¬Έμ—, ν•„μˆ˜ 인자λ₯Ό λ¨Όμ € 받은 λ‹€μŒ 선택적 인자λ₯Ό λ°›λŠ” 것을 μ›μΉ™μœΌλ‘œ ν•œλ‹€.
선택적 μΈμžλŠ” ...으료 ν‘œμ‹œν•˜λ©° μœ„μ—μ„œ 밝힌 κ²ƒμ²˜λŸΌ ν•„μˆ˜ μΈμžμ™€ 선택적 인자의 μˆœμ„œκ°€ μ€‘μš”ν•˜κΈ° λ•Œλ¬Έμ— 선택적 인자 λ’€μ—λŠ” λ‹€λ₯Έ 맀개 λ³€μˆ˜λ₯Ό λ‘˜ 수 μ—†λ‹€. λ˜ν•œ ν•„μˆ˜ 인자 말 κ·ΈλŒ€λ‘œ κ°€λ³€ μΈμžκ°€ μ•„λ‹Œ ν•˜λ‚˜ μ΄μƒμ˜ 인자λ₯Ό λ°˜λ“œμ‹œ ν•„μš”λ‘œ ν•œλ‹€. μ•„λž˜ ν•¨μˆ˜μ˜ μ›ν˜•μ—μ„œ argκ°€ ν•„μˆ˜ 인자λ₯Ό μ˜λ―Έν•œλ‹€.
T function(T args, ...);
C
볡사
pritnf ν•¨μˆ˜μ˜ 경우λ₯Ό μ‚΄νŽ΄λ³΄μž.
printf("i'm %d years old.\n you are %d years old.\n", age1, age2);
C
볡사
이 κ²½μš°μ— ""(Double Qoute)둜 묢여진 λ¬Έμžμ—΄ 뢀뢄이 ν•„μˆ˜ μΈμžκ°€ λ˜λŠ” 것이고 age1 이후 age2κΉŒμ§€κ°€ λ°”λ‘œ 선택적 μΈμžκ°€ λ˜λŠ” 것이닀. 일반적으둜 ν•„μˆ˜ 인자둜 μ£Όμ–΄μ§€λŠ” μΈμžλ“€ 쀑 ν•˜λ‚˜λŠ” 선택적 인자λ₯Ό λͺ‡ 개 λ°›μ•˜λŠ”μ§€ λͺ…μ‹œν•˜μ—¬ 선택적 μΈμžλ“€μ—μ„œ 정지 μ‹ ν˜Έλ₯Ό 찾을 수 있게 ν•΄μ€€λ‹€.
κ°€λ³€ 인자λ₯Ό ν¬ν•¨ν•œ ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜κΈ° 전에 λ§€ν¬λ‘œμ— λŒ€ν•΄ λ¨Όμ € μ•Œμ•„λ³΄μž.

3) C Variadic Macros

C μ–Έμ–΄μ—μ„œ κ°€λ³€ 인자λ₯Ό κ°€μ§€λŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œ μ•„λž˜μ˜ 맀크둜λ₯Ό ν™œμš©ν•œλ‹€.
va_list // κ°€λ³€ 인자 λͺ©λ‘ va_start // κ°€λ³€ 인자λ₯Ό κ°€μ Έμ˜¬ 수 μžˆλ„λ‘ κ°€λ³€ 인자 μ‹œμž‘ μ£Όμ†Œ μ°Έμ‘°ν•˜λŠ” 포인터 μ„€μ • va_arg // κ°€λ³€ 인자λ₯Ό μ°Έμ‘°ν•˜λŠ” 포인터λ₯Ό 톡해 μ—­μ°Έμ‘° ν›„, ν•΄λ‹Ή λ°μ΄ν„°μ˜ 크기만큼 λ°€μ–΄ λ‹€μŒ 인자λ₯Ό μ°Έμ‘° va_end // κ°€λ³€ 인자λ₯Ό λͺ¨λ‘ 처리 ν›„, κ°€λ³€μΈμžλ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터λ₯Ό NULL둜 μ΄ˆκΈ°ν™” va_copy // κ°€λ³€ 인자 λͺ©λ‘μ„ 볡사
C
볡사
μœ„μ˜ λ§€ν¬λ‘œλ“€μ€ stdarg.h에 μ •μ˜λ˜μ–΄ 있기 λ•Œλ¬Έμ— 헀더λ₯Ό μΆ”κ°€ν•΄μ€˜μ•Ό μ΄μš©ν•  수 μžˆλ‹€.
μ΄μ „μ—λŠ” varargs.hκ°€ μ‚¬μš©λ˜μ—ˆμ§€λ§Œ 더이상 μ‚¬μš©μ„ ꢌμž₯ν•˜μ§€ μ•ŠλŠ”λ‹€. stdarg.hλŠ” C89 ν‘œμ€€λΆ€ν„° μΆ”κ°€λœ 헀더 νŒŒμΌμ΄λ‹€. C++μ—μ„œλŠ” cstdarg 헀더 파일이 μ‚¬μš©λœλ‹€.
#include <stdarg.h>
C
볡사
맀크둜λ₯Ό ν™œμš©ν•œ ν•¨μˆ˜λ₯Ό λ³΄λ©΄μ„œ κ°€λ³€ 인자λ₯Ό μ²˜λ¦¬ν•˜λŠ” 과정을 μ•Œμ•„λ³΄μž. μ•„λž˜μ— μž‘μ„±λœ sumAllμ΄λΌλŠ” ν•¨μˆ˜λŠ” 각 인자둜 λ“€μ–΄μ˜¨ μ •μˆ˜λ₯Ό λͺ¨λ‘ λ”ν•΄μ„œ κ²°κ³Όλ₯Ό 좜λ ₯ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.
#include <stdio.h> #include <stdarg.h> void sumAll(int args, ...) { int result; int tmp; // Part 1 va_list ap; result = 0; // Part 2 va_start(ap, args); for (int i = 0 ; i < args ; i++) { // Part 3 tmp = va_arg(ap, int); result += tmp; printf("%d", tmp); if (i == args - 1) break; printf(" + "); } printf(" = %d\n", result); // Part 4 va_end(ap); } int main(void) { sumAll(1, 10); sumAll(2, 10, 20); sumAll(3, 10, 20, 30); sumAll(4, 10, 20, 30, 40); sumAll(5, 10, 20, 30, 40, 50); return (0); }
C
볡사

Part 1: va_list

va_list ap;
C
볡사
κ°€λ³€ 인자 λͺ©λ‘λ₯Ό μ˜λ―Έν•˜λ©°, κ°€λ³€ 인자의 μ£Όμ†Œλ₯Ό 담을 수 μžˆλŠ” 포인터 λ³€μˆ˜μ΄λ‹€. κ΄€μŠ΅μ μœΌλ‘œ apλΌλŠ” 이름을 μ‚¬μš©ν•˜ν•œλ‹€. va_list의 νƒ€μž…μ€ typedefλ₯Ό 톡해 λ‚΄λΆ€μ μœΌλ‘œ char *둜 μ •μ˜λ˜μ–΄ μžˆλ‹€.

Part 2: va_start

va_start(ap, args);
C
볡사
va_startλŠ” μœ„μ—μ„œ μ„ μ–Έν•œ va_list νƒ€μž…μ˜ apλ₯Ό μ΄ˆκΈ°ν™” ν•΄μ£ΌλŠ” λ§€ν¬λ‘œμ΄λ‹€. va_startλ₯Ό 톡해 첫 번째 κ°€λ³€ 인자의 μ£Όμ†Œλ₯Ό apκ°€ μ°Έμ‘°ν•  수 μžˆλ„λ‘ λ§Œλ“€μ–΄μ€€λ‹€. μ •μ˜ λ˜μ–΄ μžˆλŠ” ν˜•νƒœλŠ” Microsoft Visual Studio κΈ°μ€€μœΌλ‘œ μ•„λž˜μ™€ κ°™λ‹€.
#define va_start(ap, v) ( (ap) = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
C
볡사
β€’
_ADDRESSOF(v) => &(v)
β€’
_INTSIZEOF(v) => ( (sizeof(v) + sizeof(v) - 1) & ~(sizeof(int) - 1) )
va_startλŠ” λ§ˆμ§€λ§‰ ν•„μˆ˜ 인자λ₯Ό 맀개 λ³€μˆ˜λ‘œ λ„£κΈ°λ§Œ ν•˜λ©΄ μžλ™μœΌλ‘œ κ°€λ³€ 인자의 μ‹œμž‘ μ£Όμ†Œλ₯Ό κ³„μ‚°ν•˜μ—¬ ap에 ν• λ‹Ήν•΄μ£ΌλŠ” 역할을 μˆ˜ν–‰ν•œλ‹€.
주어진 ν•„μˆ˜ μΈμžλ“€ 쀑 λ§ˆμ§€λ§‰ ν•„μˆ˜ 인자인 v의 크기λ₯Ό 재고, v의 μ‹œμž‘ μ£Όμ†Œμ—μ„œ v의 ν¬κΈ°λ§ŒνΌμ„ λ”ν•˜μ—¬ κ°€λ³€ 인자의 μ‹œμž‘ μ£Όμ†Œλ₯Ό ꡬ할 수 있게 ν•΄μ€€λ‹€. 그리고 κ°€λ³€ 인자의 μ‹œμž‘ μ£Όμ†Œλ₯Ό ap에 ν• λ‹Ήν•΄μ£ΌλŠ”λ°, 이 λͺ¨λ“  것듀이 va_startλ₯Ό 톡해 이뀄진닀.
v의 μ£Όμ†Œμ—μ„œ v의 크기λ₯Ό λ”ν•œ 것이 κ°€λ³€ 인자의 μ‹œμž‘ μ£Όμ†Œκ°€ λ˜λŠ” μ΄μœ λŠ”, ν•¨μˆ˜μ˜ ν˜ΈμΆœμ„ 톡해 λ„˜μ–΄μ˜¨ μΈμžλ“€μ€ 일련의 λ©”λͺ¨λ¦¬ 곡간을 μ°¨μ§€ν•˜λŠ” ν˜•νƒœλ₯Ό κ°–κΈ° 떄문이닀.

Part 3: va_arg

tmp = va_arg(ap, int);
C
볡사
va_argλŠ” va_listκ°€ μ°Έμ‘°ν•˜κ³  μžˆλŠ” νŠΉμ • κ°€λ³€ 인자λ₯Ό μ—­μ°Έμ‘°ν•˜κ³ , va_listλ‚΄μ˜ λ‹€μŒ κ°€λ³€ 인자λ₯Ό μ°Έμ‘°ν•˜λ„λ‘ ν•΄μ£ΌλŠ” λ§€ν¬λ‘œμ΄λ‹€. λ‹€μŒ κ°€λ³€ 인자λ₯Ό μ°Έμ‘°ν•˜λ„λ‘ λ§Œλ“€ λ•ŒλŠ” sizeof(type)만큼 λ‹€μŒμ— μžˆλŠ” 값을 μ°Έμ‘°ν•˜λ„λ‘ λ§Œλ“ λ‹€. μœ„μ˜ κ²½μš°λŠ” sizeof(int)만큼 λ‹€μŒμ— μžˆλŠ” 값을 μ°Έμ‘°ν•˜λ„λ‘ λ§Œλ“ λ‹€κ³  λ³΄λ©΄λœλ‹€.
μœ„ 과정은 μ•„λž˜μ™€ 같은 맀크둜λ₯Ό 톡해 이뀄진닀.
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
C
볡사
va_list의 κ°€λ³€ 인자λ₯Ό μ—­μ°Έμ‘°ν•˜κ³  λ‹€μŒ κ°€λ³€ 인자λ₯Ό 가리킀도둝 λ§Œλ“œλŠ” 연산은 μžμ„Ένžˆ 보면, λŒ€μž… μ—°μ‚°μžλ₯Ό 톡해 νŠΉμ • νƒ€μž…μ˜ 크기 만큼 λ¨Όμ € λ°€μ–΄μ„œ λ‹€μŒ κ°€λ³€ 인자λ₯Ό 가리킀도둝 λ§Œλ“€μ–΄ 놓은 ν›„ λ‹€μ‹œ κ·Έ νŠΉμ • νƒ€μž…μ˜ ν¬κΈ°λ§ŒνΌμ„ λΉΌμ„œ ν˜„μž¬ μ°Έμ‘°ν•˜κ³  κ°€λ³€ 인자λ₯Ό μ—­μ°Έμ‘° ν•  수 μžˆλ„λ‘ λ§Œλ“€μ–΄ λ‘” 것을 λ³Ό 수 μžˆλ‹€.
_INTSIZEOF(t)만큼 더해놓고 _INTSIZEOF(t)만큼 λ‹€μ‹œ λΊ€ 값을 t * νƒ€μž…μ˜ 포인터 λ³€μˆ˜λ₯Ό μ—­μ°Έμ‘°ν•œ 것을 λ³Ό 수 μžˆλ‹€.
for ꡬ문으둜 μž‘μ„±ν•œ λ°˜λ³΅λ¬Έμ„ 그림을 톡해 μ‚΄νŽ΄λ³΄μž.
char, short 의 κ²½μš°μ—λŠ” int둜 λŒ€μ‹  μ“°κ³ , float의 κ²½μš°μ—λŠ” double둜 λŒ€μ‹  μ“΄ 이후 ν˜• λ³€ν™˜μ„ ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€. 이처럼 μˆ˜ν–‰ν•˜λŠ” μ΄μœ λŠ” λ©”λͺ¨λ¦¬μ— νŠΉμ • 값이 쓰일 λ•ŒλŠ” μ£Όμ†Œ 체계 λ‹¨μœ„λ‘œ 기둝을 ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. 이λ₯Ό 톡해 Byte Padding νš¨κ³Όκ°€ μΌμ–΄λ‚˜μ„œ 32 λΉ„νŠΈ μ£Όμ†Œ 체계λ₯Ό κΈ°μ€€μœΌλ‘œ 4 λ°”μ΄νŠΈ μ•„λž˜μ˜ νƒ€μž…λ“€μ€ 4 λ°”μ΄νŠΈμΈ int둜 처리 ν›„, 각자의 νƒ€μž…μœΌλ‘œ ν˜• λ³€ν™˜ ν•˜μ—¬ 값을 μ½μ–΄λ‚΄λŠ” 것이닀. ex) char ch = (char)va_arg(ap, int);

Part 4: va_end

va_end(ap);
C
볡사
κ°€λ³€ 인자 λͺ©λ‘μ„ μ§€μΉ­ν•˜λŠ” va_list νƒ€μž…μ˜ 포인터 λ³€μˆ˜λ₯Ό NULL을 ν• λ‹Ήν•˜λ©΄μ„œ κ°€λ³€ 인자 μ‚¬μš©μ˜ 끝낼 λ•Œ μ‚¬μš©ν•œλ‹€. μ•„λž˜ 맀크둜λ₯Ό 보면 va_list νƒ€μž…μœΌλ‘œ ν˜• λ³€ν™˜ ν›„ 0을 λ„£μ–΄μ£ΌλŠ” 것을 λ³Ό μˆ˜μžˆλ‹€. μ—¬κΈ°μ„œμ˜ 0은 NULL을 μ˜λ―Έν•˜λŠ”λ°, va_argλ₯Ό μ‚¬μš©ν•˜μ—¬ νŠΉμ • λ©”λͺ¨λ¦¬ 곡간을 μ°Έμ‘°ν•˜κ³  μžˆλŠ” 포인터에 NULL을 ν• λ‹Ήν•˜μ—¬ μ°Έμ‘°ν•˜λŠ” 곡간이 없도둝 λ§Œλ“ λ‹€.
#define va_end(ap) ( ap = (va_list)0 )
C
볡사
μœ„ λ§€ν¬λ‘œλŠ” μ‹€μ œλ‘œ 없어도 ν”„λ‘œκ·Έλž¨μ— 지μž₯이 μ—†λ‹€. 인텔 κ³„μ—΄μ˜ CPUμ—μ„œλŠ” va_endκ°€ 아무 일도 ν•˜μ§€ μ•ŠλŠ”λ‹€κ³  ν•œλ‹€. ν•˜μ§€λ§Œ λ‹€λ₯Έ ν”Œλž«νΌκ³Όμ˜ ν˜Έν™˜μ„±μ—μ„œ μ€‘μš”ν•œ 역할을 ν•  수 μžˆμœΌλ―€λ‘œ κ΄€λ‘€μ μœΌλ‘œ λ„£μ–΄μ€€λ‹€. λ˜ν•œ ν”„λ‘œκ·Έλž˜λ°μ„ ν•˜λ©΄μ„œ 이미 μ‚¬μš©μ΄ λλ‚œ va_listλ₯Ό μ‚¬μš©ν•˜μ—¬λ„ μ°Έμ‘°ν•˜λŠ” 것이 없도둝 μ•ˆμ „μ„±μ— κΈ°μ—¬ν•˜κΈ°λ„ ν•œλ‹€.

Bonus: va_copy

va_copy(va_list dest, va_list src);
C
볡사
va_copyλŠ” ν˜„μž¬ μœ„μΉ˜λ₯Ό μ €μž₯ν•΄μ•Ό ν•˜λŠ” μƒν™©μ—μ„œ μ‚¬μš©ν•œλ‹€. 예λ₯Όλ“€μ–΄ 루프λ₯Ό λŒλ©΄μ„œ 포인터가 계속 μ „μ§„ν•˜κ³  μžˆλŠ” μƒν™©μ—μ„œ ν•΄λ‹Ή μœ„μΉ˜λ₯Ό μ €μž₯ν•΄μ•Ό ν•  κ²½μš°κ°€ 생기면 va_copyλ₯Ό ν™œμš©ν•΄μ„œ ν•΄λ‹Ή μœ„μΉ˜λ₯Ό μ €μž₯ν•΄λ‘”λ‹€.

Bonus: Without Macros

λ§€ν¬λ‘œλŠ” μ „μ²˜λ¦¬κΈ°μ— μ˜ν•΄ 컴파일 μ‹œμ  직전에 ν…μŠ€νŠΈ μΉ˜ν™˜μœΌλ‘œ μ²˜λ¦¬λœλ‹€. κ·Έλ ‡λ‹€λ©΄ κ°€λ³€ 인자λ₯Ό μœ„ν•΄ κ΅¬ν˜„λœ λ§€ν¬λ‘œλ“€μ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³ λ„ κ°€λ³€ 인자λ₯Ό ν™œμš©ν•œ ν•¨μˆ˜μ²˜λŸΌ λ§Œλ“€ 수 μžˆμ§€ μ•Šμ„κΉŒ?
μœ„μ—μ„œ κ°€λ³€ μΈμžμ™€ κ΄€λ ¨λœ λͺ¨λ“  λ§€ν¬λ‘œλ“€μ˜ ν˜•νƒœλ₯Ό μ‚΄νŽ΄λ³΄μ•˜λ‹€. 이에 따라 맀크둜λ₯Ό μ΄μš©ν•˜μ§€ μ•Šκ³  μ•„λž˜μ™€ 같이 μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.
#include <stdio.h> #include <stdarg.h> void sumAll(int args, ...) { int result; int tmp; //va_list ap; char *ap; result = 0; //va_start(ap, args); ap = (char *)&args + sizeof(args); for (int i = 0 ; i < args ; i++) { //tmp = va_arg(ap, int); tmp = *(int *)ap; ap += sizeof(int); result += tmp; printf("%d", tmp); if (i == args - 1) break; printf(" + "); } printf(" = %d\n", result); //va_end(ap); ap = 0; } int main(void) { sumAll(1, 10); sumAll(2, 10, 20); sumAll(3, 10, 20, 30); sumAll(4, 10, 20, 30, 40); sumAll(5, 10, 20, 30, 40, 50); return (0); }
C
볡사
μœ„ μ½”λ“œλ₯Ό 컴파일 ν•˜κ³  μ‹€ν–‰ν•˜λ©΄, μ˜¬λ°”λ₯΄μ§€ μ•Šμ€ κ²°κ³Όκ°€ λ‚˜νƒ€λ‚˜λŠ” 것을 λ³Ό 수 μžˆλ‹€. λΆ„λͺ… μ˜¬λ°”λ₯Έ 값이 λ‚˜μ™€μ•Ό ν•˜λŠ”λ° λ©”λͺ¨λ¦¬μ˜ 값이 μ˜¬λ°”λ₯΄κ²Œ μ—­μ°Έμ‘° λ˜μ§€ μ•ŠλŠ” 것을 μœ μΆ”ν•  수 μžˆλ‹€. 일반적으둜 32 λΉ„νŠΈ μ£Όμ†Œ μ²΄κ³„μ—μ„œλŠ” 문제 없이 μˆ˜ν–‰λ  μ½”λ“œμ§€λ§Œ, ν˜„μž¬ μ‹€μŠ΅μ„ μˆ˜ν–‰ν•˜λŠ” μ»΄ν“¨ν„°λŠ” 64 λΉ„νŠΈ μ£Όμ†Œ 체계λ₯Ό μ΄μš©ν•¨μ— 따라 λ°œμƒν•œ λ¬Έμ œμ΄λ‹€.
64 λΉ„νŠΈ μ£Όμ†Œ 체계λ₯Ό μ΄μš©ν–ˆμ„ λ•Œ, 맀크둜λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  κ΅¬ν˜„ν•œ μ½”λ“œκ°€ μ˜¬λ°”λ₯Έ κ²°κ³Όκ°€ λ‚˜μ˜€μ§€ μ•ŠλŠ” μ΄μœ λŠ” μ•„λž˜ λΈ”λ‘œκ·Έμ— μžμ„Ένžˆ μ„€λͺ…λ˜μ–΄ μžˆλ‹€.

4. Format Specifier Rules

1) Rule 정리 ν˜•μ‹

정리λ₯Ό μœ„ν•΄ μ•„λž˜μ™€ 같이 μΆ•μ•½ν•΄μ„œ ν‘œν˜„ν–ˆλ‹€λŠ” 것을 μ°Έκ³ ν•˜μž.
printf("%3.2c", 'a');
C
볡사
β†’ "%3.2c", 'a'
β†’ %{3.2}c
β†’ %{w.p}c
β†’ w.p

2) Rule of Only Width (with Flag)

width에 λŒ€ν•΄μ„  기본적으둜 인자의 길이 값이 width의 μ˜΅μ…˜μœΌλ‘œ 주어진 값을 λ„˜μ–΄κ°”μ„ λ•Œ, width ν•„λ“œλ₯Ό λ¬΄μ‹œν•œλ‹€.

[1] w

λ„ˆλΉ„κ°€ wκ°€ λ˜λ„λ‘ 빈 μžλ¦¬μ— λŒ€ν•΄ 곡백을 μ™Όμͺ½μ— μΆ”κ°€
#include <stdio.h> int main(void) { printf("%5d", 0); return (0); }
C
볡사

[2] -w

λ„ˆλΉ„κ°€ wκ°€ λ˜λ„λ‘ 빈 μžλ¦¬μ— λŒ€ν•΄ 곡백을 였λ₯Έμͺ½μ— μΆ”κ°€
#include <stdio.h> int main(void) { printf("%-5d", 0); return (0); }
C
볡사

[3] 0w

λ„ˆλΉ„κ°€ wκ°€ λ˜λ„λ‘ 빈 μžλ¦¬μ— λŒ€ν•΄ 0을 μ™Όμͺ½μ— μΆ”κ°€
#include <stdio.h> int main(void) { printf("%05d\n", 1); return (0); }
C
볡사

[4] -0w

λ„ˆλΉ„κ°€ wκ°€ λ˜λ„λ‘ 빈 μžλ¦¬μ— λŒ€ν•΄ 0을 였λ₯Έμͺ½μ— μΆ”κ°€ν•΄μ•Όν•  것 κ°™μ§€λ§Œ, flag ν•„λ“œμ˜ -와 0은 ν•¨κ»˜ μ‚¬μš©ν•  수 μ—†λ‹€. 기본적으둜 μ•„λž˜ κ·Έλ¦Όκ³Ό 같이 컴파일 κ²½κ³ λ₯Ό λ„μš΄λ‹€.
#include <stdio.h> int main(void) { printf("%-05d\n", 1); return (0); }
C
볡사
만일 이 κ²½κ³ λ₯Ό λ¬΄μ‹œν•˜κ³  κ°•μ œλ‘œ 컴파일 ν•˜λ©΄ -w와 같은 결과둜 좜λ ₯λ˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.

[5] *

0 < * : 인자둜 받은 *에 λŒ€ν•΄ λ„ˆλΉ„κ°€ *이 λ˜λ„λ‘ 빈 μžλ¦¬μ— λŒ€ν•΄ 곡백을 μ™Όμͺ½μ— μΆ”κ°€
0 > * : 인자둜 받은 *에 λŒ€ν•΄ λ„ˆλΉ„κ°€ *이 λ˜λ„λ‘ 빈 μžλ¦¬μ— λŒ€ν•΄ 곡백을 였λ₯Έμͺ½μ— μΆ”κ°€
#include <stdio.h> int main(void) { printf("%*d\n", 5, 0); printf("%*d\n", -5, 0); return (0); }
C
볡사

[6] -*

인자둜 받은 *에 λŒ€ν•΄ λ„ˆλΉ„κ°€ *이 λ˜λ„λ‘ 빈 μžλ¦¬μ— λŒ€ν•΄ 곡백을 였λ₯Έμͺ½μ— μΆ”κ°€
#include <stdio.h> int main(void) { printf("%-*d\n", 5, 0); printf("%-*d\n", -5, 0); return (0); }
C
볡사

[7] 0*

0 < * : 인자둜 받은 *에 λŒ€ν•΄ λ„ˆλΉ„κ°€ *이 λ˜λ„λ‘ 빈 μžλ¦¬μ— λŒ€ν•΄ 0을 μ™Όμͺ½μ— μΆ”κ°€
0 > * : 인자둜 받은 *에 λŒ€ν•΄ λ„ˆλΉ„κ°€ *이 λ˜λ„λ‘ 빈 μžλ¦¬μ— λŒ€ν•΄ 0을 였λ₯Έμͺ½μ— μΆ”κ°€ν•΄μ•Όν•  것 κ°™μ§€λ§Œ, 인자둜 받은 *이 음수라면 flag의 -μ˜΅μ…˜μ΄ μ μš©λœλ‹€. flag의 -와 0은 ν•¨κ»˜ μ‚¬μš©ν•  수 μ—†μœΌλ―€λ‘œ -w와 같은 결과둜 좜λ ₯λœλ‹€. -0w처럼 컴파일 κ²½κ³ λ₯Ό 주지 μ•ŠλŠ” μ΄μœ λŠ” μ½”λ“œ 상에 wλ₯Ό λͺ…μ‹œν•΄λ†“μ€ 것이 μ•„λ‹ˆκ³  런 νƒ€μž„μ— μ‚¬μš©μžλ‘œλΆ€ν„° μž…λ ₯을 받도둝 λ§Œλ“€μ—ˆκΈ° λ•Œλ¬Έμ΄λ‹€. 런 νƒ€μž„μ— λ°œμƒν•œ μΌ€μ΄μŠ€λŠ” 컴파일 νƒ€μž„μ—μ„œ μ°Ύμ•„λ‚Ό 수 μ—†λ‹€.
#include <stdio.h> int main(void) { printf("%0*d\n", 5, 1); printf("%0*d\n", -5, 1); return (0); }
C
볡사

[8] -0*

flag ν•„λ“œμ˜ -와 0은 ν•¨κ»˜ μ‚¬μš©ν•  수 μ—†λ‹€λŠ” λ™μΌν•œ 이유둜 컴파일 κ²½κ³ λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.
#include <stdio.h> int main(void) { printf("%-0*d\n", 5, 1); printf("%-0*d\n", -5, 1); return (0); }
C
볡사
κ°•μ œλ‘œ μ»΄νŒŒμΌμ„ μˆ˜ν–‰ν•˜λ©΄, μ•„λž˜μ— λ³΄μ΄λŠ” κ²ƒμ²˜λŸΌ -*κ³Ό 같은 결과둜 좜λ ₯λ˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.

3) Rule of Only Precision (with Flag)

.precision은 기본적으둜 자릿수λ₯Ό μ±„μšΈ λ•Œ 0을 μ±„μ›Œμ£ΌλŠ” μ„±μ§ˆμ΄ 있으며 .precision의 κ°’μœΌλ‘œλŠ” μŒμˆ˜κ°€ μ•„λ‹Œ κ°’λ§Œ 올 수 μžˆλ‹€. (μŒμˆ˜κ°€ λ“€μ–΄μ˜€λ©΄ .precision의 값을 μ²˜λ¦¬ν•˜λŠ” 방식이 μžˆλ‹€. μžμ„Έν•œ 것은 printf μ„€λͺ… 뢀에 μžˆλŠ” .precision ν•„λ“œμ˜ μ„€λͺ…을 μ°Έκ³ ν•˜μž.)

[1] .p

μ •μˆ˜μ— λŒ€ν•΄μ„  총 μžλ¦Ώμˆ˜κ°€ pκ°€ λ˜λ„λ‘ 0을 μ™Όμͺ½ 빈 곡간에 μ±„μ›Œ λ„£λŠ”λ‹€.
μ‹€μˆ˜μ— λŒ€ν•΄μ„  μ†Œμˆ˜μ  μ•„λž˜ μžλ¦Ώμˆ˜κ°€ pκ°€ λ˜λ„λ‘ 0을 빈 곡간에 μ±„μ›Œ λ„£λŠ”λ‹€. 만일 μžλ¦Ώμˆ˜κ°€ λ„˜μ–΄κ°€λ©΄ 자릿수λ₯Ό λ§žμΆ”κΈ° μœ„ν•΄ λ°˜μ˜¬λ¦Όμ„ μˆ˜ν–‰ν•œλ‹€.
#include <stdio.h> int main(void) { printf("%.5d\n", 1); printf("%.5f\n", 0.1); printf("%.5f", 0.000015); return (0); }
C
볡사

[2] -.p

width 값이 주어진 ν˜•νƒœκ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— κ·Έ κ²°κ³Όκ°€ .p와 λ™μΌν•˜κ²Œ λ‚˜νƒ€λ‚œλ‹€.
#include <stdio.h> int main(void) { printf("%-.5d\n", 1); printf("%-.5f\n", 0.1); printf("%-.5f", 0.000015); return (0); }
C
볡사

[3] 0.p

width 값이 주어진 ν˜•νƒœκ°€ μ•„λ‹Œλ°λ‹€κ°€ .precision νŠΉμ„± 상 0을 빈 μžλ¦¬μ— μ±„μš°κΈ° λ•Œλ¬Έμ— κ·Έ κ²°κ³Όκ°€ .p와 λ™μΌν•˜κ²Œ λ‚˜νƒ€λ‚œλ‹€.
#include <stdio.h> int main(void) { printf("%0.5d\n", 1); printf("%0.5f\n", 0.1); printf("%0.5f", 0.000015); return (0); }
C
볡사

[4] -0.p

flag의 -와 0은 ν•¨κ»˜ μ‚¬μš©ν•  수 μ—†κΈ° λ•Œλ¬Έμ— 컴파일 κ²½κ³ κ°€ λ°œμƒν•œλ‹€.
#include <stdio.h> int main(void) { printf("%-0.5d\n", 1); printf("%-0.5f\n", 0.1); printf("%-0.5f", 0.000015); return (0); }
C
볡사
λ‹€λ§Œ κ°•μ œλ‘œ μ»΄νŒŒμΌμ„ μ‹œμΌœλ„, width 값이 주어진 ν˜•νƒœκ°€ μ•„λ‹Œλ°λ‹€κ°€ .precision νŠΉμ„± 상 0을 빈 μžλ¦¬μ— μ±„μš°κΈ° λ•Œλ¬Έμ— κ·Έ κ²°κ³Όκ°€ -.p와 λ™μΌν•˜κ²Œ λ‚˜νƒ€λ‚œλ‹€.

[5] .*

.p와 κ²°κ³Όκ°€ λ™μΌν•˜λ‹€. ν•˜μ§€λ§Œ p 값을 μ‚¬μš©μžμ—κ²Œμ„œ 인자둜 λ°›μ•„μ„œ μ‚¬μš©ν•˜κ²Œ λœλ‹€.
#include <stdio.h> int main(void) { printf("%.*d\n", 5, 1); printf("%.*f\n", 5, 0.1); printf("%.*f", 5, 0.000015); return (0); }
C
볡사

[6] -.*

-.p와 κ²°κ³Όκ°€ λ™μΌν•˜λ‹€. ν•˜μ§€λ§Œ p값을 μ‚¬μš©μžμ—κ²Œμ„œ 인자둜 λ°›μ•„μ„œ μ‚¬μš©ν•˜κ²Œ λœλ‹€.
#include <stdio.h> int main(void) { printf("%-.*d\n", 5, 1); printf("%-.*f\n", 5, 0.1); printf("%-.*f", 5, 0.000015); return (0); }
C
볡사

[7] 0.*

0.p와 κ²°κ³Όκ°€ λ™μΌν•˜λ‹€. ν•˜μ§€λ§Œ p값을 μ‚¬μš©μžμ—κ²Œμ„œ 인자둜 λ°›μ•„μ„œ μ‚¬μš©ν•˜κ²Œ λœλ‹€.
#include <stdio.h> int main(void) { printf("%0.*d\n", 5, 1); printf("%0.*f\n", 5, 0.1); printf("%0.*f", 5, 0.000015); return (0); }
C
볡사

[8] -0.*

-0.p와 같이 flagμ—μ„œ -와 0이 ν•¨κ»˜ μ‚¬μš©λ  수 μ—†κΈ° λ•Œλ¬Έμ— μ•„λž˜μ™€ 같이 컴파일 κ²½κ³ κ°€ λ°œμƒν•œλ‹€.
#include <stdio.h> int main(void) { printf("%-0.*d\n", 5, 1); printf("%-0.*f\n", 5, 0.1); printf("%-0.*f", 5, 0.000015); return (0); }
C
볡사
λ‹€λ§Œ κ°•μ œλ‘œ μ»΄νŒŒμΌμ„ μ‹œμΌœλ„, width 값이 주어진 ν˜•νƒœκ°€ μ•„λ‹Œλ°λ‹€κ°€ .precision νŠΉμ„± 상 0을 빈 μžλ¦¬μ— μ±„μš°κΈ° λ•Œλ¬Έμ— κ·Έ κ²°κ³Όκ°€ -.*와 λ™μΌν•˜κ²Œ λ‚˜νƒ€λ‚œλ‹€.

4) Rules of Width + Precision (with Flag)

[1] w.p

[2] -w.p

w.p의 결과와 λ™μΌν•˜λ©΄μ„œ μΆ”κ°€μ μœΌλ‘œ 쒌츑 정렬을 μˆ˜ν–‰ν•œλ‹€.

[3] 0w.p

w.p의 결과와 λ™μΌν•˜λ©΄μ„œ μΆ”κ°€μ μœΌλ‘œ 빈 곡간에 0으둜 μ±„μ›Œ λ„£λŠ”λ‹€.

[4] -0w.p

flagμ—λŠ” -와 0을 ν•¨κ»˜ μ‚¬μš©ν•  수 μ—†κΈ° λ•Œλ¬Έμ— 컴파일 κ²½κ³ λ₯Ό λ„μš΄λ‹€.
κ°•μ œλ‘œ 컴파일 μ‹œν‚¬ 경우 -w.p와 λ™μΌν•œ κ²°κ³Όλ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

[5] *.* / *.p / w.*

w.p의 결과와 λ™μΌν•˜λ©΄μ„œ *에 ν•΄λ‹Ήν•˜λŠ” 인자λ₯Ό μ‚¬μš©μžμ—κ²Œ 직접 λ°›λŠ”λ‹€.

[6] -*.* / -*.p / -w.*

-w.p의 결과와 λ™μΌν•˜λ©΄μ„œ *에 ν•΄λ‹Ήν•˜λŠ” 인자λ₯Ό μ‚¬μš©μžμ—κ²Œ 직접 λ°›λŠ”λ‹€.

[7] 0*.* / 0*.p / 0w.*

0w.p의 결과와 λ™μΌν•˜λ©΄μ„œ *에 ν•΄λ‹Ήν•˜λŠ” 인자λ₯Ό μ‚¬μš©μžμ—κ²Œ 직접 λ°›λŠ”λ‹€.

[8] -0*.* / -0*.p / -0w.*

flagμ—λŠ” -와 0을 ν•¨κ»˜ μ‚¬μš©ν•  수 μ—†κΈ° λ•Œλ¬Έμ— 컴파일 κ²½κ³ λ₯Ό λ„μš΄λ‹€.
κ°•μ œλ‘œ 컴파일 μ‹œν‚¬ 경우 -*.*와 λ™μΌν•œ κ²°κ³Όλ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

5) Warnings of Each Type

[1] c

w, *, -w, -* 등에 λŒ€ν•΄ ν™œμš© κ°€λŠ₯ν•˜λ‹€.
.p, .*, 0w, 0* 등에 λŒ€ν•΄ κ²½κ³ κ°€ λ‚˜νƒ€λ‚œλ‹€.
λ‹€λ§Œ 0w, 0*에 λŒ€ν•΄μ„œλŠ” μ•„λž˜μ™€ 같이 κ²½κ³ κ°€ λ‚˜νƒ€λ‚˜λ„ κ°•μ œλ‘œ 컴파일 μ‹œμ—λŠ” 정상 적용된 값이 λ‚˜μ™€μ•Ό ν•œλ‹€λŠ” 것을 μˆ™μ§€ν•΄μ•Ό ν•œλ‹€.
#include <stdio.h> int main(void) { printf("%05c\n", 'a'); printf("%0*c\n", 5, 'a'); return (0); }
C
볡사

[2] s

w, *, -w, -*, .p, .*, w., *., w.p, *.* 등에 λŒ€ν•΄ ν™œμš© κ°€λŠ₯ν•˜λ‹€.
0w, 0* 등에 λŒ€ν•΄ κ²½κ³ κ°€ λ‚˜νƒ€λ‚œλ‹€.
λ‹€λ§Œ 0w, 0*에 λŒ€ν•΄μ„œλŠ” μ•„λž˜μ™€ 같이 κ²½κ³ κ°€ λ‚˜νƒ€λ‚˜λ„ κ°•μ œλ‘œ 컴파일 μ‹œμ—λŠ” 정상 적용된 값이 λ‚˜μ™€μ•Ό ν•œλ‹€λŠ” 것을 μˆ™μ§€ν•΄μ•Ό ν•œλ‹€.
#include <stdio.h> int main(void) { printf("%05.3s\n", "abcdef"); printf("%0*.*s\n", 5, 3, "abcdef"); return (0); }
C
볡사

[3] p

w, *, -w, -* 등에 λŒ€ν•΄ ν™œμš© κ°€λŠ₯ν•˜λ‹€.
.p, .*, 0w, 0* 등에 λŒ€ν•΄ κ²½κ³ κ°€ λ‚˜νƒ€λ‚œλ‹€.
λ‹€λ§Œ .p, .*, 0w, 0*에 λŒ€ν•΄μ„œλŠ” μ•„λž˜μ™€ 같이 κ²½κ³ κ°€ λ‚˜νƒ€λ‚˜λ„ κ°•μ œλ‘œ 컴파일 μ‹œμ—λŠ” 정상 적용된 값이 λ‚˜μ™€μ•Ό ν•œλ‹€λŠ” 것을 μˆ™μ§€ν•΄μ•Ό ν•œλ‹€.
w의 κ²½μš°μ—λŠ” 0xλ₯Ό λ„ˆλΉ„μ— ν¬ν•¨ν•˜κ³ , p의 경우 0xλ₯Ό μ •ν™•λ„μ—μ„œ μ œμ™Έν•˜κ³  좜λ ₯이 λ˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.
#include <stdio.h> int main(void) { printf("%.20p\n", "abcdef"); printf("%.*p\n", 20, "abcdef"); printf("%020p\n", "abcdef"); printf("%0*p\n", 20, "abcdef"); return (0); }
C
볡사

[4] d / i / u / x / X

λͺ¨λ“  ν•„λ“œμ— λŒ€ν•΄ ν™œμš© κ°€λŠ₯ν•˜λ‹€.

5. Reference

1) printf

2) Variable Argument