1. printf 함수의 이해
2. 문법 정리 및 실습
1. printf 함수의 이해
C언어에서 printf 함수는 C언어를 공부하는 초심자 입장에서, 디버깅을 하는 개발자 입장에서 모두 정말 중요한 함수이다.
그래서 첫 장에 이 가장 기본적이면서도 중요한 함수에 대해 알아보겠다.
(1) 함수의 기본 구조 이해
먼저 printf 함수의 기본 구조를 알아보자.
int printf(const char *format, ...);
위 코드는 앞 게시글에서 본 함수를 선언하는 내용이다. 왜 하는지 기억이 나지 않는다면 잠시 보고와도 좋다.
2024.10.02 - [study/C] - C언어 시작하기_C(2)
C언어 시작하기_C(2)
0. main()과 헤더파일의 중요성1. main() 에 대하여2. 헤더 파일 0. main()과 헤더파일의 중요성main()과 헤더파일 둘 중 하나라도 C언어코드에 없으면 프로그램이 작동하지 않는다.이 내용을 반드시 숙
sinmat.tistory.com
다시 본론으로 돌아와서 함수를 선언할 때에는 함수의 기본 구조로 선언문을 작성하게 된다.
한마디로 위에 적힌 코드가 printf 함수의 기본 구조라는 뜻이다.
하나하나 살펴보자.
2. 문법 정리 및 실습
(1) 문법 정리
-int
이 함수 자체의 자료형을 이야기 한다.
정확히 말하자면 함수가 return(반환) 해주는 결과값의 자료형을 말하는 것이다.
(반환_return 에 대해서 잘 모르겠다면 다음에 잘 정리해 두겠다.)
그렇다면 어떤 값이 반환되는지도 눈으로 직접 확인해보자.
#include <stdio.h>
int main(){
int count = printf("abcdef\n");
printf("%d\n", count);
}
이렇게 코드를 짜고 실행을 해보겠다. 컴파일 하고 실행하는 과정은 생략하겠다.
설명을 하자면 int 자료형의 count 변수에 printf("abcdef\n"); 을 실행하고 나온 반환값을 넣어준다.
그리고 그 count 변수를 printf에 넣어서 한 번 무엇이 출력 되는지 모도록 하자.

먼저 printf("abcdef\n"); 에 대한 출력을 보면 abcedf가 먼저 나오고
printf("abcdef\n"); 을 실행하고 return된 값을 count라는 변수에 값을 저장해준다.
그 다음 printf는 count에 들어간 데이터 값이 출력되어야 한다.
출력을 해보니 '7'이 나오고 있다.
이는 count 변수에 저장된 문자열이 7개라는 것이다.
즉, printf 함수는
첫번째로 안에 들어있는 문자열을 출력해주는 역할을 하고,
두번째로는 출력한 문자열의 길이를 숫자로 알려준다.
는 것을 알 수 있다.
-printf
이 함수 자체의 이름이다. 이 printf 함수를 선언함을 알려주며, 사용할 것을 말한다.
-const char *
const는 읽기 전용으로 변수를 선언해주는 키워드이다.
(= const 자체가 의미하는 바는 뒤에 나오는 변수를 선언하되, 읽기 전용으로 선언하여, 변수의 데이터 값이 바뀔 일이 없음을 보장하는 의미)
char은 문자형 자료를 의미한다.
*은 포인터를 의미한다.
(즉, char형식의 자료를 찾아주는 포인터 역할을 한다는 것이다. 이 내용이 헷갈린다면 아래 링크에 자세히 적어두겠다.)
한마디로 printf 함수 안에는 변수로 char 즉, 문자형 자료가 와야 한다는 것을 알려주는 동시에
이 printf 함수를 실행시키는 동안에는 이 자료의 내용이 변하지 않는다는 것을 알려주는 것이다.
-format
이건 그냥 변수명이다. 사실 여기에 다른 문자가 적혀있어도 된다.
이전 게시물에서 printf의 함수를 직접 선언하는 내용을 다루었다.
그 때에 원래라면
int printf(const char*format, ...);
이렇게 적겠지만
int printf(const char *dkanshfoskdlfeksxmfdj, ...);
이렇게 해도 잘 작동한다는 의미이다.
- , (콤마)
콤마를 기준으로 이 함수에서 받는 인자가 구분된다.
int printf(첫번째 인자, 두번째 인자); 이런식으로 표현되어있는 것이다.
첫번째 인자 = const char *format
두번째 인자 = ...
- ...
...은 가변인자(variable arguments)를 말한다.
가변인자들은 형식에 맞게 형식지정자의 위치에 들어갈 수 있다.
[형식 문자열과 형식 지정자]
1. 형식 문자열 : 문자열은 문자열인데 형식 지정자를 포함하고 있는 문자열을 말한다.
2. 형식 지정자 : 함수 호출 시 값들이 출력될 자리를 미리 지정하는 문자열(%s, %d, %f 등)
형식 지정자는 그 모양에 따라 어떤 자료형이 오게 될지 정해준다.
ex) %d = 정수형, %s = 문자열, %c = 단일문자, %p = 포인터 메모리 주소(16진수로)

