프로그래밍:c

C++은 C를 기반으로 만든 객체지향언어(Object Oriented Language)이다. C++의 ++는 C/C++ 에서의 증감연산자로 +1을 시키는 연산자다. 즉, C에서 한 단계 올라간 언어라는 의미를 담고 있다. 여담으로 Microsoft에서 C++에 ++를 한 번 더 하여 만든 것이 C#이다. ++위나 아래에 ++를 붙이면 #이 되어 C#이 되었다.

C++는 C에서 파생된만큼 기존 C언어 라이브러리들과도 호환이 잘되며, C++만의 독자적인 라이브러리를 가지고 있어 C로 개발된 외부 라이브러리를 C++문법에 맞게 사용할 수도 있다. C와 Python 사이에 있는 언어로서 속도는 C에 가까우면서도 C보다는 코딩이 편하다. 다음은 이 문서에서 다룰 C++에 대한 내용이다.

기본 자료형

다음은 추가 라이브러리 필요없이 바로 쓸 수 있는 자료형이다. 각 자료형의 크기는 64bit ubuntu 20.04 LTS 버전의 g++ 9.3.0버전 기준으로 작성되었다. 자료형마다 할당되는 크기는 OS, CPU, 컴파일러 등에 따라 차이가 있을 수 있다.

유형 구분 자료형 크기 범위 비고
유형 없음 void - - -
정수형 bool 1 byte 1 or 0 true or false
char(int8_t) 1 byte $-2^7 \sim 2^7-1$ ($-128 \sim 127$) -
unsigned char(uint8_t) 1 byte $0 \sim 2^8-1$ ($0 \sim 255$) -
short(int16_t) 2 byte $-2^{15} \sim 2^{15}-1$ ($-32,768 \sim 32,767$) -
unsigned short(uint16_t) 2 byte $0 \sim 2^{16}-1$ ($0 \sim 65,535$) -
int(int32_t) 4 byte $-2^{31} \sim 2^{31}-1$ ($-2,147,483,648 \sim 2,147,483,647$) -
unsigned int(uint32_t) 4 byte $0 \sim 2^{32}-1$ ($0 \sim 4,294,967,295$) -
long(int64_t) 8 byte $-2^{63} \sim 2^{63} -1$ ($-9,223,372,036,854,775,808 \sim 9,223,372,036,854,775,807$) -
unsigned long(uint64_t) 8 byte $ 0 \sim 2^{64}-1$ ($0 \sim 18,446,744,073,709,551,615$) -
실수형 float 4 byte $-3.402\ 823\ 4 \times 10^{-38} \sim 3.402\ 823\ 4 \times 10^{38}$ 최대 정확도: 소수점 아래 7자리
double 8 byte $-1.797\ 693\ 134\ 862\ 315\ 7 \times 10^{308} \sim 1.797\ 693\ 134\ 862\ 315\ 7 \times 10^{308}$ 최대 정확도: 소수점 아래 15자리
long double 16 bytes $\pm1.189\ 731\ 495\ 357\ 231\ 765\ 085\ 759\ 326\ 628\ 007\ 016\ 2 \times 10^{4932}$ 최대 정확도: 소수점 아래 37자리

long의 경우 long int, long long, long long int 로도 쓸 수 있다.

이 중 주로 사용하는 자료형은 char(문자, 문자열), int(정수), float(실수), double(실수) 이다.

자료형이 가진 범위를 넘어선 숫자를 계산할 경우 stack overflow가 일어나서 원치 않은 결과를 얻을 수 있다. 또 자신이 다룰 숫자에 비해 너무 큰 크기를 가진 자료형을 사용하게 되면 메모리 낭비가 될 수 있다. 따라서 자신이 다룰 숫자의 크기가 어느정도 될 지 가늠해 보고 적절한 자료형을 사용하는게 중요하다.

다시 한 번 강조하지만 위의 자료형 크기는 참조용이며, 자신의 PC 환경에 따라 조금씩은 다를 수 있다. 특히 long과 long double의 경우 PC에 따라 각각 4 byte, 8 byte를 할당하는 경우도 있으니 다음과 같이 확인해 보고 사용하는 것을 권장한다.

#include <iostream>
 
using std::cout;
 
int main()
{
    cout << "long: " << sizeof(long) << "\n";
    cout << "long double: " << sizeof(long double) << "\n";
    return 0;
}

라이브러리 추가가 필요한 자료형

이 문서에서는 추가 라이브러리의 include가 필요한 자료형을 다룬다.

자료 유형 속해 있는 라이브러리 역할 비고
string <string> 문자열을 더 쉽게 다룰 수 있다. -
vector <vector> 기존의 배열을 더 쉽게 다룰 수 있다. -
map <map> key:value 쌍을 이용할 수 있다. -
unordered_map <unordered_map> map과 같지만 key 기준 정렬이 일어나지 않아 정렬이 필요하지 않은 경우 성능상 map보다 유리하다. -
pair <utility> 2개의 자료형을 하나의 객체로 묶을 수 있다. <vector> 라이브러리에서 <utility>를 include 하고 있으므로 <vector>를 include 했다면 따로 할 필요가 없다.
tuple <tuple> 3개 이상의 자료형을 하나의 객체로 묶을 수 있다. -
deque <deque> vector와 비슷하지만 pop_front(), pop_back() 같은 함수를 지원하여 가장 첫 원소 혹은 가장 마지막 원소만 제거할 수 있다. -

<string> 라이브러리에 있는 자료형으로 문자열을 좀 더 쉽게 다룰 수 있다. 한 예로 + 연산자로 서로 다른 문자열을 합칠 수 있다. 포함되어 있는 함수는 매우 많으나 주로 사용하는 몇 가지만 설명한다.

