[3-1] printf 함수

2024. 9. 2. 17:20·📚 STUDY/🔥 C

🌟 글 많음 주의........ 미리 경고합니닷 🌟

 

- printf 함수는 서식 문자열이라고 불리는 문자열을 문자열의 특정 부분에 추가된 값과 함께 출력하는 기능을 수행하도록 만들어짐.

- printf가 호출되려면, 서식 문자열과 출력을 할 때 삽입되어야하는 값을 공급해줘야 함.

printf(string, expr1, expr2, …);
  • 출력되는 값들은 상수, 변수 혹은 매우 복잡한 표현식일 수도 있음. printf 함수는 호출 한 번으로 무한가지의 값을 출력할 수 있음.
  • % 다음으로 나오는 정보는 값이 어떤 규격으로 본래 형식(이진수)에서 출력되는 형식(문자) 변환되는지를 정함.
  • 변환 규격 %d : printf이 int값을 이진수로부터 10진수를 갖는 문자열로 변환되어 출력하는 규격을 정해줌.
  • 변환규격 %f : float 값에 대해 마찬가지로 규격을 정함.

 

- 서식 문자열의 일반적인 글자들은 생긴 그대로 출력될 것임. 변환 규격의 경우, 출력되어야 할 값들로 바뀌어져 출력됨.

int i;
int j;
float x;
float y;

i = 10;
j = 20;
x = 43.2892f;
y = 5527.0f;

printf("i = %d, j = %d, x = %f, y = %f\n", i, j, x, y);
  • printf 함수를 호출하면, 다음과 같은 결과가 출력됨. i = 10, j = 20, x = 43.289200, y = 5527.000000
  • 서식 문자열의 일반적인 글자들은 그냥 그대로 출력되었음.
  • 네 개의 변환 규격들은 순서대로 변수 i, j, x, y로 바뀌어져 출력됨.
[!!!] C 컴파일러들은 서식 문자열에서의 변환 규격의 개수와 출력되는 것들의 개수가 같은지를 반드시 확인하지 않는다. 다음과 같은 printf 함수의 호출을 보면 출력해야할 값보다 변환 규격이 더 많다.
printf("%d %d\n", i); /*** WRONG ***/
printf은 i의 값은 제대로 출력하고, 아무런 의미가 없는 두 번째 정수값을 출력할 것이다. 반대로 출력해야할 값이 변환 규격보다 많으면 비슷한 문제를 일으킨다.
printf("%d\n", i, j); /*** WRONG ***/
이 경우엔 printf이 i의 값은 출력하지만 j의 값은 출력하지 않을 것이다.
좀 더 구체적으로 언급하자면, 컴파일러들은 굳이 변환 규격이 출력되는 것의 유형에 적합한지를 확인하지 않는다. 만약 프로그래머가 잘못된 규격을 사용한다 할지라도, 프로그램은 실행이 될 것이고 아무런 의미가 없는 결과값을 출력할 것이다. 다음과 같이 int 변수 i와 float 변수 x가 틀린 순서로 되어있는 상태에서 printf을 호출해주었다고 하자.
printf("%f %d\n", i, x); /*** WRONG ***/
우선 printf은 서식 문자열이 지시하는 대로 따라야하기 때문에 지시한 대로 float 값과 int 값을 순서대로 출력할 것이다. 물론 두 개 다 의미없는 결과값일 것이다.

 

 

📌 변환 규격

- 변환 규격을 통해 프로그래머는 출력을 좀 더 다양하고 구체적으로 할 수 있음. 그렇기에, 변환 규격은 사용, 읽기 복잡함.

- 2단원에서 변환 규격을 통해 서식에 대한 정보를 첨가해줄 수 있다는 것을 배움.

- 구체적으로 보자면, float 값을 소수점 아래 한 자리까지만 출력해주기 위해 %.1f 를 이용함.

- 좀 더 일반적으로 보자면, 변환 규격은 %m.pX이나 %-m.pX와 같은 형식을 가짐. 여기서 m과 p는 정수 상수이고 X는 문자임. m과 p는 선택적으로 추가해주는 것이고, m과 p를 나누는 소수점은 p와 함께 사용해야함.

- 변환 규격 %10.2f에선 m은 10, p는 2이고 X는 f임. 변환 규격 %10f에선 m은 10, p는 사용되지 않았기 때문에 소수점과 함께 사용되지 않았으며, X는 f임. 반면에 변환 규격 %.2f의 경우 반대로 p는 2이고 m는 사용되지 않았음.

 

- m의 뜻은 최소 범위 너비(minimun field width)로, 출력할 글자의 최소 개수를 정함. 출력할 값의 글자가 m개보다 적다면, 주어진 범위 내에 있는 것임.

ex) %4d를 준 다음 출력할 값을 123으로 준다면, 실제 출력되는 값은 ·123일 것. (이 단원에선 스페이스를 ·로 표기함)