#include <stdio.h>
int main(){
printf("여기가 바로 문자열(this is string)\n");
int a = 247;
printf("형식 지정자 사용(Format Specifiers) %d \n", a);
}
위와 같이 하여 출력을 해보면아래와 같이 출력되게 된다.

설명을 덧붙여보자면 '바로 위 사진'에 따옴표 " "로 감싸져있는 부분 안쪽이 문자열부분이다.
그런데 그 안에 형식 지정자가 들어가면 형식 문자열이 되는 것이다.
그리고 형식 지정자에 뒤에 있는 a라는 변수에 저장되어있는 데이터 247 이 들어가서 출력된다.
그렇다면 형식지정자는 왜 사용하는 것일까?
위의 예시에서는 직접 a에 숫자를 넣어줬지만 실제 서비스를 운영할 때에는 저런 값들이 수시로 변화하게 된다.
예를 들면 league of legends 에서
A챔피언이 B챔피언을 때리면 몇의 데미지가 들어갔는지 숫자가 나오도록 하는 코드를 짰다고 한다면
A챔피언의 공격력이 레벨업을 할 때마다, 아이템을 살 때마다, 버프를 받을 때마다 유동적으로 바뀌게 되는데
그것을 일일히 다 코드를 만들기보다는 그 순간의 A챔피언의 공격력을 뽑아다가 대입해주기만 하면 되는 것이다.
여기까지 printf 의 내용을 다루었다.
이제 printf함수를 자유롭게 사용해보도록 하자.
(2) 실습
int main() {
printf("what time is it now? \n");
int hour = 13;
int min = 55;
printf("it's %d : %d \n", hour, min);
}

printf("%d %s %c", 5, 5, 5);

위와 같이 하니 오류가 나온다.
뭐가 문제인가 생각해보고 해결해보자. 10초 주겠다.
#include <windows.h>
Sleep(1000); // 대충 10초 기다린다는 의미
format speciries의 type이 'char *'이어야 하는데 argument는 type을 int형으로 가지고 있다고 말하고 있다.
해석해보면 형식지정자의 자료형(타입)이 문자형(char) 포인터(변수)여야 하는데 정수형(int)이라고 한다.
#include <stdio.h>
int main() {
printf("%d %s %c", 5, "5", 5);
}

이것도 뭔가 이상하지 않는가? 5 가 3번 나와야 할 것 같은데 2번만 나오고 % 가 있다.
왜 그럴까?
이것도 10초 줘보겠다.
Sleep(1000);
%c는 문자character(1개)를 출력해주는 형식 지정자이다. 그런데 문자가 아니라 정수(integer)가 위치에 있기 때문에 아무것도 출력하지 않는 것이다.
앞에서는 오류를 냈지만 여기서는 왜 오류를 내지 않고 그냥 출력만 하지 않는 걸까?
먼저 %s 부터 알아본다면
%s는 문자열을 받는 형식 지정자이다.
%s는 인자가 들어올 때 문자열데이터 또는 문자열 데이터를 담고 있는 메모리의 주소 값을 기대하고 있기 때문이다.
인자가 들어올 때 실제 문자열, 즉 알파벳이 들어오면 그대로 출력을 해주고, 숫자데이터가 들어오면 그것을 메모리의 주소로 생각한다.
그래서 위와 같이 5라는 숫자가 들어오면 먼저는 이 5라는 정수를 메모리의 주소값으로 해석하려고 시도한다.
그리고 cpu와 os가 메모리에서 5라는 주소를 찾게 된다. 그러면 두 가지 상황이 발생할 수 있다.
-메모리 5의 주소가 유효하지 않거나 운영체제에 의해 보호되고 있는 영역임.
-메모리 5의 주소가 유효하지만 그 안에 데이터가 문자열이 아님.
%c는 문자를 받는 형식 지정자이다.
%c는 인자가 들어올 때 문자데이터 또는 아스키코드를 기대하고 있다.
인자가 들어올 때 실제 문자, 즉 알파벳이 들어오면 그대로 출력을 해주고, 숫자데이터가 들어오면 그것을 아스키 코드로 생각한다.
그래서 위와 같이 5라는 숫자가 들어오면 먼저는 이 5라는 정수를 아스키 코드로 생각하고 해석하려고 시도한다.
그리고 아스키 코드로 해석해서 출력을 한다.
그렇다면 %s 일때 정수를 넣어 오류가 발생하지 않도록 할 수도 있을 것이고,
%c일때도 정수를 넣어 오류가 발생하지 않도록 할 수 있을 것이다.
(이어서...)
이런식으로도 해보고 뭐 되든 안되든 다 실행해보자.
그래야 이녀석들이 무엇을 말하고 있는지 정확하게 이해할 수 있을 것이다.
'study > C' 카테고리의 다른 글
| C언어 시작하기_C(2) (0) | 2024.10.02 |
|---|---|
| C언어 시작하기_C(1) (6) | 2024.09.20 |