C++과 gcc를 이용하여 hello, world 콘솔에 출력보기!!
그전에 gcc에 대해서 알아봅시다.
gcc 기본 커맨드 설명
gcc란! GNU 컴파일러 모음(GNU Compiler Collection, 줄여서 GCC)는 GNU 프로젝트의 일환으로 개발되어 널리 쓰이고 있는 컴파일러입니다. 자유 소프트웨어 중에 가장 잘 알려진 것들 중 하나이죠. 원래 GCC는 C만을 지원했던 컴파일러로 이름도 "GNU C 컴파일러"엿지만, 후에 C++, Java, Fortran, Ada 등 여러 언어를 컴파일할 수 있게 되면서, 현재의 이름으로 바뀌었습니다. GCC는 리처드 스톨만이 1987년 GNU 프로젝트의 컴파일러로 작성했씁니다. GNU 프로젝트에 컴파일러가 없었기 때문에 이 개발은 자유 소프트웨어 재단이 후원하였습니다. 1997년 개발 과정은 공개되었으며, 속도 또한 빨라졌습니다. 199년 첫 번전이 나왔는데 현재 GCC는 전세계적으로 관리되고 있으며, 다양한 중앙 처리 장치를 처리할 수 있게 되었습니다. GNU 시스템의 공식 컴파일러이므로 GCC는 많은 컴파일러와 운영 체제를 만드는데 사용되었습니다. 한편, 시스템 네이티브 컴파일러를 사용했을때 비해서 GCC를 사용하면 같은 파서로 코드를 처리하므로 이식성을 향상시킬 수 있었습니다. GCC는 상용 컴파일러에 비해서 느린 코드를 생성했지만 최근 많이 개선되었습니다.
gcc에 대한 기본 이해
gcc를 소스를 가져다 손수 설치해보신 적은 없을 것입니다. 보통은 바이너리 패키지로 된 것을 가져다 설치를해요! gcc 패키지가 어떤 것으로 구성되어있는지! gcc가 제대로 설치되어 있는지 알보봅시다
/lib/cpp ----> /usr/lib/gcc-lib/i386-linux/2.7.2.1/cpp (링크)
/usr/bin/cc ----> gcc (링크)
/usr/bin/gcc C 컴파일러 'front-end'
/usr/bin/protoize
/usr/bin/unprotoize
/usr/info/cpp.info->.gz GNU info 시스템을 이용하는 파일들
/usr/info/gcc.info->.gz
/usr/lib/gcc-lib
마지막 /usr/lib/gcc-lib 디렉토리에 gcc에 관한 모든 내용이 설치됩니다.
보통은 이러한 형식으로 디렉토리 구조를 가집니다.
/usr/lib/gcc-lib/<플랫폼>/<gcc 버전>
/usr/lib/gcc-lib 밑의 내용을 살펴보겠습니다
/usr/lib/gcc-lib/i386-linux/2.7.2.1/cc1
/usr/lib/gcc-lib/i386-linux/2.7.2.1/cpp
/usr/lib/gcc-lib/i386-linux/2.7.2.1/include/*.h
/usr/lib/gcc-lib/i386-linux/2.7.2.1/libgcc.a
/usr/lib/gcc-lib/i386-linux/2.7.2.1/specs
cc1은 진짜 C 컴파일러 본체입니다. gcc는 단지 적절하게 C인지 c++인지 아니면 오트젝티브 C 인지를 검사하며 컴파일 작업만 아니라 "링크" 라는 작업까지 C 언어로 프로그램 소스를 만든 다음, 프로그램 바이너리가 만들어지기까지의 모든 과정을 관장해주는 "조정자"역할을 해줍니다.
C 컴파일러는 cc1, C++ 컴파일러는 cc1plus, 오브젝티브 C 컴파일러는 cc1obj입니다. 여러분이 C++/오브젝티브 C 컴파일러를 설치하셨다면 cc1plus, cc1obj 라는 실행파일도 찾아볼 수 있습니다. cpp는 "프리프로세서"입니다. #include 등의 본격적인 cc1 컴파일에 들어가기에 앞서 먼저(pre) 처리(process)해주는 녀석입니다.
g++ 즉 C++ 컴파일러에 대한 패키지는 다음과 같습니다.
/usr/bin/c++ ---------------------------------> (링크)
/usr/bin/g++
/usr/bin/gcc-lib/i386-linux/2.7.2.1/cc1plus (진짜 C++ 컴파일러)
오브젝티브 C 컴파일러 패키지는 다음과 같습니다.
/usr/lib/gcc-lib/i386-linux/2.7.2.1/cc1obj
/usr/lib/gcc-lib/i386-linux/2.7.2.1/include/objc/*.h
/usr/lib/gcc-lib/i386-linux/2.7.2.1/libobjc.a
gcc 사용하기
#include <stdio.h>
int main (void) {
printf("Hello World!");
retrun 0;
}
위의 코드로 Hello World!를 출력해봅시다. 컴파일을 하기전에 헤더와 main함수, 입출력에 대해서 알아봅시다
위의 코드에서는 stdio.h라는 헤더 함수를 사용했는데요 아래에서 쓴 printf함수 원래 기본 형은 printf()입니다. 괄호가 붙어있으면 대다수 함수라고 볼 수 있습니다. 여기서 중요한 점은 이는 함수라는 점인데요. 보통 이렇게 생각합니다. "우리는 저 함수를 선언해준 적이 없는데?" 라고 생각 할 수 있는데요. 아니에요! 사실 저희는 함수를 선언했답니다~ 바로 #include <stdio.h> 이 부분에서 사용했어요.
#include<stdio.h>에서 printf를 포함한 여러 함수들을 선언했다는 의미입니다. 다른 헤더 파일도 있는데 이는 각각의'~.h'와 같은 방식으로 여러가지 함수들이 '선언' 되어있습니다! 이를 #include안에 넣으면 됩니다.
또한 여기서 사용된 printf는 출력 함수로 출력 내용을 형식과 같이 나타나게 되면 사용할 수 있게 됩니다. scanf도 있는데 이는 입력 함수이며 printf와 같이 형식과 같이 표현하면 입력을 받을 수 있게됩니다.
이제 헤더와 입출력 함수에 대해 알았으니 main 함수의 원리에 대해 알아보겠습니다
int main() {
내용
return 0;
}
이는 main함수인데요 c언어에서는 main이라는 함수를 쓰면 프로그램이 실행됨을 의미하며, '0의 값이 반환될 경우, 프로그램이 정상적으로 마쳤으니 종료해라' 라는 의미를 갖고 있습니다.
이제 컴파일하고 실행 파일을 만들어 봅시다.
gcc hello.c -o hello.out 이를 통해서 컴파일을 할 수 있습니다.
이를 실행 할때는 ./hello.out 이렇게 치면 나오는데요 유닉스는 기본적으로 PATH라는 환경변수에 있는 디렉토리에서만 실행파일을 찾습니다.
만약 PATH라는 환경변수에 현재디렉토리를 의미하는 도트 문자(.)가 들어있지 않다면 현재 디렉토리의 실행파일은 절대 실행되지 않습니다. 게다가 현재 디렉토리를 PATH 환경 변수에 넣어준다 할지라도 도스처럼 현재 디렉토리를 먼저 찾는 일이 없고 PATH에 지정한 순서대로 수행합니다.
중간에 -o에 대해서 볼 수 있었는데요 이는 출력 파일명을 정하는 옵션입니다. 일반적으로는 파일명 그대로에다가 .out으로 출력 파일이라는 것을 의미하며 이 옵션을 사용하지 않고 gcc hello.c를 입력했을 때는 a.out으로 출력 파일이 생성됩니다.
이외에도 -c, -l, -L 옵션이 존재하는데요. 이는 좀더 심화된 것으로 이번 챕터에서는 다루지 않도록 합니다! 나중에 심화를 하게된다며 배우도록 하겠습니다!!
간단하게 c++로 Hello World 출력하기
#include <iostream>
int main(Void) {
cout << "Hello World!";
return 0;
}
c++에는 stdio.h와 비슷하게 iostream헤더가 입출력 해더와 다른 함수들을 가지고 있습니다. printf와 비슷한 것은 cout이며 이외에는 c에서 배운 것과 같습니다
이를 컴파일 해봅시다
g++ hello.cpp -o hello.out
c++의 확장자는 cpp이므로 이를 사용해주고 c++이므로 g++을 통하여 컴파일을 할 수 있습니다!!
c와 c++ 언어에서의 Hello World를 출력하는 방법에 대해서 알아보았으며 이제 다음챕터로 넘어가봅시다!!