시리즈:쉽게 배우는 프로그래밍 입문/C++

Hwangjy9 (토론 | 기여)님의 2015년 8월 15일 (토) 22:14 판 (문자열 찾아 바꾸기 - "일일히" 문자열을 "일일이" 문자열로)

문서의 내용이 너무 쉬워서 오늘부터 프로그래밍 할 수 있을 것 같습니다.

이 문서에는 독자적으로 연구한 내용이 들어갑니다. 다른 사람의 의견을 존중하면서 무례하지 않도록 작성해 주시고, 의견 충돌 시 토론 문서에서 토론해 주세요.

틀:토막글

틀:중급 프로그래밍 항목

묻지도 따지지도 않고 문법을 배우고 싶은 사람은 문법을 읽으면 된다. 만약, 프로그래밍을 C++로 입문하고자 하는 사람이 있다면 따라하기로.

이 언어를 배우려는 사람에게 전하는 주의사항

만약 C 문법을 잘 모르는 경우 반드시 쉽게 배우는 프로그래밍 입문/C 참고.

C 문법을 그대로 사용하는 경우

물론 프로그래밍을 할 수는 있다. 그렇지만, C의 문법보다 형변환[1] 조건이 빡빡하다던가, C++의 많은 기능을 사용할 수 없다던가 하는 점이 있기 때문에, 정말 C로 개발해야만 하는 상황(거의 없겠지만)이 아니라면 C++의 문법을 사용하는 것이 좋다.

객체지향은 또 뭐야?

쉽게 말해, 모든 대상을 "데이터"와 "기능"으로 추상화해서 나타낸 것이다. 기존의 C에서 사용하던 구조체(struct)는 말 그대로 단순히 데이터를 담는 "자료형"의 역할을 했지만, 클래스는 어떤 대상을 데이터와 기능의 집합으로 나타내므로 그 대상의 성질, 특성과 같은 것들을 표현할 수 있다. 예를 들어서 휴대폰을 프로그래밍한다고 하자(하드웨어 같은 건 신경 끄고). 보통 기능을 늘어놓는다면(구조적 프로그래밍) 전화기능이라던가, 문자기능 등을 써넣을 것이다. 객체지향으로 프로그래밍을 한다면 휴대폰의 화면, 버튼, 카메라, 배터리, CPU 등을 (객체로) 만든 뒤, 이것들을 유기적으로 연결해서 휴대폰이란 프로그래밍을 만든다. 이렇게 현실과 비슷하게 구성하기 때문에, 프로그래밍계의 혁명이라 카더라.

쓸데없이 불친절하고 어려운 템플릿

템플릿은 메타프로그래밍 요소로, 서로 다른 여러 가지의 클래스에 대해 각각을 따로 프로그래밍하지 않고 같은 이름을 가지는 대상(클래스, 함수)으로 프로그래밍할 수 있게 한다. 다시 말해서, 일반화 프로그래밍이 가능하다! 하지만, C++의 템플릿은 다른 여타 언어들의 메타프로그래밍 요소와는 달리 템플릿 메타프로그래밍이라는 변태짓을 가능하게 한다.나쁜 녀석들 같으니라고 구글링을 해도 답이 안나온다 이 기법은 C++ 프로그래머 중에서도 정말 고수들만이 제대로 활용할 수 있으므로, 공부하려고 마음먹었을 때 각오하는 것이 좋다.하지만 우리 회사는 못하게 하는데 그럴때는 실력에 대한 신뢰감을 줘야..

함수형 프로그래밍은 또 어디에서 굴러들어온건데?

시간이 지나면서, 프로그래머들은 객체지향의 한계에 봉착하게 된다. 대세는 멀티코어! 다들컴맹 빼고 들어봤을 것이다. 멀티코어 프로그래밍은 서로 다른 프로세스가 하나의 데이터에 동시에 접근하는 경우가 비일비재하기 때문에[2] 접근 통제를 위해 프로세스들을 락/언락해야만 한다. 그런데 락/언락을 자주 하게 되면 CPU에서 병목현상이 발생하기 때문에 프로그램의 실행시간, 반응 속도 등에 영향을 끼치게 된다.

이 멀티코어 프로그래밍을 위한 대안이 바로 함수형 프로그래밍이다. 함수형 프로그래밍에 사용되는 함수는 수학에서의 함수의 성질을 따른다. 기존의 함수는 모든 작업을 순차적으로 처리해야만 했지만, 함수형 프로그래밍에서는 작업 순서를 변경시켜서 어떤 것을 먼저 처리하고 어떤 것을 지연시켜도 같은 결과가 나오는 것이다!

