이번 강좌에서 배우게 될 것은
- 변수란 무엇인가?
- 정수형, 실수형 변수
- 16 진법, 메모리 주소
- 변수 이름 짓기
안녕하세요? 여러분. 잘 지내셨나요. 지난 강의는 잘 이해가 되셨나요? 아마, 이해가 잘 안 되었을 것 입니다. 왜냐하면 우리는 C 언어의 기본적인 이해도 없이 프로그램을 무작정 분석했기 때문이죠. 따라서, 지난번의 강의가 C 언어의 맛보기 였다면, 이제 본격적으로 C 언어의 세계로 풍덩 빠져 보도록 합시다.
변수란 무엇인가?
컴퓨터는 많은 내용을 '기억' 합니다. 정확히 말하면, 컴퓨터의 '메모리' 라는 부분에 전기적인 신호를 써 놓는 것이죠. 컴퓨터가 무엇을 기억해야 되냐고 생각할 수 있지만, 우리가 많이 하는 게임인 스타크레프트만 보아도 일단, 각 유닛의 HP 와 마나, 그리고 실시간으로 바뀌는 미네랄과 가스, 뿐만 아니라 유닛의 위치, 유닛의 데미지 등 모든 것을 기억해야지 우리가 게임을 제대로 즐길 수 있게 되죠. 만약 컴퓨터가 미네랄의 양을 제대로 기억 못한다면 미네랄이 갑자기 100 에서 0 이 되거나 10 에서 9999 로 바뀔 수 있기 때문이죠.
그렇다면 컴퓨터는 이러한 데이터들을 어떻게 기억할까요? 바로 컴퓨터의 메모리, 즉 RAM 이라는 특별한 기억공간에 이를 기록합니다. 보통 우리는 흔히 RAM 을 설명할 때 아래 처럼 표시합니다.
마치, 감옥에 온 것처럼 각 '방' 에 데이터들이 저장될 수 있습니다. 이 때, 컴퓨터는 각 방에 이름을 붙이는데 단순하게 숫자로 이름을 붙입니다. 0 번, 1 번, 2 번 ,... 이 때, 우리 대부분이 사용하는 32 비트 CPU 에서는 최대 2³² 개(4GB). 즉, 42 억개 달하는 방을 가질 수 있는데 이러한 방들을 모두 숫자로 구분하게 된다. 보통, 컴퓨터의 메모리 번지는 16 진수로 나타내는데, 여기서 간단하게 16 진수에 대해 알아 보도록 합시다.
수를 표현하는 방법
여기서는 수를 표현하는 방법에 대해 간단하게 집고 넘어갑니다. 이진법이 무엇인지, 아니면 이 단어 조차도 처음 들어본 사람이라는 2 - 3 강 수를 표현하는 방법을 읽어 보시길 바랍니다. 물론 이 부분에 대해 완벽한 이해가 되있더라도 한 번쯤 읽어 보기를 권합니다.
○○○○○○○○○○○○○○
위에 흰 공이 있습니다. 위의 흰 공은 몇 개 인가요? 우리는 아마 지금 머리속에 '14개 아니야' 라는 생각이 들었을 것입니다. 물론, 경우에 따라 잘못세면 '13개... 아 , 14개군' 이라고 생각할 수 도 있겠지요. 그런데 컴퓨터는 이를 14 로 보지 않습니다. 컴퓨터는 이를 1110 으로 생각합니다. '어? 컴퓨터는 특별히 많이 세나..'
아닙니다. 단지, 컴퓨터는 수를 표현하는 방법이 다를 뿐입니다. 우리가 14 라는 숫자를 좀 더 고상하게 표현해 보면 아래와 같습니다.
반면에 컴퓨터가 14 를 1110 이라 한 것은

이기 때문에 1110 이라 한 것입니다. (참고로, 2³ = 2 × 2 × 2를 편리하게 나타낸 것입니다.)
우리와 같이 10을 기준으로 한 것을 10 진법이라 하고,위 컴퓨터와 같이 2를 기준으로한 것을 2진법이라 합니다. 그렇다면 16 진법은 16을 기준으로 표현한 것이죠.
또한 우리가 한 가지 알 수 있는 사실은 임의의 진법 N 진법은, N 개의 숫자를 필요로 한 다는 것입니다. 예를들어, 이진법에서는 0 과 1 밖에 숫자가 필요하지 않았으나, 10 진법의 경우 0,1,2,3,4,5,6,7,8,9 와 같이 10 개의 숫자가 필요로 한 것입니다.
그렇다면 16 진법은 0,1,2,3,4,5,6,7,8,9 외에도 6 개의 숫자가 더 필요로 하는데, 수학자들은 이를 A,B,C,D,E,F 로 표현하였습니다. 따라서, 14는 16 진법으로 나타내면 E 가 되는 군요.
그런데, 컴퓨터가 왜, 계산하기 힘든 16 진법을 사용하느냐면 2 진법에서 16 진법으로 바꾸기 쉽기 때문이죠. 아래의 예제를 본다면, 237 은 아래와 같이 이진법으로 바꿀 수 있습니다.