- 위의 경우와는 반대로 출력할 값의 글자가 m 개보다 크다면 자동으로 범위를 필요한만큼 넓힘. 그렇기 때문에 규격 %4d을 준 다음 출력할 값을 12345로 준다면, 실제 출력되는 값은 12345일 것.

- 만약 m앞에 마이너스 기호를 표기해준다면, 숫자를 왼쪽에 정렬하게 됨. 즉, 규격 %-4d을 준 다음 출력할 값을 123로 준다면, 실제 출력되는 값은 123·임.

 

- p의 뜻은 정확도임. 정확도는 x 혹은 규격자의 종류에 따라 다르게 정의됨. x는 값이 출력되기 전 어떤 방식의 변환이 적용되어야하는지를 결정함. 가장 자주 사용되는 숫자의 변환 규격자는 다음과 같음.

  • d - [Q&A] 정수를 십진법 형식으로 보여준다. p는 최소 자리수를 의미한다. 만약 필요하다면 숫자가 시작하는 부분에 추가적으로 0을 추가해준다. 만약 p가 포함되지 않았다면 p의 값이 1이라고 가정한다. 다시 말해 %d와 %.1d는 같은 것이다.
  • e - 소수를 지수 형식(물리량을 나타낼 때 사용하는 방식)으로 보여준다. p는 출력할 소수점 이하 자리수를 결정한다. 기본값은 여섯자리이다. 만약 p의 값이 0이라면 소수점을 출력하지 않는다.
  • f - 소수를 지수 없이 고정 소수점 형식으로 보여준다. p는 e 규격자와 같은 의미를 갖는다.
  • g - 소수를 숫자의 크기에 따라 지수 형식 혹은 고정 소수점 형식으로 보여준다. p는 최대 유효 숫자 자리수를 의미한다. 이는 소수점 아래 자리수를 의미하는 것이 아니다. f 변환과는 달리 g 변환은 추가적인 0을 출력하지 않는다. 심지어 출력할 값이 소수점 이하 자리수가 없다면 g는 소수점 조차 출력하지 않는다.

- g 규격자는 프로그램을 작성할 때 숫자가 사이즈를 예측할 수 없거나, 사이즈가 다양할 때, 이를 출력하는데 유용함. 적당히 크거나 적당히 작은 숫자를 출력할 때 고정 소수점 형식을 사용함. 허나 매우 크거나 매우 작은 숫자를 출력할 땐 지수 형식을 사용함으로써 숫자가 길지 않게 만듦.  %d, %e, %f, %g 외에도 다른 다양한 규격자들이 있지만 이후 단원에서 차차 소개하도록 함.

 

 

🔥 [프로그래밍] printf를 통한 숫자 서식

🌐 tprintf.c

/* Prints int and float values in various formats */
#include <stdio.h>

int main(void)
{
  int i;
  float x;
  i = 40;
  x = 839.21f;

  printf("|%d|%5d|%-5d|%5.3d|\n", i, i, i, i);
  printf("|%10.3f|%10.3e|%-10g|\n", x, x, x);

  return 0;
}
  • printf의 서식 문자열 내부에 있는 |는 이 서식 문자열이 출력될 때 얼마나 많은 칸을 소모하는지를 보여주기 위해 사용함. %, \와는 달리 |는 printf에서 아무런 기능을 갖고있지 않아, 마음대로 사용할 수 있음.
  • 위 프로그램을 출력하면 다음과 같음.

|40|   40|40   |  040|

| 839.210| 8.392e+02|839.21 |

 

- 이 프로그램에서 사용한 변환 규격들에 대해 좀 더 구체적으로 살펴보자.

  • %d ― i를 십진수의 형태로 출력하되, 최소한의 공간만을 차지한다.
  • %5d ― i를 십진수의 형태로 출력하되, 최소 다섯 칸을 사용한다. i는 두 칸을 차지하므로, 추가적으로 빈 칸 세 칸이 더 추가되었다.
  • %-5d ― i를 십진수의 형태로 출력하되, 최소 다섯 칸을 사용한다. i는 두 칸을 차지하므로, 추가적으로 빈 칸 세 칸이 i가 먼저 출력되고 나서 추가되었다. 즉, i는 좌측으로 정렬된다.
  • %5.3d ― i를 십진수의 형태로 출력하되, 출력은 최소 다섯 칸, 숫자는 최소 세 칸을 사용한다. i는 두 칸 밖에 안되므로 세 칸을 채우기 위해 0이 추가되었다. 이제 세 칸이 찼으므로 부족한 두 칸을 빈 칸으로 채워 총 다섯칸을 채운다, i는 우측으로 정렬된다.
  • %10.3f ― x를 고정된 십진수의 형태로 출력하되, 출력은 최소 열 칸, 소수점 이하는 최소 세 칸을 사용한다. x는 소수점 이전 세 칸, 소수점 이후 세 칸, 소수점이 한 칸, 총 일곱 칸이 필요하므로 세 칸을 채우기 위해 x 좌측에 빈 칸 세 칸이 추가되었다.
  • %10.3e ― x를 지수형으로 출력하되, 출력은 최소 열 칸, 소수점 이하는 최소 세 칸을 사용한다. x는 지수를 포함하면 총 아홉 칸을 사용하기 때문에 x 좌측에 빈 칸 한 칸이 추가되었다.
  • %-10g ― x를 고정 십진수 형태나 지수형으로 출력하되, 출력은 최소 열 칸을 사용한다. 위의 경우에선 printf은 x를 고정 십진수 형태로 출력했다. 앞에 마이너스 기호는 x를 좌측으로 정렬하라는 의미이기 때문에 x 이후에 빈 칸 네 칸이 추가되었다.