더럽게 기능이 많은데, 이 많은 걸 언제 배워!

그래서 C++의 진입장벽이 높은거다. 현재진행형으로 언어 표준을 개정해나가면서 짧은 시간에 많은 기능이 추가되거나, 바뀌거나, 사라지고 있다. 하지만, "C++스러운" 프로그래밍 방법은 표준을 개정해나가도 크게 변하지 않는다. 표준은 "C++스러운" 방법을 위한 편의 기능을 제공하는 방향으로 개정되고 있다고 생각해도 된다. 그러니, "C++스러운" 방법이 무엇인지 안다면, 앞으로 계속 표준이 바뀌더라도 학습이 용이할 것이다.

많은 내용들 중 중심적인 내용을 먼저 학습한 후, 곁가지로 제공되는 기능을 익혀나가는 방법은 C++을 공부하는 좋은 방법 중 하나이다. C를 빠르게 공부한 후, C++의 중심적 내용인 클래스를 공부하면 나머지는 다 부가기능처럼 보일것이다.

배워두면 좋은 점

  1. 일단 언어 자체가 매우 강력하다.
    위에서 기능이 많아서 배우기 어렵다고 했는데, 그 말은 다시 돌려 말하면 그만큼 많은 기능을 사용할 수 있고, 사용 여하에 따라서는 매우 강력한 도구가 될 수 있단 뜻이다. 특히 최근 대세인 Java보다 매우 빠르며[3], 프로그램 실행 속도는 C와 거의 다를 바가 없을 수준[4]이다.
  2. 고급 언어의 특성을 많이 가지고 있으면서(추상화 등), 중간 언어(C)의 기능을 다 사용할 수 있다.
    고급 언어는 프로그램 설계를 쉽게 해준다. 특히 C++은 고급 언어들 중에서도 일부에서만 지원하는 몇몇 강력한 기능(연산자 오버라이딩) 등을 지원한다. 하지만 많은 고급 언어들은 오류 방지나 무결성 등을 위해 메모리 직접 접근을 제한하는 등 직접 프로그래머가 건드릴 수 있는 부분을 제한함으로서 안정성을 얻으려 했다. 반면, C++은 그런거 없다. 사용할 수 있는 부분은 C에서 크게 다르지 않은, 이걸로 OS를 구축할 수 있을 정도의 언어이다. 그런 부분을 버린 만큼 조심히 다뤄야하지만, 조심하게 다루면서 사용하게 되면 고급 언어들에서는 사용할 수 없는, 중간 언어들에서 사용하던 유용한 트릭들을 사용할 수 있다.
  3. 하는 사람이 생각보다 많이 없다!
    불과 한 10년전만 하더라도 C++ 프로그래머가 거의 대부분을 차지했지만, 최근 Java에 대한 지속적 투자와 임베디드화 경향이 맞물리면서 Java가 득세하는 바람에, Java 프로그래머는 넘쳐나는데 C++ 프로그래머는 수가 많이 줄었다.

준비

윈도에서라면 Visual Studio 커뮤니티 2013를 사용해보자.

개인 사용자들에게는 무료로 공개되어 있는 버전이다. 참고로 이거 하나면 C++ 뿐만이 아니라 C#, VB.NET 개발도 가능하다. 학생의 경우 Dreamspark 프로그램을 통해 Professional 등의 버전을 사용할 수도 있다.

최신 표준의 기능들을 사용하고 싶다면 컴파일러를 LLVM로 바꾸면 된다.

리눅스 유저라면 eclipse를 이용하면 된다. 그리고 이클립스에서 C++을 코딩할 수 있도록 g++과 eclipse-cdt를 터미널 혹은 시냅틱에서 설치하자. IDE 따위 필요없는 변태라면, g++하나만 있어도 된다.

후술된 내용들을 보기 전에 위의 C 프로그래밍 내용을 숙지하자. C++은 기본적으로 C에서 기원했다.

예외란 없다Hello, World!

빈 프로젝트를 생성한 후 소스(.cpp)파일에 다음 내용을 작성한다.

#include <iostream>

int main(void)
{
    std::cout << "Hello, World!" << std::endl;
    return 0;
}


혹은 이렇게도 쓸 수 있다.