이 때, 이진법을 16 진법으로 바꾸려면 뒤에서 부터 4 개씩 차근차근 바꾸면 됩니다. 위의 경우, 뒤의 4 개인 1101 을 16 진법으로 바꾸면 (13 이므로 D ) D 이고, 그 다음 4개인 1110 을 16 진법으로 바꾸면 (14 이므로 E) E 입니다. 결과적으로 237 = ED 가 되죠. 마찬가지로 111100111 을 한 번 바꿔보자면, 0111 은 7 이므로 그냥 7, 그 다음 1110 은 E, 마지막 1 은 그냥 1. 따라서 이 수는 1E7 이 됩니다. 간단하죠?
이제 다시 본론으로 돌아와서 봅시다. 아까 메모리가 최대 2³² 까지 가능하다고 했습니다. 이 때, 번지를 0 번부터 메기므로 2³² 번째 메모리의 주소는 11111111111111111111111111111111b 이겠죠. 이 때, 끝에 b 는 binary 의 약자로, 2 진법으로 썼다는 것을 표시해 주는 것 입니다. 위 2 진법으로 표현된 숫자는 1 이 32 개 연속되어 있는 것이므로 16 진법으로 나타내면 FFFFFFFF 가 되겠죠. 따라서, 번지는 0x00000000 부터 0xFFFFFFFF 까지 가능합니다. 이 때, 앞에 0x 는 16 진법이라는 것을 표시해 주는 것 입니다.
만약, 우리가 0x12345678 부터 0x1234567B 부분에 내가 캔 미네랄의 양에 관한 정보를 저장했다고 합시다. (이 한칸에는 1 바이트, 즉 00000000b 부터 11111111b 만큼의 정보를 저장할 수 있습니다. ) 만약 우리가 건물을 지을 때, 내가 가진 미네랄의 양이 건물이 필요로 하는 미네랄의 양과 비교하기 위해, 내가 캔 미네랄의 양에 관한 정보가 필요합니다. 그런데, 이렇게 미네랄에 관한 정보가 필요로 할 때 마다, 이 길고 알아보기 힘든 복잡한 주소를 일일이 써서 알아야 하나요? 그렇게 된다면 힘들어서 프로그래밍 어떻게 하나요.
하지만 다행히도 C 언어에는 '변수' 라는 것이 있어서, 이 모든 작업을 쉽게 할 수 있는 것이죠. 예를들어, 내가 캔 미네랄의 양을 mineral 이라는 변수에 저장했다고 합시다. 그렇다면 컴퓨터는 '알아서' 메모리의 어딘가에 mineral 의 방을 주고 그 내용을 저장합니다. 예를들어서, 컴퓨터가 이 mineral 이라는 변수에게 4 칸의 자리를 할당해 주었다고 합시다. 이는 아래 그림처럼 메모리 상에 표시됩니다.
이 때, 우리가 미네랄을 더 캐서 8 을 추가해야한다고 봅시다. 만약 이전에 8 을 추가한다면 0x12345678 부터 0x1234567B 까지의 모든 내용을 불러와서 8 을 더한 후, 다시 집어넣는 작업을 일일이 손으로 써 주어야 되었을 것입니다. 하지만, 이제는 단순히 mineral = mineral + 8 과 같이 써 주기만 한다면 mineral 에 8 이 더해지는 것이죠. (만약 mineral = mineral + 8 이라는 식이 이해가 안되도 그냥 넘어가세요. 이 처럼 간단해 진다는 것을 말해주고 싶었을 뿐입니다)
자, 이제. 변수가 무엇인지 알겠죠?
변수 선언하기
프로젝트를 만들어 위의 내용을 적은 후, 컴파일 해봅시다. 까먹었다면 1 강을 참조하세요. 만약 성공적으로 하였다면 아래와 같은 화면을 볼 수 있겠죠.
일단, 이번에도 역시 생소한 것들이 나왔기 때문에 한 문장씩 차근차근 살펴 봅시다.
음, 이게 무엇일까요? 이전에 int main() 에서 보았던 int 가 다시 나타났군요. 사실 이 문장에 뜻은 a 라는 변수를 우리가 쓰겠다고 컴파일러에게 알리는 것입니다. 만약 이러한 문장이 없다면 우리가 x 가 뭐고 y 가 뭔지 알려주지도 않은 채, 친구에게 x + y 가 얼마냐? 하고 물어보는 것과 똑같은 격이 되는 것이지요.
이 때, a 앞에 붙은 int 라는 것은 'int' 형의 데이터를 보관한다는 뜻으로, int 형의 변수는 -2147483648 부터 2147483647 까지의 숫자를 보관 할 수 있게 됩니다. 따라서, 만약 중간의 문장을
와 같이 한다면 아마 a 의 값을 출력하였을 때, 이상한 결과가 나오게 되죠. 왜냐하면 보관할 수 있는 범위를 초과하는 숫자를 보관했기 때문이죠.
그럼 이제, 걱정이 생깁니다. a 에 고작 10 밖에 안 넣을 거 면서, 굳이 2147483647 까지 표현할 수 있는 int 형의 변수를 왜 사용했냐고 물어 볼 수 있을 것 입니다. 컴퓨터 자원의 낭비 아닌가? 라는 생각도 들지요. 물론, int 형 보다 작은 범위의 숫자 데이터 만을 가지는 형식이 있기는 하지만(char), 32 비트 CPU 는 int 형의 변수를 가장 빨리 처리합니다.
또한, 2147483647 보다 큰 수를 사용하려면 어떻게 해야되냐는 궁금증도 생기지요. 물론 이 보다도 훨씬 큰 숫자를 처리하는 데이터 형식이 있습니다. 아래의 표를 참조하세요.
세번째 열인 Range 를 보시면, unsigned 와 signed 라고 나뉜 것이 있는데, 보통 int 라 하면 signed int 를 뜻합니다. 이는 음수/양수 모두 표시할 수 있는 대신에 양수의 표현할 수 있는 범위가 줄어듭니다. 반면에 unsigned int 는 양수만을 표현할 수 있는 대신에, 양수의 표현할 수 있는 범위가 늘어나죠. 또한 마지막에 보면 float ,double, long double 이 있는데 이들은 '실수형' 자료형으로 소수(0.1, 1.4123 등) 을 표현 할 수 있습니다. 뿐만 아니라 double 의 경우,
이기 때문에 1110 이라 한 것입니다. (참고로, 2³ = 2 × 2 × 2를 편리하게 나타낸 것입니다.)
우리와 같이 10을 기준으로 한 것을 10 진법이라 하고,위 컴퓨터와 같이 2를 기준으로한 것을 2진법이라 합니다. 그렇다면 16 진법은 16을 기준으로 표현한 것이죠.
또한 우리가 한 가지 알 수 있는 사실은 임의의 진법 N 진법은, N 개의 숫자를 필요로 한 다는 것입니다. 예를들어, 이진법에서는 0 과 1 밖에 숫자가 필요하지 않았으나, 10 진법의 경우 0,1,2,3,4,5,6,7,8,9 와 같이 10 개의 숫자가 필요로 한 것입니다.
그렇다면 16 진법은 0,1,2,3,4,5,6,7,8,9 외에도 6 개의 숫자가 더 필요로 하는데, 수학자들은 이를 A,B,C,D,E,F 로 표현하였습니다. 따라서, 14는 16 진법으로 나타내면 E 가 되는 군요.
그런데, 컴퓨터가 왜, 계산하기 힘든 16 진법을 사용하느냐면 2 진법에서 16 진법으로 바꾸기 쉽기 때문이죠. 아래의 예제를 본다면, 237 은 아래와 같이 이진법으로 바꿀 수 있습니다.
이 때, 이진법을 16 진법으로 바꾸려면 뒤에서 부터 4 개씩 차근차근 바꾸면 됩니다. 위의 경우, 뒤의 4 개인 1101 을 16 진법으로 바꾸면 (13 이므로 D ) D 이고, 그 다음 4개인 1110 을 16 진법으로 바꾸면 (14 이므로 E) E 입니다. 결과적으로 237 = ED 가 되죠. 마찬가지로 111100111 을 한 번 바꿔보자면, 0111 은 7 이므로 그냥 7, 그 다음 1110 은 E, 마지막 1 은 그냥 1. 따라서 이 수는 1E7 이 됩니다. 간단하죠?
이제 다시 본론으로 돌아와서 봅시다. 아까 메모리가 최대 2³² 까지 가능하다고 했습니다. 이 때, 번지를 0 번부터 메기므로 2³² 번째 메모리의 주소는 11111111111111111111111111111111b 이겠죠. 이 때, 끝에 b 는 binary 의 약자로, 2 진법으로 썼다는 것을 표시해 주는 것 입니다. 위 2 진법으로 표현된 숫자는 1 이 32 개 연속되어 있는 것이므로 16 진법으로 나타내면 FFFFFFFF 가 되겠죠. 따라서, 번지는 0x00000000 부터 0xFFFFFFFF 까지 가능합니다. 이 때, 앞에 0x 는 16 진법이라는 것을 표시해 주는 것 입니다.
만약, 우리가 0x12345678 부터 0x1234567B 부분에 내가 캔 미네랄의 양에 관한 정보를 저장했다고 합시다. (이 한칸에는 1 바이트, 즉 00000000b 부터 11111111b 만큼의 정보를 저장할 수 있습니다. ) 만약 우리가 건물을 지을 때, 내가 가진 미네랄의 양이 건물이 필요로 하는 미네랄의 양과 비교하기 위해, 내가 캔 미네랄의 양에 관한 정보가 필요합니다. 그런데, 이렇게 미네랄에 관한 정보가 필요로 할 때 마다, 이 길고 알아보기 힘든 복잡한 주소를 일일이 써서 알아야 하나요? 그렇게 된다면 힘들어서 프로그래밍 어떻게 하나요.
하지만 다행히도 C 언어에는 '변수' 라는 것이 있어서, 이 모든 작업을 쉽게 할 수 있는 것이죠. 예를들어, 내가 캔 미네랄의 양을 mineral 이라는 변수에 저장했다고 합시다. 그렇다면 컴퓨터는 '알아서' 메모리의 어딘가에 mineral 의 방을 주고 그 내용을 저장합니다. 예를들어서, 컴퓨터가 이 mineral 이라는 변수에게 4 칸의 자리를 할당해 주었다고 합시다. 이는 아래 그림처럼 메모리 상에 표시됩니다.
이 때, 우리가 미네랄을 더 캐서 8 을 추가해야한다고 봅시다. 만약 이전에 8 을 추가한다면 0x12345678 부터 0x1234567B 까지의 모든 내용을 불러와서 8 을 더한 후, 다시 집어넣는 작업을 일일이 손으로 써 주어야 되었을 것입니다. 하지만, 이제는 단순히 mineral = mineral + 8 과 같이 써 주기만 한다면 mineral 에 8 이 더해지는 것이죠. (만약 mineral = mineral + 8 이라는 식이 이해가 안되도 그냥 넘어가세요. 이 처럼 간단해 진다는 것을 말해주고 싶었을 뿐입니다)
자, 이제. 변수가 무엇인지 알겠죠?
변수 선언하기
/* 변수 알아보기 */
#include <stdio.h>
int main()
{
int a;
a = 10;
printf("a 의 값은 : %d \n", a);
return 0;
}
#include <stdio.h>
int main()
{
int a;
a = 10;
printf("a 의 값은 : %d \n", a);
return 0;
}
프로젝트를 만들어 위의 내용을 적은 후, 컴파일 해봅시다. 까먹었다면 1 강을 참조하세요. 만약 성공적으로 하였다면 아래와 같은 화면을 볼 수 있겠죠.
일단, 이번에도 역시 생소한 것들이 나왔기 때문에 한 문장씩 차근차근 살펴 봅시다.
int a;
음, 이게 무엇일까요? 이전에 int main() 에서 보았던 int 가 다시 나타났군요. 사실 이 문장에 뜻은 a 라는 변수를 우리가 쓰겠다고 컴파일러에게 알리는 것입니다. 만약 이러한 문장이 없다면 우리가 x 가 뭐고 y 가 뭔지 알려주지도 않은 채, 친구에게 x + y 가 얼마냐? 하고 물어보는 것과 똑같은 격이 되는 것이지요.
이 때, a 앞에 붙은 int 라는 것은 'int' 형의 데이터를 보관한다는 뜻으로, int 형의 변수는 -2147483648 부터 2147483647 까지의 숫자를 보관 할 수 있게 됩니다. 따라서, 만약 중간의 문장을
a = 10000000000000;
와 같이 한다면 아마 a 의 값을 출력하였을 때, 이상한 결과가 나오게 되죠. 왜냐하면 보관할 수 있는 범위를 초과하는 숫자를 보관했기 때문이죠.
그럼 이제, 걱정이 생깁니다. a 에 고작 10 밖에 안 넣을 거 면서, 굳이 2147483647 까지 표현할 수 있는 int 형의 변수를 왜 사용했냐고 물어 볼 수 있을 것 입니다. 컴퓨터 자원의 낭비 아닌가? 라는 생각도 들지요. 물론, int 형 보다 작은 범위의 숫자 데이터 만을 가지는 형식이 있기는 하지만(char), 32 비트 CPU 는 int 형의 변수를 가장 빨리 처리합니다.
또한, 2147483647 보다 큰 수를 사용하려면 어떻게 해야되냐는 궁금증도 생기지요. 물론 이 보다도 훨씬 큰 숫자를 처리하는 데이터 형식이 있습니다. 아래의 표를 참조하세요.
세번째 열인 Range 를 보시면, unsigned 와 signed 라고 나뉜 것이 있는데, 보통 int 라 하면 signed int 를 뜻합니다. 이는 음수/양수 모두 표시할 수 있는 대신에 양수의 표현할 수 있는 범위가 줄어듭니다. 반면에 unsigned int 는 양수만을 표현할 수 있는 대신에, 양수의 표현할 수 있는 범위가 늘어나죠. 또한 마지막에 보면 float ,double, long double 이 있는데 이들은 '실수형' 자료형으로 소수(0.1, 1.4123 등) 을 표현 할 수 있습니다. 뿐만 아니라 double 의 경우,
까지표현 할 수 있습니다. (물론 정확도가 떨어집니다. 앞 15 자리 까지가 정확)
음, 이 문장은 쉽게 알 수 있군요. 변수 a 에 10 이라는 데이터를 집어넣는 다는 것입니다. 즉, 나중에 a 의 값을 출력시 10 이 나오겠군요. 나중에 이 문장은 C 언어의 산술 연산에 대해 공부해 볼 때, 자세히 알아 봅시다.
마지막으로, 어제도 보았던 printf 문이군요. 그런데, 약간 다른 것이 있습니다. %d 가 말이죠. 사실, %d 는 컴퓨터에서 출력되지 않았습니다. 그 대신, %d 가 출력될 자리에 무언가 다른 것이 출력되었는데, 그 것이 바로 a 의 값이죠. 즉, %d 는 a 의 값을 '10 진수' 로 출력하라 라는 뜻이지요.
또 다른 예제를 봅시다.
프로그램을 제대로 짰다면 아래와 같은 결과를 볼 수 있을 것입니다.
일단, 위 프로그램에서 생기는 궁금증은 2 가지 있습니다. % 달린게 2 개나 있는데, 이를 어떻게 해야되냐와, %d 말고도 %o 와 %x 는 무엇인가 입니다.
먼저, printf 의 작동 원리에 대해 봅시다.
printf 출력시에, 큰 따옴표로 묶인 부분 뒤에 나열된 인자들 (8, a) 가 순서대로 큰 따옴표 안의 % 부분으로 들어감을 알 수 있습니다. 따라서 , 예를들면 printf("%d %d %d %d", a,b,c,d); 와 같은 문장은 a , b, c, d 의 값이 순서대로 출력되겠죠.
이제, %o 와 %x 는 무엇인가요? 이는 인자의 값(a) 를 출력하는 형식 입니다. 즉, %o 는 a 의 값을 8 진수로 출력하라라는 뜻이고, %x 는 a 의 값을 16진수로 출력하라는 뜻 이죠.
실수형 변수
앞서 말했듯이, 실수형에는 float 와 double 이 있습니다. double 의 경우 int 형에 비해 덩치가 2 배나 크지만 그 만큼 엄청난 크기의 숫자를 다룰 수 있습니다. 그 대신, 처음 15 개의 숫자들만 정확하고 나머지는 10 의 지수 형태로 표현됩니다. 또한 float 과 double 의 장점은 소수를 표시할 수 있다는 점인데, 정수형 변수에서 소수를 넣는다면 (예를들어 int a; a = 1.234; ), 소수 부분은 다 잘린 채, 나중에 a 의 값을 표시해 보면 1 이 나올 것 입니다.
실행해 본다면 아래와 같이 나오게 됩니다.
일단, 위 코드를 보면서 궁금한 점이 생기지 않았나요?
왜, float 형 변수 a 를 선언할 때 에는 숫자 뒤에 f 를 붙였는데 double 형 에서는 f 를 안 붙였는 지요. 왜냐하면, 그냥 f 를 안 붙이고 float a = 3.141592 로 하면 이를 double 형으로 인식하여 문제가 생길 수 있기 때문이죠. 따라서, float 형이라는 것을 확실히 표시해 주기 위해 f 를 끝에 붙이는 것 입니다.
이제, 마지막으로 %d, %o, %x 도 아닌 %f 가 등장하였습니다. 만약, 여기서 a 를 %d 형식으로 출력하면 어떻게 될까요? 한 번 해보세요. 아마 이상한 숫자가 나오게 될 것입니다. 왜냐하면 a 는 지금 정수형 변수가 아니기 때문이죠. 설사, 우리가 a = 3f; b = 3; 라고 해도, 이미 a 와 b 를 실수형 변수로 선언하였기 때문에 컴퓨터는 a ,b 를 절대 정수로 보지 않습니다.
따라서, 우리는 실수형 변수를 출력하는 형식인 %f 를 사용해야 합니다.
참고로 주의할 사항은 printf 에서 %f 를 이용해 수를 출력 할 때 다음과 같이 언제나 소수점을 뒤에 붙여 주어야 한다는 점입니다. 예를 들어서
을 하면 화면에 이상한 값 (아마도 0 이 출력될 것입니다) 이 나오지만 ,
을 하면 화면에 제대로 1.0 이 출력됩니다.
printf 의 또 다른 형식
a = 10;
음, 이 문장은 쉽게 알 수 있군요. 변수 a 에 10 이라는 데이터를 집어넣는 다는 것입니다. 즉, 나중에 a 의 값을 출력시 10 이 나오겠군요. 나중에 이 문장은 C 언어의 산술 연산에 대해 공부해 볼 때, 자세히 알아 봅시다.
printf("a 의 값은 : %d \n", a);
마지막으로, 어제도 보았던 printf 문이군요. 그런데, 약간 다른 것이 있습니다. %d 가 말이죠. 사실, %d 는 컴퓨터에서 출력되지 않았습니다. 그 대신, %d 가 출력될 자리에 무언가 다른 것이 출력되었는데, 그 것이 바로 a 의 값이죠. 즉, %d 는 a 의 값을 '10 진수' 로 출력하라 라는 뜻이지요.
또 다른 예제를 봅시다.
/* 변수 알아보기 2*/
#include <stdio.h>
int main()
{
int a;
a = 127;
printf("a 의 값은 %d 진수로 %o 입니다. \n",8, a);
printf("a 의 값은 %d 진수로 %d 입니다. \n",10, a);
printf("a 의 값은 %d 진수로 %x 입니다. \n",16, a);
return 0;
}
#include <stdio.h>
int main()
{
int a;
a = 127;
printf("a 의 값은 %d 진수로 %o 입니다. \n",8, a);
printf("a 의 값은 %d 진수로 %d 입니다. \n",10, a);
printf("a 의 값은 %d 진수로 %x 입니다. \n",16, a);
return 0;
}
프로그램을 제대로 짰다면 아래와 같은 결과를 볼 수 있을 것입니다.
일단, 위 프로그램에서 생기는 궁금증은 2 가지 있습니다. % 달린게 2 개나 있는데, 이를 어떻게 해야되냐와, %d 말고도 %o 와 %x 는 무엇인가 입니다.
먼저, printf 의 작동 원리에 대해 봅시다.
printf 출력시에, 큰 따옴표로 묶인 부분 뒤에 나열된 인자들 (8, a) 가 순서대로 큰 따옴표 안의 % 부분으로 들어감을 알 수 있습니다. 따라서 , 예를들면 printf("%d %d %d %d", a,b,c,d); 와 같은 문장은 a , b, c, d 의 값이 순서대로 출력되겠죠.
이제, %o 와 %x 는 무엇인가요? 이는 인자의 값(a) 를 출력하는 형식 입니다. 즉, %o 는 a 의 값을 8 진수로 출력하라라는 뜻이고, %x 는 a 의 값을 16진수로 출력하라는 뜻 이죠.
실수형 변수
앞서 말했듯이, 실수형에는 float 와 double 이 있습니다. double 의 경우 int 형에 비해 덩치가 2 배나 크지만 그 만큼 엄청난 크기의 숫자를 다룰 수 있습니다. 그 대신, 처음 15 개의 숫자들만 정확하고 나머지는 10 의 지수 형태로 표현됩니다. 또한 float 과 double 의 장점은 소수를 표시할 수 있다는 점인데, 정수형 변수에서 소수를 넣는다면 (예를들어 int a; a = 1.234; ), 소수 부분은 다 잘린 채, 나중에 a 의 값을 표시해 보면 1 이 나올 것 입니다.
/* 변수 알아보기 3*/
#include <stdio.h>
int main()
{
float a = 3.141592f;
double b = 3.141592;
printf("a : %f \n", a);
printf("b : %f \n", b);
return 0;
}
#include <stdio.h>
int main()
{
float a = 3.141592f;
double b = 3.141592;
printf("a : %f \n", a);
printf("b : %f \n", b);
return 0;
}
실행해 본다면 아래와 같이 나오게 됩니다.
일단, 위 코드를 보면서 궁금한 점이 생기지 않았나요?
float a = 3.141592f;
double b = 3.141592;
double b = 3.141592;
왜, float 형 변수 a 를 선언할 때 에는 숫자 뒤에 f 를 붙였는데 double 형 에서는 f 를 안 붙였는 지요. 왜냐하면, 그냥 f 를 안 붙이고 float a = 3.141592 로 하면 이를 double 형으로 인식하여 문제가 생길 수 있기 때문이죠. 따라서, float 형이라는 것을 확실히 표시해 주기 위해 f 를 끝에 붙이는 것 입니다.
printf("a : %f \n", a);
printf("b : %f \n", b);
printf("b : %f \n", b);
이제, 마지막으로 %d, %o, %x 도 아닌 %f 가 등장하였습니다. 만약, 여기서 a 를 %d 형식으로 출력하면 어떻게 될까요? 한 번 해보세요. 아마 이상한 숫자가 나오게 될 것입니다. 왜냐하면 a 는 지금 정수형 변수가 아니기 때문이죠. 설사, 우리가 a = 3f; b = 3; 라고 해도, 이미 a 와 b 를 실수형 변수로 선언하였기 때문에 컴퓨터는 a ,b 를 절대 정수로 보지 않습니다.
따라서, 우리는 실수형 변수를 출력하는 형식인 %f 를 사용해야 합니다.
참고로 주의할 사항은 printf 에서 %f 를 이용해 수를 출력 할 때 다음과 같이 언제나 소수점을 뒤에 붙여 주어야 한다는 점입니다. 예를 들어서
printf("%f", 1);
을 하면 화면에 이상한 값 (아마도 0 이 출력될 것입니다) 이 나오지만 ,
printf("%f", 1.0);
을 하면 화면에 제대로 1.0 이 출력됩니다.
printf 의 또 다른 형식
/* printf 형식 */
#include <stdio.h>
int main()
{
float a = 3.141592f;
double b = 3.141592;
int c = 123;
printf("a : %.2f \n", a);
printf("c : %5d \n", c);
printf("b : %6.3f \n", b);
return 0;
}
#include <stdio.h>
int main()
{
float a = 3.141592f;
double b = 3.141592;
int c = 123;
printf("a : %.2f \n", a);
printf("c : %5d \n", c);
printf("b : %6.3f \n", b);
return 0;
}
만약 위 소스를 성공적으로 쳤다면 실행시 아래와 같이 나오게 됩니다.
printf("a : %.2f \n", a);
이번에는 %f 가 아니라 %.2f 로 약간 다릅니다. 그렇다면 .2 가 뜻 하는 것은 무엇일까요? 대충 짐작했듯이, 무조건 소수점 이하 둘째 자리 까지만 표시하라 란 뜻입니다. 따라서, 위의 경우 3.141592 중 3.14 까지만 출력되고 나머지는 잘리게 되죠.
여기서 '무조건' 이라는 것은 %.100f 로 할 경우에도, 3.141592000000....00 을 표시해서 무조건 100 개를 출력하게 합니다.
printf("c : %5d \n", c);
이번에는 %d 가 아닌 %5d 입니다. 여기서 .5 가 아님을 주의합시다. 이 말은, 숫자의 자리수를 되도록 5 자리로 맞추라는 것 입니다. 따라서, 123을 표시할 때, 5 자리를 맞추어야 하므로 앞에 공백을 남기고 그 뒤에 123 을 표시했습니다. 그런데, 123456 을 표시할 때, %5d 조건을 준다면 어떻할까요? 이 때는 그냥 123456 을 다 표시합니다. 앞서 .?f 는 ? 의 수 만큼 무조건 소수점 자리수를 맞추어야 하지만 이 경우는 반드시 지켜야 되는 것은 아닙니다.
printf("b : %6.3f \n", b);
마지막으로, 위에서 썼던 두 가지 형식을 모두 한꺼번에 적용한 모습입니다. 전체 자리수는 6 자리로 맞추되, 반드시 소수점 이하 3 째 자리 까지만 표시한다는 뜻이지요.
변수 작명하기
앞서, 보았듯이 변수를 선언하는 것은 어려운 일이 아닙니다. 단지, 아래의 형태로 맞추어 주기만 하면 되죠.
(변수의 자료형) 변수1, 변수2, ..... ;
/* 예를 들어 */
int a , b, c, hi;
float d, e, f, bravo;
double g, programming;
long h;
short i;
char j,k, hello, mineral ;
/* 예를 들어 */
int a , b, c, hi;
float d, e, f, bravo;
double g, programming;
long h;
short i;
char j,k, hello, mineral ;
이 때, 변수 선언시 주의해야 할 점이 있습니다. 일단, 변수 선언은 소스의 최상단에 위치해야 합니다. 예를들어서 아래와 같이 프로그램을 짠다면...
/* 변수 선언시 주의해야 할 점 */
#include <stdio.h>
int main()
{
int a;
a = 1;
printf("a 는 : %d", a);
int b; // 오류발생!
return 0;
}
#include <stdio.h>
int main()
{
int a;
a = 1;
printf("a 는 : %d", a);
int b; // 오류발생!
return 0;
}
컴파일시 다음과 같은 오류를 발생하게 됩니다.
error C2143: 구문 오류 : ';'이(가) '형식' 앞에 없습니다.
따라서, 이러한 오류를 방지하기 위해, 모든 변수는 최상단에 몰아서 선언을 해야 합니다.
두번째로, 사람의 이름을 지을 때, 여러가지를 고려하듯이 변수의 이름에서도 여러가지 조건들이 있습니다. 아래 예제를 보세요.
/* 변수 선언시 주의해야 할 점 */
#include <stdio.h>
int main()
{
int a, A; // a 와 A 는 각기 다른 변수 입니다.
int 1hi;
// (오류) 숫자가 앞에 위치할 수 없습니다.
int hi123, h123i, h1234324; // 숫자가 뒤에 위치하면 괜찮습니다.
int 한글이좋아;
/*
(오류)
변수는 오직 알파벳, 숫자, 그리고 _ (underscore)로만으로 이루어져야 합니다. */
int space bar;
/*
(오류)
변수의 이름에는 띄어쓰기하면 안됩니다. 그 대신 _ 로 대체하는 것이 읽기 좋습니다.*/
int space_bar; // 이것은 괜찮습니다.
int enum, long, double, int, break
/* (오류)
지금 나열한 이름들은 모두 '예약어' 로 C 언어에서 이미 쓰이고 있는 것들입니다.
따라서 이러한 것들은 쓰면 안됩니다. 이를 구분하는 방법은 예약어들을 모두
외우거나 '파란색' 으로 표시된 것들은 모두 예약어라 볼 수 있습니다 */
return 0;
}
#include <stdio.h>
int main()
{
int a, A; // a 와 A 는 각기 다른 변수 입니다.
int 1hi;
// (오류) 숫자가 앞에 위치할 수 없습니다.
int hi123, h123i, h1234324; // 숫자가 뒤에 위치하면 괜찮습니다.
int 한글이좋아;
/*
(오류)
변수는 오직 알파벳, 숫자, 그리고 _ (underscore)로만으로 이루어져야 합니다. */
int space bar;
/*
(오류)
변수의 이름에는 띄어쓰기하면 안됩니다. 그 대신 _ 로 대체하는 것이 읽기 좋습니다.*/
int space_bar; // 이것은 괜찮습니다.
int enum, long, double, int, break
/* (오류)
지금 나열한 이름들은 모두 '예약어' 로 C 언어에서 이미 쓰이고 있는 것들입니다.
따라서 이러한 것들은 쓰면 안됩니다. 이를 구분하는 방법은 예약어들을 모두
외우거나 '파란색' 으로 표시된 것들은 모두 예약어라 볼 수 있습니다 */
return 0;
}
이 안에 모든 내용이 들어 있습니다. 변수의 이름은 반드시
- 숫자가 앞에 위치하면 안됩니다. 그러나 중간이나 뒤는 괜찮습니다.
- 변수명은 오직 영어, 숫자, _ 로 만 구성되어 있어야 합니다.
- 변수의 이름에 띄어쓰기가 있으면 안됩니다.
- 변수의 이름이 C 언어 예약어 이면 안됩니다. 보통 예약어를 쓰면 파란색 글자체로 표시되어 예약어를 썼는지 안썼는지 알 수 있습니다.
자, 이제 우리는 C 언어에서 중요한 부분인 변수에 대해서 알아보았습니다. 현재 우리는 수를 다루는 변수들만 다루었지만, 다음 강좌에서는 변수에 대한 산술 연산과, 문자를 다루는 변수에 대해 알아보도록 하겠습니다.
강좌를 보다가 조금이라도 궁금한 것이나 이상한 점이 있다면 꼭 댓글을 남겨주시기 바랍니다. 그 외에도 강좌에 관련된 것이라면 어떠한 것도 질문해 주셔도 상관 없습니다. 생각해 볼 문제도 정 모르겠다면 댓글을 달아주세요.
현재 여러분이 보신 강좌는 <<씹어먹는 C 언어 - <3. 변수가 뭐지? >>> 입니다. 이번 강좌의 모든 예제들의 코드를 보지 않고 짤 수준까지 강좌를 읽어 보시기 전까지 다음 강좌로 넘어가지 말아주세요
현재 여러분이 보신 강좌는 <<씹어먹는 C 언어 - <3. 변수가 뭐지? >>> 입니다. 이번 강좌의 모든 예제들의 코드를 보지 않고 짤 수준까지 강좌를 읽어 보시기 전까지 다음 강좌로 넘어가지 말아주세요
'C' 카테고리의 다른 글
| 씹어먹는 C 언어 - <6. 만약에...(if 문)> (129) | 2009/04/28 |
|---|---|
| 씹어먹는 C 언어 - <5. 문자 입력 받기> (115) | 2009/04/27 |
| 씹어먹는 C 언어 - <4. 계산하리 > (173) | 2009/04/24 |
| 씹어먹는 C 언어 - <3. 변수가 뭐지? > (249) | 2009/04/22 |
| 씹어먹는 C 언어 - <2 - 1. C 언어 본격 맛보기> (154) | 2009/04/17 |
| 씹어먹는 C 언어 - <1. C 언어가 뭐야?> (308) | 2009/04/16 |