💡 보통 언제 사용하나?

  • 값이 0-100 사이인 2차월 배열을 이중 포문으로 출력하면 40 3 39 39\n 3 100 3 35 이런식으로 나와서 보기 불편함. 이때, "%3d",a[i][j] 같은 방법으로 사용하면 깔끔하게 출력됨.

 

 

📌 확장 비트열

- \n과 같은 코드를 확장 비트열이라고 부름.

- 확장 비트열은 문자열로 하여금 컴파일러에서 문제를 일으킬 수도 있는 문자들을 출력하게 해줌. (프린트되지 않는 제어 문자들이나 "와 같이 컴파일러가 특별히 다루는 문자들을 의미함)

- printf의 서식 문자열 중에 가장 먼저 실행됨.

 

💡 몇 가지 확장 비트열

 

printf("Item\tUnit\tPurchase\n\tPrice\tDate\n");

 

이 프로그램을 실행하게 된다면 다음과 같이 나옴.

 

`Item Unit Purchase

Price Date`

 

- 위의 예시 말고도 자주 쓰이는 확장 비트열은 \"이고, 이는 " 문자를 출력함. "는 문자열의 시작, 끝을 나타내주는 문자이기에 문자열 내에선 확장 비트열을 사용하지 않는 이상 사용할 수 없음.

printf("\"Hello!\"");

 

위 구문을 실행한다면 다음과 같이 출력됨.

 

"Hello!"

 

- 당연하겠지만 문자열 내부에 \ 한 개를 사용할 수 없음. 컴파일러는 이를 확장 비트열의 시작으로 인식할 것이기 때문임. 즉, \ 문자열을 출력해주기 위해서는 두 번 연속해서 사용해주면 됨.

printf("\\"); /* 문자 \ 하나를 출력한다 */
printf("\\"); /* prints one \ character */

 

 

 

💡 본 내용은 K.N.King의 C Programming: A Modern Approach 책을 참고하였습니다.

저작자표시 (새창열림)

'📚 STUDY > 🔥 C' 카테고리의 다른 글

Q&A  (3) 2024.09.02
[3-2] scanf 함수  (0) 2024.09.02
Q&A (GCC, GNU, 함수, 주석, 식별자, 레이아웃..)  (4) 2024.09.02
[2-8] C 프로그램의 레이아웃  (0) 2024.09.02
[2-7] 식별자  (0) 2024.09.02
'📚 STUDY/🔥 C' 카테고리의 다른 글
  • Q&A
  • [3-2] scanf 함수
  • Q&A (GCC, GNU, 함수, 주석, 식별자, 레이아웃..)
  • [2-8] C 프로그램의 레이아웃
엄지잉
엄지잉
공부하는거 올림
  • 엄지잉
    엄지잉의 이것저것
    엄지잉
  • 전체
    오늘
    어제
    • 분류 전체보기 (94)
      • 🏫 학교 (2)
        • 👩‍🏫 교직 (1)
        • 🏢 USG (1)
      • 🌱 탐구 (17)
        • 📷 SLAM (7)
        • 💡 연구 (8)
        • 🌐 BOJ (2)
      • 📚 STUDY (47)
        • 🔥 C (32)
        • 📈 알고리즘 (9)
        • 👀 컴퓨터비전 (5)
        • 🔆 UNITY (1)
      • 🏆 자격증 (23)
        • ⚡ 정처기 (17)
        • 🔠 TOEIC (6)
      • 🎈 활동 (4)
        • 🎁 CJ 리모트 인턴십 (2)
        • 😶 기타 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    프언 활용
    RC
    Slam
    c기초
    azurekinect
    2021년
    정보처리기사
    mocopi
    BOJ
    Body Tracking
    Unity
    컴퓨터비전
    정보시스템 구축관리
    Azure Kinect
    식별자
    DB 구축
    토익
    필기
    정처기
    C언어
    알고리즘
    opencv
    실기
    모션캡처
    SW 설계
    Remote Internship
    2022년
    C++
    C
    SW 개발
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
엄지잉
[3-1] printf 함수
상단으로

티스토리툴바