#include <iostream>
using namespace std;
int main(void)
{
    cout << "Hello, World!" <<endl;
    return 0;
}

또는

#include <cstdio>
int main(void)
{
    printf("Hello, World!");
    return 0;
}


설명: C언어의 stdio와 같이 표준 입출력을 담당하는 C++의 헤더는 iostream이다. C++는 C언어와는 차이점이 존재하는데 표준 입출력에서 '함수'가 아닌 '(여러 함수를 포함하는)객체'를 사용한다는 점이다. C언어를 사용해오던 개발자가 C++를 처음 접할 때 생소함을 느끼는 이유가 그것이다.

참고로 C++는 C언어와 상위호환이 가능한 언어로 설계되어 기존의 C표준 헤더를 사용하는 것이 가능하다. 비교적 최근의 C++표준은 헤더 명 앞에 c를 붙이고 확장자를 지워서 stdio.h를 cstdio와 같이 쓴다. 예제 코드는 세 번째 소스코드를 참조하면 된다.

C++ 표준 입출력에서는 입출력을 위한 여러 객체나 함수를 제공하는데 대표적으로 cout, cin, endl등이 있다. 위의 소스코드에서 쓰인 cout객체는 콘솔 화면 상에 문자열을 출력하는 기능을 가지고 있다(cout를 console out로 이해하면 편하다). cout 객체의 사용방법은 cout객체와 출력하려는 대상을 << 연산자로 연결하는 것이다. 출력 대상에는 문자열, 정수, 실수, 문자 등이 있고 << 연산자는 비트연산자가 아님을 주의한다. 또한 endl은 개행(endl을 end line으로 이해하면 편하다)의 기능을 하는 객체이다. 이 객체는 cout 객체 뒤에 전달할 수 있으며 이스케이프 시퀀스 \n로 대체가 가능하다(물론 따옴표 안에 묶어야 한다). 따라서

std::cout<<"Hello World"<<std::endl;

은 다음 문장과 완벽하게 똑같다.

std::cout<<"Hello World\n";

이쯤에서 cout 앞에 쓰인 std라는 것의 정체가 궁금할 것이다. 이것은 이름공간(name space)라는 것인데, 여러분들이 정의한 객체나 함수가 헤더에 존재하는 것과 이름이 중복된다면 곤란해지므로 이것을 방지하기 위해 만들어진 개념이다. 이름공간안에 묶인 객체나 함수를 사용하기 위해서는 항상 앞에 이름공간의 경로를 명시해야 하며 경로를 연결하는 연산자는 :: 연산자이다.

std::를 일일이 붙이는 것도 꽤 번거로운 일이지만 이는 어느 정도 감수할 수 있다. 그러나 cout객체의 경로가 aaa::bbb::ccc::ddd::eee라고 한다면 번거로운 것은 물론이고 가독성까지 떨어지기 때문에 적당한 생략이 필요하다. 그래서 존재하는 것이 바로 using 이다. 이름 공간의 경로를 using 하나만 사용한다면 통째로 생략하는게 가능해진다.

앞의 예제를 보면

using namespace std;

라고 적혀 있을 것이다. 이것은 '이름공간 std에 들어 있는 모든 객체나 함수는 이름공간을 생략하고 쓰겠다'라는 선언이다. 하지만 using을 남용하면 이름 충돌 위험성이 있기 때문에 별로 좋은 코딩 습관은 아니다. 위처럼 std::를 꼬박꼬박 붙여주거나 사용할 객체만 골라서 using std::cout; 와 같이 선언하면 된다.

데이터형

배열

제어문

함수

참조형(레퍼런스)

포인터와 참조형의 차이

동적할당

객체지향 기초

struct

struct의 확장 class

구조체에 함수를 추가

생성자와 소멸자

접근지정자

예외처리

고급 과정

각주

  1. 간단히 설명하자면, 문자를 정수로 바꾸는 등의 한 데이터 타입을 다른 타입으로 변환하는 것을 말한다.
  2. 이렇게 되면 프로그램을 여러번 실행시켰을 때 같은 조건에서도 항상 같은 결과가 나온다고 기대할 수 없다.
  3. 물론 완벽하게 빠른건 아니나, 일반적인 경우에는 Java보다 매우 빠르다.
  4. 대신 C에 비해 문법적으로 복잡하기 때문에 컴파일에 걸리는 시간은 일반적으로 훨씬 길다. 때문에 실무에서는 컴파일 타임을 줄이는 몇가지 방안을 사용한다.