C언어는 1972년 AT&B Bell Lab에서 Dennis Ritchie라는 사람에 의하여 개발되었다. COBOL, FORTRAN, PASCAL등 그 이전에 개발된 수많은 언어들을 밀어내고 C는 가장 중요한 언어의 하나로 자리잡았다. 많은 이유들이 있겠으나 필자가 생각키로는 C언어의 시스템적인 특성 때문이라고 생각한다. 즉, 시스템(OS)를 개발하는데 가장 적합한 언어라는 뜻이다. C라는 이름은 그 이전에 있던 B라는 언어를 모태로 만들었기 때문이라고 한다. 현재 B언어는 사용되지 않는다. 그러면 A라는 언어도 있었을까? 그건 모르겠다.
컴퓨터의 기초편에서 비트, 바이트, 16진수등에 대해서 이야기 했다. C언어의 출발은 여기서 하도록 한다. 그 이유는 C언어는 시스템 언어이기 때문이다. 컴퓨터의 기능은 저장과 계산이라고 했다. 언어에서 가장 기본적인 저장은 변수(variable)에 한다. 변수라는 이름은 말 그대로 값을 바꿀수 있다고 해서 붙여진 이름이다.
void main()
{
int a;
a = 10;
}
여기서 파란색으로 된 부분이 변수 a를 선언한 부분이다. a라는 저장소를 만든것이다. 이 프로그램을 실행하면 컴퓨터는 a에 저장될 값을 넣어둘 장소를 메모리 어딘가에 할당한다. 즉, a의 주소를 정해 주는 것이다. 몇 바이트나 a를 위해서 할당해 줄까? 컴퓨터, OS, 컴파일러 등에 따라서 달라질 수 있다. 다른 대부분의 언어들은 integer변수의 크기가 결정되어 있지만 C는 그렇지 못하다. 이유는? 시스템에 밀접한 언어이기 때문이다.
16비트 컴퓨터라면 16비트 즉, 2바이트를 할당하고 32비트 컴퓨터라면 32비트 즉, 4바이트를 할당한다. 말하자면 C의 int 변수는 컴퓨터의 기초 메모리 접근 단위와 일치하도록 하고 있다. 그런데 int가 몇 바이트를 사용하는지가 무슨 상관일까? 대부분 별 상관없이 쓸 수 있다. 그러나 a에 얼마나 큰 값이 들어갈 수 있는지를 알지 못하고 프로그램을 만든다면 그 값의 한계안에서 프로그램이 실행되면 문제가 없지만 그 값의 크기를 벋어나는 숫자가 들어가면 큰 문제를 발생시킨다. 그러므로 컴퓨터 언어에서 변수를 사용할 때는 그 변수의 한계값을 분명히 알아야 한다.
현재 대부분의 컴퓨터는 32비트 컴퓨터이므로 이후로는 int는 4바이트를 사용하는 것으로 가정한다. 4바이트라면
1111 1111 1111 1111 1111 1111 1111 1111(이진수) = FFFFFFFF(16진수) = 4,294,967,295(십진수)
가 최대값이다. 그러나 int는 양수와 음수가 모두 들어갈수 있으므로 실제 int가 가지는 한계값은
-2147483648 ~ 2147483647
이다. 그러므로
a = 2147483647;
a = a + 1;
의 결과는 2147483648이 아니라 -2147483648이다.(실제 프그램을 만들어서 확인해 보라.) 한계값을 넘어서는 계산을 하는 것을 오버플로우(overflow)가 발생했다고 표현한다. 위의 계산이 오버플로우가 발생하는 예의 한가지이다. int가 가질 수 있는 값의 한계를 모른다면 위 계산의 결과를 제대로 예측할 수 없으며 그 결과 또한 원하는 바와는 전혀 다른 결과를 가져올 수 밖에 없을 것이다.
자 그렇다면 컴퓨터는 a 변수를 어디에 저장했을까? 즉, 주소는 어디일까? 다음과 같은 코드로 알수 있다.
int a;
int address;
address = (int)&a;
위의 코드를 실행하면 address변수에는 a의 주소가 들어가게된다. &는 변수의 주소를 알아오는 기능을 한다. 읽을 때도 "address of"로 읽는다. 여기서 주의해서 볼 것은 address변수도 int로 선언되었다는 것이다. 컴퓨터가 저장을 하기 위해서는 바이트 단위의 주소가 필요한데 주소 체계도 32비트의 제한이 있다는 것이다. 즉 컴퓨터가 실질적으로 저장할수 있는 메모리 한계도 여기서 발생한다. 32비트 컴퓨터는 32비트(4바이트) 주소체계를 가지며 4,294,967,296 개의 주소를 가질 수 있으며 한 주소에는 한 바이트씩 할당되므로 하나의 프로그램이 접근할 수 있는 메모리의 한계는 4,294,967,296 바이트가 되고 이것을 4기가 바이트로 읽는다.
메모리가 커지면서 메모리 크기를 이야기 할때 바이트를 쓰기 보다는 킬로, 메가, 기가등을 사용하는데 이 단위들은 일반적으로는
킬로(K) = 1,000
메가(M) = 1,000,000
기가(G) = 1,000,000,000
으로 사용하는 것이지만 컴퓨터에서는 정확히는 이 값이 아니다. 컴퓨터에서 이 값들은
킬로(K) = 210 = 1,024
메가(M) = 220 = 1,048,576
기가(G) = 230 = 1,073,741,824
으로 사용된다. 자 그러면 4 기가 바이트를 계산해 보자.
4 * 1,073,741,824 = 4,294,967,296 = 100,000,000(16진수) = 232
가 된다. C언어는 이처럼 컴퓨터 메모리 구조와 밀접한 관계를 가지고 있으며 이러한 특성이 C언어를 컴퓨터 시스템을 운용하고 설계하는데 가장 강력한 도구로 자리잡게 만든 것이다.