함수명 함수 설명 예시
to_string(x) int나 double 같은 숫자형 자료를 string 자료형으로 변환하여 반환한다. to_string(3) $\rightarrow$ “3”
to_string(3.8) $\rightarrow$ “3.8”
stoi(x) string 자료형을 int형 정수로 변환하여 반환한다. stoi(“3”) $\rightarrow 3
stoi(“3.8”) $\rightarrow$ 3
stod(x) string 자료형을 double형 실수로 변환하여 반환한다. stod(“3”) $\rightarrow$ 3.0
stod(“3.8”) $\rightarrow$ 3.8
string.substr(start, count) 문자열을 start 위치부터 start+count-1 위치까지 잘라서 string 자료형으로 반환한다. “abcde”.substr(1,3) $\rightarrow$ “bcd”
string.c_str() string 자료형인 문자열을 const char형 포인터로 변환하여 반환한다. “abcde”.c_str() $\rightarrow$ “abcde”(type is const char*)

substr의 경우 인자가 하나만 있으면 start위치부터 끝까지를 반환한다.

다음은 각 함수를 사용하는 코드다.

| example_string.cpp
#include <iostream>
#include <string>
#include <typeinfo>
 
using std::cout;
using std::string;
using std::to_string;
using std::stoi;
using std::stod;
 
int main()
{
    cout.precision(17);
 
    string str1 = "1234.56789";
 
    int x = stoi(str1);// x = 1234
    double xd = stod(str1); // xd = 1234.56789
 
    string i_to_s = to_string(x); // i_to_s = "1234"
    string d_to_s = to_string(xd); // d_to_s = "1234.56789"
 
    string sub1 = str1.substr(5);// sub1 = "56789"
    string sub2 = str1.substr(5,3);// sub2 = "567"
    string sub3 = sub1 + sub2;// sub3 = "56789567"
 
    const char *ch = str1.c_str(); // ch = "1234.56789"
 
    cout << "str: " << str1 << "\t type: " << typeid(str1).name() << "\n";
    cout << "str to int: " << x << "\t type: " << typeid(x).name() << "\n";
    cout << "str to double: " << xd << "\t type: " << typeid(xd).name() << "\n";
    cout << "substr one parameter: " << sub1 << "\t type: " << typeid(sub1).name() << "\n";
    cout << "substr two parameter: " << sub2 << "\t type: " << typeid(sub2).name() << "\n";
    cout << "string + operation: " << sub3 << "\t type: " << typeid(sub3).name() << "\n";
    cout << "str to char array: " << ch << "\t type: " << typeid(ch).name() << "\n";
}

실행결과는 다음과 같다.

str: 1234.56789 $\quad$ type: std::_ _cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
str to int: 1234 $\quad$ type: int
str to double: 1234.56789 $\quad$ type: double
substr one parameter: 56789 $\quad$ type: std::_ _cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
substr two parameter: 567 $\quad$ type: std::_ _cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
string + operation: 56789789 $\quad$ type: std::_ _cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
str to char array: 1234.56789 $\quad$ type: char const*

g++의 경우 typeid를 나름대로 define하여 쓰고 있어 그냥 실행하면 int는 i로 double은 d로 const char* 는 PKc로 나타난다. 위와 같이 정확한 명칭으로 나타나게 하기 위해서는

./example_string | c++filt --types

형식으로 실행을 해야한다.

vector는 다루기 쉬운 동적배열 자료형이다.

vector에서 지원하는 함수는 다음과 같다.

함수명 함수 설명
vector.begin() vector의 첫 요소의 주소를 가리키는 포인터를 반환한다.
vector.end() vector의 마지막요소 +1 번째 요소(null값)의 주소를 가리키는 포인터를 반환한다.
vector.capacity() vector의 크기를 반환한다.
vector.size() vector가 실제로 사용하고 있는 크기를 반환한다.
vector.at(x) vector의 x번째 요소를 반환한다. 잘못된 위치를 넣으면 컴파일 타임에서 에러가 발생한다.
vector.push_back(x) vector의 마지막 요소 다음에 x를 추가한다.
- C++에 matplotlib 라이브러리 추가해서 그래프 그리기

matplotlib 라이브러리 추가해서 그래프 그리기

이 문서는 Ubuntu-20.04 LTS 버전 기준으로 작성되었다.

  1. git clone을 이용하든 https://github.com/lava/matplotlib-cpp에 직접 접속하든 선택하여 matplotlibcpp.h파일을 /usr/include 혹은 /usr/local/include 에 넣는다.
  2. sudo apt install python-numpy를 터미널에서 실행한다.

다음은 간단히 sin 그래프를 그리는 예제코드다.

| example.cpp
#include <iostream>
#include <vector>
#include <cmath>
#include <matplotlibcpp.h>
 
using std::vector;
using std::sin;
using std::cout;
 
namespace plt = matplotlibcpp;
 
int main()
{
    const double pi = M_PI;
 
    vector<double> x(21);
    vector<double> y(21);
 
    for(int i = 1; i < x.capacity(); ++i)
    {
        x[i] = x[i-1] + pi/10;
        y[i] = sin(x[i]);
    }
 
    plt::plot(x,y); //plot the x,y
    plt::grid(true); //show grid
    plt::show(); // show figure
}

컴파일할 때는

g++ example.cpp -I/usr/include/python3.8 -lpython3.8 -o example

로 하면 된다.

  • 프로그래밍/c.txt
  • Last modified: 2026/03/24 16:37
  • by admin