아닙니다. 그 반대죠.
많은 사람들이 C++에 대해서 오해하고 있는 것이 참으로 안타깝습니다.
프로그래밍 언어를 처음 시작하는 사람에게 C는 별로 좋지 않습니다
(다른 관점에서 보면, Java도 마찬가지고요.)
차라리 C++부터 배우는 것이 낫습니다.
제가 C/C++ 자료실에 올린 Bjarne Stroustrup의 논문에 있는 예제를 들어보죠.
http://www.borlandforum.com/impboard/impboard.dll?action=read&db=cpp_res&no=17
(지금부터는 프로그래밍을 전혀 모르는 사람의 입장에서 생각해봅시다.)
사용자에게 이름을 입력받고, 그대로 출력하는 간단한 프로그램을 생각해봅시다.
표준 C++이라면 다음과 같이 간단하게 만들 수 있습니다.
아주 직관적이죠? 굳이 설명하지 않아도 쉽게 이해할 수 있을 겁니다.
#include <iostream> // get standard I/O facilities
#include <string> // get standard string facilities
int main()
{
using namespace std; // gain access to standard library
cout << "Please enter your full name: ";
string name;
cin >> name;
cout << "\nHello, " << name << ".\n";
}
C의 경우라면, 다음과 같이 하면 되겠죠?
일단, 입력 받는 문자의 갯수에 제한이 있겠군요.
#include <stdio.h> /* get standard I/O facilities */
/* maximum name length is 19 characters */
#define MAX_LEN 20
int main()
{
char name[MAX_LEN];
printf("Please enter your first name: ");
scanf("%s", name); /* read characters into name */
printf("Hello, %s.\n", name);
return 0;
}
초보자가 위 코드를 제대로 이해하기 위해 알아두어야 할 것이 꽤 많습니다.
우선, 전처리기 문장인 #define과, char 배열의 개념입니다.
C의 문자열은 '\0'으로 끝나기 때문에 20 - 1 = 19 문자까지만 저장된다든지,
name은 문자배열의 주소를 나타낸다든지 말이죠.
괴상한 암호 같이 생긴 "%s"도 직관과는 거리가 멀죠.
게다가 위 코드는 완전하지도 않습니다.
만약 scanf로 입력받을 때, 19문자 이상을 입력하게 되면,
name 배열의 크기를 넘어가 버리기 때문에, 프로그램 자체가 죽어버립니다. -_-;;
정말 초보에게는 좌절감만 느끼게 하기 십상이죠.
초보의 좌절감을 해소하기 위해서, 프로그램이 죽어버리는 문제를 해결해보죠.
다음과 같이 scanf의 라인에 '19'만 추가하면 됩니다.
scanf("%19s", name); /* read characters into name */
하지만 이렇게 하면 상수 정의문인
#define MAX_LEN 20
을 써서, 상수 값을 바꾸는 의미가 없습니다. -_-;;
scanf 안의 19도 자동으로 바뀌게 하려면
다음과 같이 수정하면 됩니다.
char fmt[10];
sprintf(fmt,"%%%ds", MAX_LEN - 1); /* create a format string: plain %s can overflow */
scanf(fmt, name); /* read at most MAX_LEN - 1 characters into name */
이제는 sprintf와 "%%%ds"의 의미도 이해해야 합니다. -_-;;
이 scanf는 아직도 문제가 남아있습니다. name 배열은 19문자까지로 입력이 제한되지만,
실제로 타이핑은 얼마든지 19문자 이상 화면에 계속되고, 그대로 남아있습니다.
게다가 맨 앞에 C++ 코드와 같이, 메모리가 허락하는 범위에서 무제한으로 문자열을
입력받고 출력하는 방법은 도저히 위의 scanf를 사용한 방법으로는 해결할 수 없습니다.
맨 처음의 C++ 코드와 비슷하게 동작하는 C 코드를 만드려면
malloc과 realloc를 써서 메모리를 동적으로 할당하고,
scanf대신 getchar를 써서 문자 하나씩 처리를 해야 합니다.
다음은 이를 구현한 코드입니다.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
void quit();
void input_str(char** str);
int main()
{
char *name;
printf("Please enter your full name: ");
input_str(&name);
printf("\nHello, %s.\n", name);
free(name); /* release memory */
return 0;
}
void quit() /* write error message and quit */
{
fprintf(stderr, "Memory exhausted.\n");
exit(1);
}
void input_str(char** str) {
#define DEFAULT_LEN 20
int max = DEFAULT_LEN, i = 0, c;
if ((*str = (char*)malloc(max)) == NULL) /* allocate buffer */
quit();
while (1) { /* skip leading whitespace */
int c = getchar();
if (c == EOF) break; /* end of file */
if (!isspace(c)) {
ungetc(c,stdin);
break;
}
}
while (1) {
c = getchar();
if (c == '\n' || c == EOF) { /* at end; add terminating zero */
(*str)[i] = 0;
break;
}
(*str)[i] = c;
if (i == max - 1) { /* buffer full */
max *= 2;
max = (char*)realloc(*str, max); /* get a new and larger buffer */
if (*str == 0) quit();
}
i++;
}
}
소스가 60라인 가까이 되는군요. -_-;;
게다가 아직도 문제는 남아 있습니다.
즉, 사용 후에는 반드시 free()로 할당된 메모리를 해제해야 합니다.
strdup() 함수의 사용법과도 비슷하죠.
버그 발생의 원인이 될 수 있는 좋지 않은 구현 방법이지만 어쩔 수 없겠네요.
도데체, 이름 하나 입력 받고 그대로 출력하는 데 알아야 될 것이 왜 이렇게 많은지!
C++이 어렵게 느껴지는 것은, 우리가 그 동안 C를 먼저 어렵게 배운 후에,
클래스의 정의부터 시작하는 어려운 C++ 책을 보고 어렵게 배웠기 때문입니다.
이제는 string과 vector와 같은 표준 라이브러리부터 먼저 배우고,
간단하면서도 실용적인 코드를 작성해 본 다음에,
객체지향과 클래스 정의를 배우면 됩니다.
C++을 단기간에 독파할 수 있는 좋은 책으로 Addison-Wesley에서 나온 "Accelerated C++"
을 강추합니다.
와우북에 있는 다음 서평을 참고하세요.
http://www.wowbook.com/computer/book/info/book_detail.asp?isbn=ISBN0-201-70353-X&review=13370#start
--------------------------------------------------------------------------------------
2003/2/26 추가:
--------------------------------------------------------------------------------------
2003/3월말 중에 위 책의 번역판이 나옵니다.
http://www.infopub.co.kr/common/bookinfo/bookinfo.asp?sku=06000144