3.2.알아야 할 중요한 개념들
변수와 상수, 제어문, 함수는 모든 언어에 적용되는 기본 개념입니다.
변수와 상수를 배웠고 제어문을 배웠으며 간단하게 함수를 만드는 법까지 배웠습니다. 변수의 선언법과 상수의 자료형, 제어문을 이용해서 루프를 돌리는 법까지 제대로 이해하셨다면 C++언어의 기초를 닦으신 셈입니다.
변수와 상수 제어문에 관한 개념은 C++언어에만 적용되는 개념이 아닙니다. 대부분의 언어에서 그대로 적용될 수 있는 개념입니다. 단지 다른 언어에서는 사용하는 함수 이름이나 선언방법 등이 조금씩 다를 뿐입니다. 명령어가 다를 뿐 기본적인 개념은 지금까지 배운 내용을 벗어나지 않습니다. 모든 언어에서 변수와 상수를 사용하며, 모든 언어가 제어문을 이용해서 변수와 상수를 제어합니다. 명령문들을 좀더 효율적으로 사용하기 위해서 함수를 사용하기도 합니다.
이들 개념만 제대로 이해하신다면 언어는 더 이상 어려운 전문영역이 아님을 아실 겁니다. 깊이 들어가면 끝이 없겠지만 자신이 원하는 간단한 프로그램을 짜는 일은 의외로 쉽다는 것을 알 수 있습니다.
지금까지 과정을 통해 변수, 상수, 함수, 제어문 등의 언어 기초지식을 끝냈습니다.
이 책을 여기까지 어려움 없이 읽으셨다면 언어에 대한 기초지식을 갖춘 분입니다. 머리말에서 말씀드렸던 것처럼 이 책의 최대목표는 사람들이 누구나 손쉽게 언어의 세계로 입문할 수 있도록 도와주는 것입니다. 그래서 나름대로 쉽게 쓴다고 썼습니다만 평가는 모두 다르리라 생각합니다. 쉽다고 평가하는 분도 계실 것이고, 어렵다고 생각하는 분도 있을 겁니다.
하여간 지금까지의 과정을 통해서 여러분은 언어를 공부하는데 필요한 가장 기본적인 개념을 배우셨습니다. 함수와 변수, 상수, 제어문의 개념에 대해서 배웠습니다. 지금까지 배운 내용을 가지고 여러분이 원하는 프로그램을 짠다는 것은 어렵습니다. 그러나 지금까지 배운 내용을 충분하게 이해하고 소화하셨다면 앞으로 어떤 언어를 배우더라도 크게 어려움을 겪지 않으리라 생각합니다.
시중에 컴퓨터와 컴퓨터언어 관련 서적이 많이 나와있지만 쉽게 따라가기 힘듭니다. 그 까닭은 개념설명이 부족하기 때문입니다. 많은 컴퓨터서적이 개념 설명이 없거나 짤막하게 한 두 줄로 설명하고는 바로 명령어 설명으로 넘어갑니다. 글 쓰는 사람에게는 너무나 당연하고 익숙한 개념이라서 이들 개념에 대한 설명을 빼먹고 지나갑니다. 사실 a+b=c라는 공식에서 a, b, c가 변수라는 사실은 중학교 수학만 배워도 아는 내용이니다.
그러나 대부분의 사람은 변수나 함수가 뭔지 모릅니다. 언어에 처음 입문하는 사람이라면 컴파일하고 실행하라는 말 뜻조차 모릅니다. 그런데 대뜸 컴파일하라는 말부터 나옵니다. 그러니 시작부터 진도가 잘 안나갑니다. 그래서 이 책에서는 C++언어의 문법설명이나 명령문 설명보다는 가장 중요한 개념을 설명하는데 많은 부분을 투자했습니다.
이 책을 통해서 컴파일과 링크가 무엇이며 왜 필요한지만 이해하셨다 해도 이 책의 가치는 있다고 생각합니다. 비록 이 책을 끝까지 읽고 여러분이 짤 수 있는 것은 간단한 글씨 몇 개를 화면으로 보여주는 프로그램에 불과하겠지만, 컴파일, 링크, 변수, 함수, 제어문이 무엇인지 이해하게 되었다면 이 책은 최소한의 가치는 가진 책이라고 생각합니다.
이제 다음 마당부터는 좀더 어려운 과정이 시작됩니다. 갈수록 친절한 설명이 줄어들고 복잡한 문법규칙이 나올 겁니다. 예제 프로그램도 점점 복잡해질 겁니다. 그러나 지금까지 잘 따라오셨다면 다음 과정도 어렵지 않게 따라하실 수 있을 것으로 믿습니다. 여러분들을 믿고 좀더 복잡하고 다양한 다음 차원으로 이동하겠습니다.
이제부터는 C++언어의 기본문법을 배우도록 하겠습니다.
지금까지의 내용을 통해서 여러분은 컴퓨터 언어와 C++언어의 기초를 배우셨습니다. 배우신 내용은 기초적인 것이지만 매우 중요한 내용입니다. 사실상 제일 중요한 내용을 배우신 겁니다. 앞으로 배울 내용은 세부적인 C++언어의 문법규칙과 함수들의 사용법입니다. 복잡하고 많은 내용이 나오겠지만 그동안 설명드린 개념만 이해하고 있다면 그다지 힘든 내용이 아닙니다. 그러나 지금까지의 설명한 내용을 제대로 이해하지 못한다면 다음 단계로 넘어가기가 점점 힘들어질 것이므로 이전 내용을 다시 한 번 복습하고 이번 마당을 공부하시기 바랍니다.
이번 마당부터는 C++언어의 전반적인 문법을 설명합니다. 한 가지 알아두셔야 할 점은 앞으로는 이전처럼 친절하고 자세하게 풀어서 설명하지 않으리라는 사실입니다. 자세하게 풀어서 설명하면 이해하는데 도움이 되겠지만 책이 매우 두꺼워져야 합니다. 시중에 나온 책을 살펴보시면 알겠지만 함수의 사용형식만 설명한 라이브러리책이 몇 백 쪽 짜리입니다. 또 컴파일러의 설치와 환경설정, 사용방법만 다룬 책 역시 두꺼운 책으로 따로 판매되고 있습니다. 만약 간단한 예제프로그램과 설명을 곁들인다면 함수 설명에만 몇 천 쪽이 금방 넘을 겁니다. 그래서 앞으로는 좀더 요약된 내용으로 설명드리겠습니다. 그러나 앞서의 과정을 충실하게 이해하고 넘어오신 분이라면 내용을 이해하는데 조금의 어려움도 없을 것으로 생각합니다.
비록 이 책이 초급자를 위한 책이라고 하지만 C++언어에 대한 전반적인 내용은 담고 있어야 합니다. 그래서 이번 마당부터는 책의 구성이 조금 달라집니다. 중요한 개념은 자세하게 설명을 하겠지만 문법이나 함수의 사용법, 예제 등은 간단하게 요약해서 설명하고 지나가겠습니다. 저는 책을 보는 방법만 설명드릴 겁니다. 나머지는 이 책을 보시는 독자 스스로 예제를 분석해가면서 읽어나가야 합니다. 자 그럼 C++언어의 전체적인 구조를 잡아보도록 하겠습니다.
C++언어에서 지원하는 함수도 많지만 컴파일러에서 지원하는 함수는 더욱 많습니다.
C++에서 지원하는 기본 함수는 매우 많습니다. 특히 볼랜드C++와 같은 컴파일러는 지원하는 함수를 더욱 늘렸습니다. 사용법 또한 매우 복잡합니다. 때문에 함수의 사용법을 설명하는 것만으로도 두꺼운 책 몇 권을 써야 할 정도입니다. 이 책에서는 함수 하나하나를 일일이 설명하지 않고 요약 정리해두었습니다. 자세하게 설명을 해주어도 이해하기 힘든 힘수를 사용형식만 보고 이해하기란 쉬운 일이 아닙니다. 그러나 함수와 관련한 각종 개념들을 이해하고 있다면 사용형식만 보고도 어렵지 않게 사용법을 익힐 수 있습니다. 컴파일러 자체에 내장된 도움말을 활용하면 더욱 쉽게 함수 사용법을 익힐 수 있을 겁니다.
함수를 많이 아는 것보다는 함수를 어디에 어떻게 사용해야 하는지 아는 것이 중요합니다.
여러 가지 문법내용 역시 마찬가지입니다. 기둥이 되는 중요한 개념만 익힌다면 나머지 내용은 책을 참고하면서 손쉽게 익힐 수 있습니다. 제 주변의 사람들 중에는 함수를 달달달 외우는 사람들이 있는데 프로그램을 짜는 실력은 그다지 뛰어나지 않습니다. 프로그램을 잘 짜기 위해서라면 함수의 이름을 외우지 않아도 됩니다. 수 많은 함수의 사용법을 외우기란 쉬운 일이 아니며, 또 그럴 필요도 없습니다. 단지 어떤 함수들이 있는지만 대충 알고 있으면 됩니다. 필요한 함수가 있다면 그때그때 라이브러리 책을 뒤져서 사용법을 살펴보면 됩니다. 프로그램을 잘 짜는 사람은 함수를 어디에 어떤 용도로 사용하는 것이 좋은지를 잘 아는 사람이지 함수를 잘 외우는 사람은 아니라는 점을 알아두시기 바랍니다.
함수를 이해하기 위해서 함수와 관련된 요소들을 잘 알고 있어야 합니다. 함수를 구성하고 있는 각종 요소들도 잘 이해하고 있어야 합니다. 마찬가지로 문법규칙을 이해하기 위해서는 문법과 관련된 주요 요소들의 개념을 잘 이해하고 있어야 합니다. C++언어 문법과 관련하여 반드시 알아두어야 할 개념들을 먼저 간단하게 살펴본 뒤에 구체적인 사용법으로 넘어가도록 하겠습니다. 이미 앞에서 설명한 내용들도 있겠지만 복습을 겸해서 다시 읽어주시기 바랍니다.
3.2.1.숫자 1과 문자 1은 어떻게 다른가?
자료형이라는 자료를 나타낼 때 사용하는 자료의 모습을 말합니다.
컴퓨터는 자료를 다루는 기계입니다. 그리고 기본적으로 컴퓨터에서 다루는 모든 자료는 0과 1의 이진수로 다루고 있다고 말씀드렸습니다. 그러나 이것은 컴퓨터의 입장에서 봤을 때 이야기입니다. 사람들로 하여금 0과 1로 된 이진수로 자료를 다루게 한다면 아무도 컴퓨터로 자료를 다루지 않을 겁니다. 그래서 사람들이 사용하기 편하도록 컴퓨터는 자신이 사용하는 이진수를 사람들이 이해하기 쉽도록 다양한 형태의 자료로 변환시켜서 보여줍니다. 때로는 글씨로, 때로는 숫자로, 때로는 그림으로 보여줍니다.
이처럼 다른 형태로 나타나는 자료의 모습을 자료형이라고 말합니다. 자료형은 매우 다양한 형태가 있습니다. 글씨, 숫자, 그림, 소리, 파일, 하드웨어와 같이 다양한 형태의 모습으로 자료형을 표시하고 관리합니다.
C++언어에서도 좀더 편하게 프로그램을 짜고 좀더 편하게 자료를 관리하기 위하여 여러 가지 형태의 자료형을 제공합니다. C++언어에서 사용하는 자료형 중에서 가장 대표적인 자료형은 숫자형과 문자형입니다. 숫자형은 다시 자연수, 정수, 실수 등으로 구별하여 달리 취급합니다. 문자형 역시 문자와 문자열로 나누어서 취급합니다. 정수형이란 글자 그대로 0이나 1, 9, -3과 같은 정수를 말합니다. 주로 숫자계산에 편하게 하려고 만든 자료형입니다. 문자형이란 a, b, M과 같은 문자를 말합니다.
자료형을 구분하는 이유는 자료의 효율적인 처리를 위해서입니다.
이처럼 자료형을 여러 가지로 구분하는 이유는 무엇이겠습니까? 좀더 빠르고 효율적으로 자료를 처리하기 위함입니다. 예를 들어서 199라는 숫자를 이진수로 표현하기 위해서는 1바이트만 있으면 됩니다. 199라는 숫자를 파일로 저장하기 위해서는 1바이트면 되는데 구태여 2바이트나 4바이트를 부여해주고 199를 표시한다면 하드디스크의 용량이 2배나 4배 정도 필요해집니다.
199.00000 이나 199나 표현방법만 다를 뿐 계산값이 같습니다. 따라서 199 대신 199.00000이라고 표현하는 것은 낭비일 뿐만 아니라 보기에도 좋지 않습니다.
그리고 컴퓨터는 199-1을 계산하는 시간과 199.00000-1을 계산할 때의 시간이 다릅니다. 199는 3단위 자리까지만 계산하면 되지만, 199.00000은 8단위 자리까지 계산해야 하기 때문입니다. 그래서 계산 결과는 같지만 계산시간은 다른 것입니다.
이런 이유로 언어프로그램은 다양한 자료형을 가지고 자료를 다루고 있습니다. 구태여 소숫점 이하의 계산이 필요하지 않다면 정수형을 사용하는 것이 좋으며, 소숫점 이하의 계산을 주로 다룬다면 실수형 자료를 사용하는 것이 좋습니다.
필요에 따라서는 형변환을 통해 다른 형태의 자료형으로 변신할 수도 있습니다.
만약 a라는 변수를 정수형 자료를 다루는 변수로 사용하기로 했다면 앞으로 a라는 변수는 정수만 다루게 됩니다. 그러나 어느 순간에는 a라는 변수가 실수형의 자료를 다루어야 할 때도 있을 겁니다. 이런 때는 형변환이라는 방법을 통하여 잠시 실수형으로 변신합니다. 형변환이라는 방법을 통하여 잠시 실수형 자료를 다룰 수 있지만 근본은 정수형 변수임을 잊지 말아야 합니다.
정수 1과 실수 1은 수학적인 계산이 되지만 문자 1은 수학적 계산이 안됩니다.
C++언어에서는 다양한 자료형을 사용하지만 가장 많이 사용하는 자료형은 정수형과 실수형, 문자형 자료 세 가지입니다. 이때 한 가지 주의해야 할 점은 정수형 자료 1과 실수형 자료 1, 문자형 자료 1은 완전히 다른 형태라는 점입니다. 정수형 자료의 1이나 2는 계산이 가능한 숫자입니다. 즉 a라는 정수형 변수에 1을 대입하고, b라는 정수형 변수에 3을 대입했을 경우 a+b=4가 나옵니다. 일반적인 수학공식을 그대로 사용할 수 있는 것이 정수형과 실수형 자료입니다.
그러나 문자형 자료 1은 계산이 가능한 숫자가 아닙니다. 숫자 1이 아니라 글자 1이기 때문입니다. 글자 1은 글자인 abc처럼 1이라는 모양이나 코드값만 가지고 있을 뿐 '한 개'라는 수학적 의미는 전혀 없습니다.
따라서 문자형 자료 1과 3을 더하면 4라는 답이 나오지 않습니다. 글자의 순서대로 더해서 13이 되거나, 두 글자의 아스키코드를 합한 값이 나옵니다. 일반적으로 문자형 자료를 더하면 두 문자의 아스키코드값을 더한 값이 나옵니다. 문자 1은 아스키코드로 49번에 해당하고, 문자 3은 아스키코드 51에 해당합니다. 따라서 '1+3=(49+51)번의 아스키코드=100번 아스키코드=d'라는 결과가 나옵니다. '1+3'은 d가 되는 겁니다. 1과 3이라는 문자를 더하면 d라는 글자가 나옵니다. 조금 황당한 결과죠?
정수 1과 실수 1은 수학적 성질이 틀리므로 계산결과도 다릅니다.
문자 1이 단지 글자로서의 의미만 가지고 있을 뿐 '한 개'라는 수학적 의미는 없다고 부분에 대해서 이해하셨을 것으로 생각합니다. 그럼 '한 개'라는 수학적 의미를 담고 있는 정수 1과 실수 1은 같은 자료형일까요? 역시 다릅니다. 같다면 구태여 자료형을 둘로 구분할 필요 없이 실수 하나로 통일해서 쓰는 것이 낫겠죠.
정수형 자료형과 실수형 자료형의 차이는 수학에서 사용하는 둘의 차이를 생각하면 쉽게 이해할 수 있습니다. 간단한 예로 a÷b=c를 정수형으로 계산해보고 실수형으로 계산해보기 바랍니다.
a, b, c가 정수형일 경우라면 '9÷4=2'가 됩니다. 소수점 자리를 계산하지 않기 때문입니다. 그러나 a, b, c가 실수형인 변수라면 '9÷4=2.25'가 됩니다. 소수점까지 계산하기 때문입니다. 그리고 실수형은 2.000이라는 수수점 표현이 가능하지만 정수형은 불가능합니다. 정수형은 죽으나 사나 2라는 표현 외에는 사용할 수 없습니다. 따라서 계산결과도 표현방법도 정수와 실수는 다릅니다.
이런 이유로 정수형 1과 실수형 1은 다른 자료형입니다.
컴퓨터란 자료를 다루는 기계입니다. 컴퓨터언어로 프로그램을 짠다는 말은 곧 컴퓨터를 이용해서 좀더 효율적으로 자료를 다룰 수 있는 도구를 만든다는 이야기입니다. 때문에 자료의 개념을 이해하고 언어에서 지원하는 자료의 종류와 특징을 파악하는 일은 프로그램 공부의 첫번째 단계가 됩니다. 이 때문에 대부분의 컴퓨터언어 책에서 자료형부터 설명하고 있는 겁니다. 이미 앞 장에서 자료형의 종류와 간단한 개념에 대해서 설명을 했으므로 여기서는 이정도로 설명을 마치고 다음에 좀더 자세하게 설명하도록 하겠습니다.
**요약: 숫자 1은 수학적 계산이 가능한 숫자를 말하지만 문자 1은 1이라는 형태를 보여주는 문자에 불과하므로 수학적 계산을 할 수 없습니다. 또한 정수형 숫자는 소수점 이하 계산이 안된다는 점에서 실수형 숫자와 다릅니다.
3.2.2. 변수를 선언하고 값을 대입해야 하는 이유
변수나 함수도 자료형의 종류에 맞게 구분됩니다.
C++언어의 자료형에 정수형, 실수형, 문자형 등이 있음을 알았습니다. 이 말은 달리 말해 변수의 종류도 정수형, 실수형, 문자형으로 나누어진다는 뜻입니다. 그리고 정수형 변수에는 늘 정수만 사용해야 할 겁니다. 마찬가지로 함수의 종류도 정수형 함수, 실수형 함수로 나누어질 겁니다. 정수형 자료를 다루는 변수는 정수형 변수가 되고, 정수형 자료를 다루는 함수는 정수형 함수가 됩니다.
변수나 함수의 자료형이 무엇인지 알려주는 일이 '선언'입니다.
그렇다면 어떤 변수나 함수가 정수형인지 문자형인지 알려줄 필요가 있습니다. 정수형 변수임을 알려주어야 정수자료를 변수나 함수에 대입할 수 있기 때문입니다. 변수나 함수의 자료형을 알려주는 일을 '변수를 선언한다' '함수를 선언한다'는 말로 표현합니다.
이처럼 '선언한다'라는 표현은 나중에 쓸 함수나 변수에 대한 기본골격을 미리 알려주는 것을 말합니다. 선언한다는 말은 변수나 함수에만 사용하는 것이 아닙니다. 배열이니 포인터니 공용체니 하는 것을 다룰 때도 선언한다는 말을 자주 사용합니다.
변수를 미리 선언해주는 까닭은 프로그램의 문제 발생 원인을 줄이기 위해서입니다.
이처럼 변수를 미리 선언해주는 까닭은 프로그램을 짤 때 문제가 발생하지 않도록 하기 위함입니다. 변수를 미리 선언해주어야 하는 이유는 다음과 같습니다.
첫번째로 변수가 사용할 자리를 미리 잡아두기 위함입니다. 컴퓨터는 메모리라는 작업공간이 있고, 이 안에서 대부분의 작업이 이루어집니다. 자료들을 고치고 변형하고 저장하는 일도 메모리(기억장치)에서 이루어집니다. 그러나 이 자리는 한정되어 있습니다. 따라서 변수가 사용될 것임을 미리 선언해두지 않으면 자리를 배정받지 못할 수도 있고, 결국 그 변수는 작업장에 들어가지도 못하는 신세가 될 수도 있습니다.
변수를 선언해주는 이유는 변수가 활동할 수 있는 자리를 미리 마련하기 위해서입니다.
변수의 선언을 일반 사회의 보기로 들면, 자리 예약을 들 수 있습니다. 어떤 공연의 관람에 참석하겠다는 의사표시를 하면 자리를 마련해줄 겁니다. 오겠다는 사람 수만큼 자리를 마련하고, 식사를 마련하는 것이 일반적인 사회통념입니다. 몇 명의 직원이 올 것인가를 알아야 책상도 마련하고 작업장소도 마련합니다. 그런데 난생 처음 보는 사람이 불쑥 나타나서 '나도 이 회사의 직원이고 지금 이런 일을 해야겠다'면서 자리를 만들어달라고 하면 당황할겁니다. 10명 분의 식사를 준비했는데, 갑자기 이름도 처음 들어보는 5명이 더 나타나서 밥 달라고 하면 문제가 발생합니다. 따라서 만약 견학이나 실습을 하게 될 경우 총무과에서는 참여할 것인지 여부와 몇 명이나 참여할 것인지를 알려주어야 합니다. 그래야 참여하는 사람의 수대로 자리를 마련해둘 수 있기 때문입니다.
따라서 변수를 선언하는 가장 큰 이유는 변수가 활동할 수 있는 자리를 미리 마련해주기 위함입니다. 우리가 사용하는 컴퓨터는 자료를 저장할 때 주소를 배정한다고 말씀드린 적이 있습니다. 여행갈 때 미리 예약을 해두지 않으면 나중에 노숙을 하는 상황이 생길 수도 있습니다. 미리 전화를 걸어서 몇 명이 간다고 말을 해두어야 나중에 호텔에 도착했을 때 여행 간 인원이 들어갈 수 있는 방을 배정받을 수 있습니다. 호텔방을 배정받기 위해서 예약을 하는 것과 마찬가지로, 변수를 저장하기 위한 주소를 배정받기 위해서 변수를 선언하는 겁니다.
변수를 선언해주는 또 다른 이유는 자료형이 무엇인지 미리 알려주기 위해서입니다.
변수를 미리 선언하는 두번째 이유는 변수가 다룰 자료형이 무엇인지 미리 알려주기 위함입니다. a라는 변수는 정수만 다루는 변수라고 미리 알려주지 않는다면 a라는 변수에 어떤 자료를 넣어야 할지 고민해야 합니다. 일단 아무 자료나 넣는다고 정수를 넣었는데, 나중에 보니 그 변수가 실수형을 다루어야 하는 변수라고 생각해봅시다. 이미 정수형 자료를 넣었으니 다시 실수형 자료를 넣기가 매우 어려울 겁니다. 때문에 변수를 선언할 때 자료형을 함께 알려줌으로써 정수를 다루어야 할 변수에 실수형 자료를 넣는 잘못을 방지할 수 있습니다. 정수형 변수에 실수를 넣으면 엉뚱한 자료를 넣었다고 알려주기 때문에 변수를 잘못 사용했다는 것을 발견할 수 있습니다.
예를 들어서 식당, 호텔방을 예약하거나 수영복을 미리 준비해놓으라고 명령 내리면서 10명이라는 사람 수만 밝히고 남녀노소 구분은 알려주지 않았다고 합시다. 예약받은 곳에서는 막연하게 방청소를 하고 아무 수영복이나 준비해둘 수밖에 없습니다. 막상 10명이 와서 보니 여자 수영복이나 어린이 수영복이 없습니다. 그렇다고 해서 여자가 남자 수영복을 입고 수영할 수도 없는 노릇입니다. 또 남자나 여자가 가운을 바꾸어입고 호텔방을 들락거릴 수도 없습니다. 따라서 자리를 예약할 때는 몇 명이냐는 숫자도 중요하지만 그 몇명이 어떤 특성을 지닌 사람이냐도 함께 알려주어야 합니다. 남자인지 여자인지, 나이는 어떻게 되는지 등을 알려주어야 정확한 음식, 방 배정, 옷준비가 가능합니다.
선언만 하고 대입되지 않은 변수는 쓰레기값을 가지게 됩니다.
그외에도 몇 가지 이유가 더 있지만 변수를 선언하는 가장 큰 이유는 이 두 가지입니다. 변수가 사용할 자리를 미리 확보하기 위함과 변수가 다룰 수 있는 자료형을 선언해둠으로써 엉뚱한 자료를 다루는 일이 없도록 하기 위함입니다.
그리고 이렇게 선언된 변수에는 어떤 자료를 대입해야 합니다. 만약 선언만 하고 아무런 자료를 대입하지 않는다면 변수는 텅 빈 채로 있게 됩니다. 때로는 쓰레기값이라는 쓸모 없는 값만 가지고 있을 수도 있습니다.
대입을 하지 않는다는 말은 곧 변수나 함수의 정의가 이루어지지 않는다는 말입니다. 정의가 이루어지지 않았으니 변수의 본질이 무엇인지 알 수가 없는 일입니다. 그래서 변수를 선언한 뒤에는 한 번이라도 정의 즉, 변수에 값을 대입하는 일이 필요합니다. 그래야만 변수가 쓰레기값을 갖지 않습니다.
사람의 사회를 생각해봅시다. 다섯 명이 저녁을 먹으러 내려가겠다고 하면 식당에서 다섯 명분의 자리를 마련해둘 겁니다. 그런데 실제로 그 자리에 아무도 오지 않고, 아무도 앉지 않는다면 미리 자리를 마련해준 사람은 매우 화가 날 겁니다. 힘들게 다섯 자리를 마련했는데 아무도 오지 않았으니까요. 또한 준비한 음식은 결국 버려야 합니다.
변수를 선언한 뒤에는 쓰레기값을 갖지 않도록 어떤 값을 대입해주어야 합니다.
변수도 마찬가지입니다. 식당에 자리를 마련했으면 가서 한 수저라도 들고 와야 하는 것이 예의인 것처럼, 변수를 선언했으면 어떤 값을 대입시켜주어서 변수의 기본 임무를 다하도록 해주어야 합니다. 이런 이유로 변수를 선언했으면 변수에 어떤 값을 대입해주어야 합니다. 물론 변수의 자료형에 알맞는 자료를 대입해주어야 합니다.
변수는 한 자리에 모아서 선언해주는 것이 보기에도 좋고 내용 파악에도 좋습니다.
이 이외에도 변수를 선언함으로써 얻는 장점들이 여럿 있습니다. 변수를 한 자리에 모아서 선언해두기 때문에 프로그램에서 사용하는 변수의 종류가 어떤 것인지 한 눈에 파악할 수 있으며, 어떤 이유로 변수를 사용하는지도 쉽게 파악이 됩니다. 또한 어떤 변수를 선언할 것인가를 생각하게 되므로 프로그램을 좀더 체계적으로 짤 수 있는 습관을 제공합니다. 또한 잘못 사용할 수 있는 변수를 제거하는 기능도 제공합니다. 그래서 변수를 사용하기 전에 변수를 선언하도록 하는 겁니다.
**요약: 변수를 미리 선언하는 이유는 변수를 사용할 수 있는 자리를 예약받기 위해서이며, 변수의 자료형이 무엇인지 미리 알려주기 위해서입니다. 변수는 선언만 하고 갑이 대입되지 않을 경우 쓰레기값을 가지게 됩니다. 따라서 변수를 선언한 뒤에는 값을 대입해
주어야 하며 가능한 한 자리에 모아서 선언해주는 것이 좋습니다.
3.2.3. 함수로부터 돌려받는 복귀값이란?
함수를 사용할 때는 인수 또는 인자를 이용한다고 말씀드렸습니다. 함수가 단순히 어떤 동작만 한다면 큰 의미가 없을 겁니다. 중요한 것은 함수가 만들어낸 결과입니다. 때문에 이 결과값을 함수를 호출했던 프로그램에 돌려주어야 합니다.
예컨대 두 수의 합을 구하는 함수를 하나 만들었다고 합시다. 이때 그 함수를 수행하기 위해서는 인수로서 두 개의 숫자가 제공되어야 합니다. 만약 두 수를 더해주는 sumab()라는 함수의 인수 두 개로 3과 4를 주었다면, 이 함수는 두 개의 수를 더해서 7이라는 계산결과를 낼 겁니다. 이때 7이라는 계산결과를 결과값 또는 복귀값, 반환값, 리턴값이라고 말합니다. 그리고 이 결과값을 어딘가에 돌려줄 경우에 '결과값을 돌려준다'고 표현합니다. 돌려주는 결과값이라 하여 복귀값(리턴값)이라는 표현을 많이 사용합니다.
예를 들어서 두 수를 더한 계산결과를 화면으로 보여주는 함수를 하나 만들었다고 합시다. 이 함수를 위해서 먼저 두 수를 더해주는 함수부터 만들어야 합니다. 그래서 이 함수에 두 개의 인수를 주고, 두 인수의 합을 돌려받아야 합니다. 그리고 이 합을 화면으로 출력하라는 함수를 하나 만들면 두 수의 합을 화면으로 보여줄 겁니다.
결과값으로 사용할 수 있는 것은 숫자나 문자 이외에도 컴퓨터가 다룰 수 있는 모든 자료가 가능합니다.
**요약: 함수가 어떤 연산을 처리한 뒤에 그 결과로서 돌려주는 결과값은 복귀값(=리턴값) 또는 반환값이라고 합니다. 복귀값으로 돌려줄 수 있는 자료는 컴퓨터가 다룰 수 있는 모든 자료가 가능합니다.
3.2.4. 토큰의 종류- 키워드, 구두점, 공백문자, 명칭 등
C++언어의 기본문법 단위를 토큰이라고 하며 키워드, 구두점, 명칭, 상수, 연산자, 문자열이 있습니다.
그동안 우리는 C++언어의 문법을 구성하는 명령어와 낱말을 이용하여 소스파일을 만들어왔습니다. 그동안 무심코 사용했던 이들 낱말을 토큰(token)이라고 합니다. 우리말로는 상징이라고 합니다. 이런 상징은 C언의 문법에 사용되는 각종 낱말을 기능과 유형별로 구분한 것인데 분류방법에 따라서 조금씩 다르게 분류됩니다. 그러나 이 중에서도 중요한 토큰은 다음과 같이 7가지로 구분합니다.
키워드(keyword)
구두점(punctuator)
공백문자(whitespace)
명칭(identifier)
상수(constant)
연산자(operator)
문자열(string literal)
C++언어를 표현하기 위해 필요한 낱맡을 키워드라고 하며 예약된 낱말입니다.
앞서 우리가 프로그램을 짤 때 사용한 여러 가지 C++언어의 명령어들이 있습니다. 변수를 선언할 때 사용한 int, float, char 등이 있으며 제어문에서 사용한 IF, CASE 등이 있습니다. 이들 낱말은 C++언어를 표현하기 위해서 꼭 필요한 낱말들입니다. 이런 낱말들을 키워드(keyword)라고 말합니다. 다른 말로 예약어(reserved word)라고 합니다.
즉 키워드는 C++언어로 프로그램을 짜기 위해서 사용하는 낱말들을 말합니다. 보통 이런 키워드는 예약되어 있는 낱말이므로 키워드에 해당하는 낱말을 변수나 함수 이름으로 사용하면 안됩니다. 같은 이름이라서 충돌이 일어날 수 있기 때문입니다.
표: C++언어에서 사용하는 키워드
asm auto break case cdecl char class const continue default delete do double else enum extern far float for friend goto huge if inline int interrupt long near new operator pascal private protected public register return short signed sizeof static struct switch template typedef union unsigned virtual void volatile while _AH _asm _AL _AX _BH _BL _BP _BX _cdecl _CH _CL _CS _CX _DH _DI _DL _DS _DX _ES _export _far _fastcall _FLAGS _huge _interrupt _loadds _near _pascal _saveregs _seg _SI _SP _SS
요소들을 구별하기 위해 사용하는 기호를 구두점이라고 합니다.
그리고 C++언어에서 사용하는 요소들을 구별하기 위해서 사용하는 기호를 구두점(punctuator)이라고 합니다. 다른 말로 각 요소를 분리한다고 하여 분리자라고도 합니다. 이미 우리가 그동안 무심코 사용해온 것이지만 정리하면 다음과 같은 것이 있습니다. 표의 구두점 구분은 볼랜드 C++에서 사용하는 구두점을 기준으로 나눈 것입니다.
표: 구두점의 종류
구두점
사용하는 곳
보기
[]
꺾쇠묶음(barcket). 포인터 선언이나 배열의 크기를 지정할 때 사용
char s[];
char s[99];
()
손톱묶음(parenthesis). 각종 제어문의 조건식이나 함수의 매개변수(인수) 목록을 지정할 때, 함수 포인터를 선언할 때 사용
if(a>b) a=10;
printf("%d",n);
int (*jegob)();
{}
활묶음(brace). 블럭의 시작과 끝을 나타낼 때. 구조체나 공용체의 틀에 또는 배열을 초기화할 때 사용
if(a>b) {a=0; b=1}
char s[2]={'a','b'};
*
별표(asterisk). 포인터를 선언할 때 사용
char *s;
,
쌍점(comma). 변수나 함수 등을 선언하거나 배열을 초기화할 때 함수의 매개변수를 나열할 때 등에 사용
int n, m, l;
jegob(i,j,k)
char s[2]={'a','b'};
;
쌍반점(semicolon). 한 문장(명령문)의 끝을 나타내거나 for문에서 사용
int n, m;
for(n=1;n<10;n++)
=
같기표(equal sign). 배열을 초기화할 때 사용
char s[2]={'a','b'};
:
콜론(colon). 라벨이름 뒤나 case 라벨에 사용
first:
case 0 : break;
...
줄임표(ellipsis). 함수원형 등에서 생략을 해야할 때 사용
int printf(char *format, ...);
#
우물정자(pound sign). 전처리기 지시자(매크로)의 접두어로 사용
#include
#define
토큰을 구별하기 위한 공백문자로 빈칸, 탭문자, 줄바꿈문자 등을 사용합니다.
토큰의 각 요소들을 구별하기 위해서 공백문자를 이용합니다. 공백문자는 빈칸글쇠(space bar)를 이용해서 집어넣는 빈칸을 말하기도 하지만 탭문자와 줄바꿈문자(개행문자)도 공백문자로 취급합니다. 그리고 이 세 문자는 동일하게 취급합니다. 동일하게 취급된다는 말은 탭을 이용해서 넓게 벌린 칸이나 스페이스바를 이용해서 벌린 한 칸이 모두 같은 공백문자라는 점입니다. 공백문자는 빈칸(space char)문자와 다릅니다.
보기
int n=3;
printf("%d is number !!",n);
보기에서 첫번째 줄을 봅시다.
___int n=3;
↓
밑줄부분의 공백이 각각의 토큰을 구별해주는 공백문자입니다.
_______printf("%d#is#number####!!",n);
↓ ↓↓ ↓↓↓↓
#으로 표시한 이것은 문장의 한 구성요원인 글자로서의 빈칸입니다.
밑줄로 보이는 이것이 공백문자로 윗 문장과 printf() 함수 사이를 구별해주고 있습니다.
명칭은 각 변수를 구별하기 위해 사용하는 변수나 함수의 이름을 말합니다.
그리고 토큰 중에 명칭이라는 것이 별도로 들어있습니다. 명칭은 우리가 사용해온 변수나 함수의 이름을 말합니다. 즉 이름을 통해 각 변수를 구별하기 때문에 다른 말로 식별자라고 합니다.
그런데 이런 변수나 함수의 이름을 사용할 때는 나름대로의 규칙에 따라야 합니다.
표: 명칭과 관련한 규칙
1. 명칭으로는 영문자와 숫자, 밑줄기호(_)만 사용할 수 있습니다. 그러므로 /=$%*&@#+ 등의 특수 문자는 명칭으로 사용할 수 없습니다.
2. 숫자는 명칭의 첫글자로 사용할 수 없습니다.다시 말해서 첫글자는 반드시 영문자로 시작해야 하며 숫자는 그 다음에 붙여서 사용할 수 있습니다. 그러므로 a1이라는 변수 이름은 가능하지만 1a라는 변수 이름을 사용할 수 없습니다.
3. C++에서는 처음의 32문자까지만 구분해주고 그 다음 문자는 무시해버립니다.물론 변수 이름을 32자 이상으로 정해도 상관 없습니다. 그러나 32자 이후의 문자는 컴파일러에서 사용하지 않고 버리니다.
4. C++에서는 대소문자를 구분합니다. 따라서 변수 A와 a는 각기 다른 변수입니다.물론 Tax와 TAX, tax, TaX, taX도 모두 각기 다른 변수로 취급합니다.
5. 키워드를 비롯한 기타 다른 토큰을 명칭으로 사용할 수 없습니다. 당연한 이야기겠죠. int, double, if, _AS 등의 예약된 이름은 변수 이름으로 사용할 수 없습니다.
그외 그동안 우리가 사용한 상수(constant)와 연산자(operator), 문자열(string literal)도 각기 성격이 다른 하나의 토큰으로 분류합니다.
**요약: C++언어의 기본문법 단위를 토큰이라고 하며, '볼랜드 C++'과 같은 컴파일러는 키워드, 명칭, 상수, 문자열, 연산자, 구두점의 여섯 가지 토큰을 사용합니다. 각 토큰 사이는 빈칸, 탭문자, 줄바꿈문자의 세 가지 공백문자로 구별합니다. 그리고 일반적으로 명
령어라고 부르는 키워드는 C++언어에서 미리 예약한 이름이므로 키워드에 해당하는 낱말은 변수나 함수이름으로 사용하지 않아야 합니다. 명칭은 변수나 함수의 이름을 말하며 몇 가지 규칙에 따라서 사용해야 합니다.
3.2.5. C++언어 프로그램은 왜 그리 많은가?
C++언어 프로그램은 초기 C++언어에 기능과 함수를 보강한 프로그램입니다.
C++언어를 배우다보면 다양한 C++언어프로그램에 대해서 듣게 됩니다. 볼랜드 C++, 비주얼C++ 외에도 다양한 C++언어프로그램이 있습니다. 왜 이렇게 많은 언어프로그램이 있는 걸까요? 이들 프로그램은 어떻게 다른 걸까요? 의문을 가졌을 겁니다.
이들 프로그램은 좀더 편하게 프로그램을 짤 수 있는 도구들입니다. 정확하게 말하면 컴파일러프로그램이라고 할 수 있지만 요즘은 개발환경에서부터 최종실행파일을 만들기까지의 모든 도구가 포함되어 있기 때문에 컴파일러프로그램이라는 말보다는 언어프로그램이라는 말을 더 많이 사용합니다.
처음에 발표된 C언어는 함수와 명령어가 그리 많지 않았습니다. 때문에 초기의 C++언어를 이용해서 프로그램을 짜려니 불편한 점이 한 둘이 아닙니다. 그래서 이러한 불편한 점을 개선하고, 좀더 편하게 프로그램을 짤 수 있도록 여러 가지 함수를 추가합니다. 이렇게 기능과 함수를 추가한 C++언어 프로그래밍 도구는 매우 편하고 유용했습니다. 그래서 이 도구를 돈을 받고 팔기에 이릅니다. 때문에 이들 도구는 초기 C++언어보다 훨씬 강력한 프로그램을 짤 수 있으나 초기 C++언어와는 호환되지 않는 문제가 발생합니다.
예를 들어서 초기 C++언어에는 윈도용 프로그램을 만드는 일이 불가능했습니다. 그래서 A사는 윈도용 프로그램을 만들 수 있는 기능을 추가한 컴파일러를 출시한 다음에 '우리가 개발한 C++언어 프로그래밍 도구를 사용하면 윈도용 프로그램도 만들 수 있습니다' 하고 광고합니다. 그러면 또 다른 회사는 A사보다 더 뛰어난 도구를 만들어냅니다. B사는 '우리는 윈도용 프로그램에서 동영상을 보여주는 함수도 제공합니다.'라고 선전하면서 C++언어 프로그램을 팝니다. 또 다른 C사는 '우리는 아주 편리한 편집기와 컴파일러를 제공하는데, 이것을 이용하면 편집기 상태에서 바로 컴파일을 해볼 수 있고, 에러가 생기면 무슨무슨 에러가 났는지 바로 알려주므로 프로그램 짜는 시간이 획기적으로 줄어든다'고 광고합니다. 그럼 또 다른 회사에서 '우리는 컴파일 시간이 절반으로 줄어든 엄청 빠른 컴파일러를 제공한다.'고 광고하면서 새로 만든 언어 프로그램을 팔아먹습니다.
국내에서는 터보C, 볼랜드C++, 비주얼C++이 인기를 끌었습니다.
이런 식으로 프로그램을 짜는 도구를 만드는 회사마다 자기네 회사에서 만든 언어프로그램을 사용하면 프로그램을 개발하는 시간이 획기적으로 줄어들 뿐만 아니라 좀더 강력한 기능을 가진 프로그램을 만들 수 있다고 자랑합니다. 이런 경쟁 속에서 태어난 것이 여러 회사에서 나온 C++언어 프로그램입니다. 그동안 많은 프로그램이 나왔지만 현재는 IBM용 C++언어 프로그램으로는 '볼랜드C++'과 '비주얼C++'이 가장 많이 사용되고 있습니다. 그러니까 이들 언어프로그램은 초기의 C++언어가 가진 함수와 기능을 보강하고, 다양한 기능을 가진 개발환경을 제공해주는 개발도구인 셈입니다.
문제는 이들 제품간에 호환성이 없다는 것입니다. 초기C나 C++언어의 함수와 문법만을 사용해서 프로그램을 짰다면 어떤 컴파일러에서도 컴파일이 가능합니다. 이는 그동안 우리가 짠 예제를 '볼랜드 C++ 3.1'과 '비주얼 C++ 6.0'에서 동시에 컴파일 가능했던 점을 통해 알 수 있습니다. 즉 그동안 우리는 표준 C++언어의 문법으로만 프로그램을 짜온 것입니다.
그러나 볼랜드C++에서만 제공하는 함수를 이용해서 프로그램을 짰다면 비주얼C++로 컴파일 할 경우 에러가 날 겁니다. 마찬가지로 비주얼C++에서만 제공하는 함수를 이용해서 짠 프로그램을 볼랜드C++로 컴파일해도 에러가 납니다. 강력한 기능을 가진 함수를 이용해서 프로그램을 짜므로 프로그램의 개발이 좀더 편하고 빨라진 반면 호환성은 점점 떨어지는 셈입니다.
기능이 다양해진 대신 컴파일러 사이의 호환성이 없어집니다.
만약 어떤 컴퓨터에서도 컴파일할 수 있는 프로그램을 만들고자 한다면 초기 C++언어의 문법과 함수에 맞게 짜야 합니다. 초기 C++언어의 문법을 이용해서 짠 프로그램은 대부분의 C++언어 프로그램에서 지원하기 때문입니다. 그러나 초기 C++언어 문법만 가지고 성능이 좋은 프로그램을 짜기란 매우 어려운 일입니다. 결국 하나의 언어를 선택해야 하는데, 각 언어간의 호환성이 점점 적어지기 때문에 어떤 언어를 선택해야 할 지 신중하게 고려해야 합니다.
이미 이 책을 사신 분은 다른 언어 대신에 C++언어를 택한 분입니다. 그러나 요즘은 C++언어도 세부적으로 분화되었습니다. 그런가하면 각 언어들이 서로 비슷한 구조와 문법을 가지고 있습니다. 때문에 C++언어를 공부한 분은 볼랜드C++을 비롯하여, 비주얼배식, 델파이까지 어렵지 않게 배울 수 있습니다. 또한 저작도구인 툴북이나 디렉터 등도 어렵지 않게 익힐 수 있고, 폭스프로나 클리퍼 등의 데이터베이스 관련 프로그램도 쉽게 익힐 수 있습니다. 많은 언어와 저작도구들이 C++언어의 구조를 기반으로 하여 발전해왔기 때문입니다.
이 책은 기본 컴파일러로 여러 가지 언어 프로그램 중에서 볼랜드C++이라는 프로그램을 선택했습니다. 때문에 그동안도 그래왔지만 앞으로는 볼랜드C++을 이용하여 프로그램을 작성하고 컴파일합니다. 물론 볼랜드C++을 이용해서 프로그램을 짠다는 것은 곧 C++언어로 프로그램을 짠다는 것과 같은 말입니다.
**요약: C++언어 프로그램이 많은 이유는 컴파일러를 만드는 회사에서 나름대로 고유한 기능을 추가하면서 제품을 출시했기 때문입니다. 그러나 각기 다른 회사에서 나온 C++언어 프로그램으로 짠 소스파일은 서로 호환성이 없어서 다른 언어프로그램으로는 컴파일
이 되지 않습니다.
3.2.6. 내장함수, 사용자정의함수, 라이브러리의 관계
C++언어의 각종 함수를 모아놓은 파일을 라이브러리 파일이라고 합니다.
C++언어는 기본적으로 함수로 이루어진 언어입니다. 그러나 초기 C++언어에서 지원한 함수의 종류는 많지 않습니다. 따라서 자신이 필요로 하는 프로그램을 짜기 위해서는 사용자 스스로 함수를 만들어야 합니다. 사용자가 만든 함수를 사용자정의함수라고 말합니다. 그렇다면 원래부터 C++언어에서 지원하던 함수는 뭐라고 부르겠습니까? 보통은 기본함수라고 말합니다.
즉 기본함수를 이용하여 새로운 함수를 계속 만들어나가는 겁니다. 그런데 사용자가 만든 함수가 매우 훌륭한 함수였다고 합시다. 다른 프로그램에서도 자주 사용할 수 있는 유용한 함수를 만들었다면 이러한 함수를 모아두었다가 또 다른 프로그램을 짤 때 사용할 수 있을 겁니다. 사용자가 만든 함수들을 모아둔 파일을 라이브러리 파일이라고 합니다. 라이브러리는 도서관이라는 뜻이니까, 컴퓨터언어에서 라이브러리라는 개념은 함수들의 도서관이라고 봐도 무방합니다.
잘 만든 함수를 컴파일 한 다음에 이들을 라이브러리 파일에 하나씩 첨가해둡니다. 그리고 이렇게 만든 라이브러리파일의 유용가치가 높아지면 라이브러리파일을 팔기도 합니다. 또 언어프로그램을 파는 회사들도 좀더 강력한 함수를 만들어 라이브러리로 제공합니다.
컴파일러에서 기본적으로 제공되는 함수를 내장함수 또는 기본함수라고 합니다.
만약 C언어 프로그램에서 제곱근을 구하는 함수를 제공하지 않는다면 사용자가 제곱근을 구하는 함수를 만들어야 합니다. 사용자가 제곱근을 구하는 함수를 만드는 일은 쉬운 일이 아닙니다. 또 제곱근을 구하는 함수를 만들 수 있다 하더라도 시간이 꽤 오래 걸릴 겁니다. 그런데 볼랜드 C++이라는 언어프로그램에서 제곱근함수를 제공해준다면 사용자가 제곱근함수를 만들지 않아도 되므로 매우 편합니다.
그동안 우리들이 배워온 prinft() 함수를 비롯하여 여러 가지 함수는 대부분 C언어 프로그램에서 제공하는 함수들입니다. 이처럼 C++언어 프로그램(또는 컴파일러)에서 제공하는 함수를 내장함수라고 합니다. 또는 기본함수라고 합니다. 프로그램에 기본적으로 내장되어 있는 함수라는 뜻입니다.
그리고 C++언어 프로그램에서 제공하지 않기 때문에 사용자가 직접 만든 함수는 사용자정의함수라고 합니다. 이들 함수를 나중에 사용할 수 있도록 모아둔 파일은 라이브러리라고 합니다.
**요약: 내장함수는 언어프로그램에서 제공하는 함수들을 말하고, 함수들을 만들어서 모아놓은 파일을 라이브러리라고 합니다. 사용자들이 직접 만든 함수는 사용자정의 함수라고 합니다.
3.2.7. 주소 또는 번지
주소란 각종 자료가 위치할 컴퓨터 내의 위치를 말합니다.
프로그램을 짜는 사람이 가장 골머리를 앓는 부분이 주소와 관련된 내용입니다. 앞서 변수를 미리 선언해두면 자리를 마련해둔다고 했습니다. 이때 마련하는 자리는 나름대로의 위치가 정해져 있을 겁니다. 주소의 개념을 넓게 생각하면 무슨 동 몇 번지라고 표현할 수 있고, 좁게 생각하면 한 건물 안에서 몇 층 몇 호라고 표현할 수 있습니다. 대부분의 작업공간은 주소를 가지고 있습니다. 집도 공장도 사무실도 모두 주소를 가지고 있습니다. 그런데 하나의 주소에 아무런 관계가 없는 두 사람을 집어넣으면 어떻게 되겠습니까? 큰 문제가 발생할 겁니다. 비행기표를 끊고 탔는데, 같은 좌석번호에 두 명이 배정되었다거나 호텔 방에 들어갔더니 다른 사람들이 자기가 예약한 방이라고 우기면 난리가 납니다. 집을 하나 샀는데 이중 등기가 되었다 해도 문제입니다. 통상 하나의 주소에는 한 명의 소유자를 인정하기 마련입니다.
마찬가지로 컴퓨터 안에도 각종 주소가 있고 각 주소를 점유할 수 있는 소유자도 한 명이어야 합니다. 컴퓨터의 주기판에 장착된 부품이 나름대로 고유한 주소를 가지고 있습니다. 그러나 프로그램을 짤 때 가장 중요한 주소는 역시 램의 주소입니다. 램을 하나의 작업공간인 사무빌딩이나 공장으로 생각해봅시다.
주인인 내가 하드디스크에 든 파일목록을 정리해서 프린터로 출력하라고 명령을 내렸습니다. 그런데 컴퓨터가 파일목록을 정리한 자료는 일단 3층 10호 방에 넣어두고, 복사할 때는 2층 4호 방에 있는 자료를 가져다가 프린터로 출력했다고 합시다. 이러면 작업내용이 엉망이 되는 셈입니다. 그러므로 파일목록을 정리한 자료를 3층 10호 방에 보관해두라고 했으면, 나중에 그 자료를 가져올 때도 3층 10호 방에 가서 가져와야 합니다. 엉뚱한 방을 찾아들어가면 골치 아픈 문제가 생깁니다.
컴퓨터에서 다루는 주소는 인간 세계의 주소와 같은 개념입니다.
컴퓨터를 다루거나 프로그램을 짜는 사람이 가장 골치 아프게 생각하는 것이 바로 주소와 관련한 내용입니다. 몇 층 몇 호실에 무슨 자료를 넣어두었는지 일일이 파악을 하고 있어야 하기 때문입니다. 문제는 이들 주소가 사람들이 알기 쉽도록 표기되지 않고 복잡한 이진수나 16진수로 표시된다는 점입니다. 그러다보니 1333번지에 있는 자료를 가져와서 더하라고 명령을 내려야 하는데 1332번지 자료를 가져와서 더하라고 명령을 내리기 일쑤입니다.
우편물을 정확하게 배달하는 것이 쉬운 일이 아닌 것처럼 원하는 주소에 원하는 자료를 배달하고 다시 가져오는 일도 쉬운 일이 아닙니다. 우편물에 우편번호와 주소를 정확하게 써야 하는 것처럼 컴퓨터에서도 정확한 주소를 적어주고 명령을 내려야 자료의 유실을 막을 수 있습니다. 하여간 컴퓨터에서 말하는 주소는 일반적인 사회에서 말하는 주소와 같은 개념이라는 점을 알아두시기 바랍니다.
**요약: 컴퓨터가 자료를 저장할 때는 일정한 규칙에 의해서 정한 주소(또는 번지)를 사용합니다. 즉 주소란 컴퓨터가 자료를 저장해둔 위치를 가리키는 말입니다. 한 주소에는 하나의 자료만 저장할 수 있습니다.
3.2.8. 인터럽트를 건다는 뜻은?
인터럽트는 프로그램의 실행을 중단시키고 작업을 가로채는 행위를 말합니다.
인터럽트라는 말에서 농구의 가로채기를 떠올렸다면 정확하게 의미를 잡은 것입니다. 인터럽트(interrupt)는 프로그램의 수행을 일시적으로 가로막는 행위를 뜻합니다. 인터럽트는 프로그램의 동작과정 중 매우 중요한 일을 합니다. 가장 대표적인 일로 어떤 프로그램의 실행을 중간에 끊고 싶을 때 사용합니다. 프로그램의 실행을 중간에 가로막는 행위는 프로그램을 실행하여 계산결과를 내는 일보다 더 중요합니다. 그래야만 원치 않는 결과를 막을 수 있기 때문입니다.
예를 들어서 어떤 디렉토리에 있는 파일을 전부 지우라는 명령을 내렸다고 해봅시다. 명령을 내리고 나니 지우면 안되는 파일이 생각났습니다. 이럴 때 파일을 전부 지우라는 명령을 중간에 취소해야 합니다. 만약 중간에 이 명령의 실행을 멈출 수 없다면 처음 내린 명령대로 파일을 몽땅 지우고 말겁니다. 이처럼 명령을 잘못 내렸다고 생각할 때 또는 더 중요한 다른 작업을 해야할 때는 지금 수행하는 프로그램의 기능을 멈추게 할 필요가 있습니다. 문서내용을 전부 프린터로 출력하라고 명령을 내린 후에 생각해보니 전부 프린트할 필요는 없고 몇 쪽만 출력하면 됩니다. 이럴 경우에는 출력기능을 가로채서 그만 두라고 해야 합니다. 안그러면 아까운 종이를 낭비하면서 문서내용 전부를 출력할 겁니다.
현재 진행중인 작업을 멈추게 할 경우 '인터럽트를 건다'고 표현합니다.
우리가 흔히 알고 있는 인터럽트는 이처럼 프로그램의 실행을 중간에 멈추어야 할 필요가 있을 때 사용합니다. 파일을 지우라고 명령을 내린 후에 취소하고 싶을 때는 [Ctrl]+[C]를 같이 누르면 됩니다. 그러면 브레이크 기능이 실행되면서 도스명령을 멈출 수 있습니다. 또 아래아한글로 출력하는 도중에 글쇠를 누르면 출력을 취소할 수 있습니다. 이렇게 현재 하던 작업의 수행을 중간에 멈추게 할 때 '인터럽트를 건다'고 말합니다.
단순하게 말하면 현재 작업중인 프로그램의 실행을 멈추게 하는 것을 말하지만, 복잡하게 말하자면 동작중인 프로그램 작업을 빼앗아오는 일이나 입출력 과정에서 자료를 내빼오는 작업 등을 일컫기도 합니다.
인터럽트란 개념은 상황에 따라서 조금씩 다른 의미로 사용하기 때문에 한 마디로 이것이 인터럽트라고 말할 수는 없습니다. 다만 현재 작업중인 프로그램의 수행이 정상적으로 끝나도록 기다려주지 않고 다른 프로그램이 중간에서 뭔가 가로막고 딴 짓을 할 경우를 뜻한다고 생각하면 됩니다. 그러니까 '인터럽트를 건다'고 하면 뭔가 지금 동작이 정상적으로 끝날 때까지 기다리지 못하고 중간에 딴 짓을 하도록 하는 행위를 말합니다.
**요약: 인터럽트란 컴퓨터의 현재 동작을 중단시키고 작업을 가로채는 행위를 말합니다. 인터럽트는 프로그램의 실행을 중간에 중지시킬 때 유용하게 사용하는 개념입니다.
3.2.9. 배열이란 무엇인가?
배열은 변수의 묶음으로 변수가 단독주택이라면 배열은 공동주택에 해당하는 개념입니다.
프로그램을 짜면서 변수를 다루다보면 몇 가지 불편한 점이 생깁니다. 첫번째로 불편한 점은 변수 하나에 하나의 자료만 넣어야 한다는 점입니다. 즉 백 개의 다른 자료를 사용하기 위해서는 백 개의 변수를 선언해주고 백 개의 변수이름을 지어준 다음에 하나씩 하나씩 자료를 대입해주어야 하는 겁니다. 이것은 매우 번거로울 뿐만 아니라 프로그램의 자동화에도 걸림돌이 됩니다.
여기에서 이런 생각을 가질 수 있습니다. 변수를 한 번만 선언해주고 변수 이름도 하나만 사용하면서 백 개의 자료를 따로따로 다룰 수 있는 방법은 없을까? 이런 생각을 토대로 해서 나온 개념이 배열이라는 개념입니다. 배열은 쉽게 말하면 여러 개의 자료를 다룰 수 있는 변수라고 보면 됩니다. 단독주택을 변수라고 생각하면 배열은 빌라나 아파트 쯤에 해당한다고 보시면 됩니다. 봉천동 23-1번지라는 주소를 가진 단독주택에는 집이 한 채이므로 소유주가 한 명이고 당연히 집에 어떤 물건을 집어넣거나 빼 갈 수 있는 권리도 소유주 한 명에게 부여됩니다. 그러나 아파트나 빌라는 조금 다릅니다. 23-1번지라는 하나의 번지를 가지고 있지만 수 십 명의 소유주가 있고, 자기 집에 어떤 자료가 물건을 넣었다 뺐다 하는 것도 각각의 소유주 권한입니다.
만약 23-1에 백두산빌라라는 집이 있다고 생각해봅시다. 이럴 경우에 이 빌라에 사는 사람들은 23-1번지라는 번지와 금강빌라라는 이름을 공통적으로 사용합니다. 그러나 자료를 넣고 뺄 때는 금강빌라 101호나 금강빌라 302호라는 호수를 붙여서 사용할 겁니다. 배열도 마찬가지입니다. a=1이라는 명령을 이용하면 a라는 변수를 1을 대입하라는 뜻이 되지만 배열을 사용할 때는 'a[2]=5'과 같이 사용해야 합니다. 이 명령은 a라는 배열의 2번 방에 5라는 숫자를 대입하라는 명령어입니다.
배열은 0번부터 시작하므로 a[2]는 두번째 방이 아니라 세번째 방입니다.
한 가지 주의할 점은 컴퓨터의 특성상 배열은 0번부터 시작한다는 점입니다. 즉 a[2]라는 배열은 2번방이지 두번째 방은 아니라는 사실입니다. a[2]라는 배열은 a라는 배열의 세번째 방이 되는 것입니다. 첫번째 방은 a[0], 두번째 방은 a[1]이라고 표시하기 때문입니다.
배열은 복잡하거나 많은 양의 자료를 다룰 때 거의 필수적입니다. 변수만 가지고 자료를 다루려면 매우 힘들 뿐만 아니라 사실상 불가능에 가깝습니다.
배열은 변수보다 훨씬 편하고 매우 유용한 개념이지만 변수보다 다루기가 까다롭습니다. 단독주택에 물건을 배달할 때는 그 주소에 놓고만 오면 되지만 빌라나 아파트에 배달할 때는 정확하게 호수까지 확인해서 배달해야 하는 것과 마찬가지입니다. 변수는 각기 독특한 이름이 있기 때문에 기억하기도 쉽고 다루기도 쉽습니다. 그러나 배열은 이름이 같기 때문에 몇 번째라는 숫자를 통해서 다른 배열과 구별해야 합니다. 이일은 생각보다 까다로운 일이지만 배열을 사용하지 않고 많은 용량의 자료를 다루기란 어려우므로 배열의 사용법을 잘 익혀두셔야 합니다.
**요약: 배열은 여러 개의 변수를 하나의 이름으로 사용할 수 있도록 확장한 변수로 볼 수 있습니다. 즉 변수를 단독주택으로 비유하면 배열은 공동주택으로 비유할 수 있습니다.
3.2.10. 선행처리기와 헤더파일의 관계
선행처리기는 소스파일을 컴파일하기 전에 먼저 처리하는 장치입니다.
선행처리기란 C++언어 프로그램이 소스파일을 컴파일하기 전에 먼저 처리하는 장치라는 뜻을 가지고 있습니다. 즉 소스프로그램을 컴파일하기 전에 먼저 선행처리기를 통해서 몇 가지 일을 처리하는데, 이때 여러 가지 헤더파일을 참조하여 함수나 변수에 대해서 정보를 얻기도 하고, 상수를 변환하여 실제로 사용할 자료로 치환하기도 합니다.
선행처리기를 사용하면 프로그램 짜기가 쉬워집니다.
선행처리기를 사용하는 까닭은 프로그램을 짜는 수고를 덜기 위해서입니다. 선행처리기를 이용하면 프로그램 짜기가 한결 편해지고 나중에 프로그램을 봤을 때도 이해하기 좋습니다.
예를 들어서 세금을 계산하는 프로그램을 만들었다고 합시다. 수입의 36.5%를 세금으로 내는 줄 알고 세금을 계산하는 곳마다 36.5를 곱해서 세금을 계산했습니다. 예를 들면 'tax=a*36.5'와 같은 문장으로 프로그램을 짰습니다.
한 200여 군데에서 36.5%를 곱했다고 합시다. 그런데 나중에 알고보니 33%로 세금이 내려갔다고 합시다. 그러면 그 많은 소스파일을 전부 뒤져서 36.5라는 숫자를 33으로 고쳐야 합니다. 그러나 선행처리기를 사용하면 이런 수고를 안해도 됩니다.
#define RATE 36.5
위와 같이 RATE라는 이름을 지정하고 여기에 36.5라는 수를 적습니다. 그리고 프로그램 안에는 'tax=a*36.5'나 '36.5*500000'와 같이 직접 수치를 쓰지 않고 'tax=a*RATE' 또는 'RATE*500000'이라고 적습니다. 그러면 컴파일을 하기 전에 선행처리기에서 알려준 정보를 토대로 컴파일러는 RATE를 36.5라는 수치로 바꿉니다. 그리고 프로그램을 컴파일해나가면서 RATE라고 써진 것을 모두 36.5라는 숫자로 바꿉니다. 따라서 200여 군데에 36.5라고 썼다면 손으로 일일이 찾아서 고쳐야 하지만, #define라는 선행처리기 명령을 이용하면 처음에 선언해준 '#define RATE 36.5'라는 문장만 '#define RATE 33'으로 고치면 됩니다. 그러면 프로그램 안의 RATE는 모두 33으로 치환되어 컴파일을 합니다. 결국 33*500000과 같은 결과를 내는 것입니다.
이처럼 선행처리기를 이용하면 프로그램을 짜거나 수정하기가 한결 쉬우며 알아보기도 쉽습니다. 33*500000이라는 명령문을 보고 무엇을 하라는 명령어인지 알아보기란 매우 어렵습니다. 33이라는 숫자를 왜 곱해야 하는지 알기 어렵기 때문입니다. 그러나 RATE*500000이라는 문장을 보면 어렵지 않게 500000만원의 월급에 세금으로 낼 비율을 곱하라는 뜻이구나 하는 것을 기억해낼 수 있을 겁니다.
가장 많이 사용하는 #include 선행처리기 명령어는 헤더파일을 포함하라는 명령어입니다.
선행처리기 명령어는 많은 것이 있지만 그중에서 가장 많이 사용하는 것은 #define 명령문과 #include 명령문입니다. 특히 #incdlude 명령문은 C언에서 거의 필수적인 명령문이나 다름 없습니다.
#include 명령문은 헤더파일을 포함하라는 명령문입니다. 그럼 헤더파일이란 무엇인가? 각종 함수나 변수의 선언을 담은 파일이라고 생각하시면 됩니다. 예를 들어서 프로그램을 열 개의 파일로 나누어서 짰습니다. 그런데 10개의 파일에서 공통적으로 man이라는 변수를 참고해야 한다고 합시다. 또는 jegob()라는 함수를 참고해야 한다고 합시다. C는 함수를 사용하기 전에 선언과 정의를 해주어야 합니다. 따라서 10개의 파일 모두에 jegob() 함수를 선언해주어야 합니다. 만약 100개의 함수를 백 개의 소스파일에 선언해주어야 한다면 보통일이 아닙니다. 특히 함수원형이 조금 달라졌을 경우에는 100개의 파일을 뒤져서 선언문을 일일이 고쳐주어야 합니다.
그래서 이런 선언문들을 묶어서 하나의 파일에 모아둡니다. 그리고 소스파일에는 #include 명령문을 이용하여 이 파일을 참고하라고 합니다. 예를 들어서 내가 만든 함수들의 원형을 'kim.h'라는 파일에 저장해두었다면 다음과 같은 명령어를 적어줍니다.
#include 'kim.h'
컴파일러는 이 명령어를 만나는 순간 소스파일을 컴파일하기 전에 kim.h 파일을 먼저 찾아보고 거기에 선언해둔 내용들을 참고합니다. 참고한 내용을 바탕으로 컴파일하면서 그 내용에 맞게 프로그램을 컴파일합니다. 따라서 함수의 원형을 변경했을 때도 kim.h 파일에 있는 한 줄만 고치면 됩니다. 100개나 되는 소스파일을 일일이 뒤져서 고칠 필요가 없습니다.
헤더파일은 주로 함수의 원형이나 변수 등을 선언해둔 파일입니다.
헤더파일은 주로 함수의 원형이나 변수 등을 선언해둔 파일인데, 볼랜드C++의 기본함수들을 담은 라이브러리도 헤더파일에 함수 원형을 적어놓았습니다. 그래서 컴파일러에서 제공하는 기본함수를 사용할 때는 세모 꺾쇠 안에 #include
와 같이 적습니다. 그리고 보통 사용자가 만든 함수나 변수를 선언해둔 파일은 작은 따옴표로 묶어서 표시합니다. 즉 #include 'kim.h'와 같이 적습니다.
**요약: 선행처리기란 C++언어 프로그램이 소스파일을 컴파일하기 전에 먼저 처리하는 장치라는 뜻입니다. 선행처리기 명령어로 가장 많이 사용하는 것으로 #include 명령문이 있으며, 헤더파일을 포함시키라는 명령어입니다. 헤더파일은 함수의 원형이나 변수 등을
선언해둔 내용을 모아놓은 파일입니다.