๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
C++ ๊ธฐ์ดˆ

[C/C++] 9. ๋ฐฐ์—ด(feat. vector & array)

by ์„œ์•„๋ž‘๐Ÿ˜ 2023. 4. 25.

 

 

 

๊ณ ์ „์ ์ธ c๊ฐ•์˜์—์„œ๋Š” ๋ฐฐ์—ด๊ณผ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ™์ด ์„ค๋ช…ํ•œ๋‹ค. ๋ฐฐ์—ด์˜ ์ด๋ฆ„์ด ๊ณง ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์ฃผ์†Œ๋ฅผ ์˜๋ฏธํ•˜๋Š” ํฌ์ธํ„ฐ๋กœ๋„ ์“ฐ์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ฐฐ์—ด ์ฑ•ํ„ฐ์—์„œ๋Š” ์–ธ์–ด์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๋ฐฐ์—ด์˜ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•๊ณผ Standard library๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•œ๋‹ค. ํฌ์ธํ„ฐ๋Š” ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์†Œ๊ฐœํ•˜๊ฒ ๋‹ค.

 

 

โœ… ๋ฐฐ์—ด

   C/C++์—์„œ ๋ฐฐ์—ด ์„ ์–ธ๊ณผ ์“ฐ์ž„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

#include <iostream>

void changeVal(double* d)
{
    d[4] =  6.0;
}

void changeColor(Car* cars)
{
    cars[1].color = "blue";
}

int main()
{
	double d[5] = {1.0, 2.0, 3.0, 4.0, 5.0};
	Car cars[3];
	int arr[] = {7,8,9};
    
	changeVal(d);
	changeColor(cars);
    
	std::cout << d[4] << " " << cars[1].color << " " << *(arr + 1);
}

// ์‹คํ–‰ ๊ฒฐ๊ณผ: 6.0 blue 8

 

  5๊ฐœ์งœ๋ฆฌ double ๋ฐฐ์—ด๊ณผ ์‚ฌ์šฉ์ž ํด๋ž˜์Šค Car 3๊ฐœ์งœ๋ฆฌ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์—ˆ๋‹ค. ๋ฐฐ์—ด์˜ ๊ธธ์ด๋Š” ๊ณ ์ •๋˜์–ด ์žˆ๊ณ , ๊ธธ์ด๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ๊ฒฝ์šฐ ๋‹ค์‹œ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ๋˜ํ•œ ๋ฐฐ์—ด ๊ฐœ์ˆ˜๋ฅผ ๋„˜์–ด๊ฐ€๋Š” index์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•  ๊ฒฝ์šฐ out of bound ๋•Œ๋ฌธ์— ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ๋ฐฐ์—ด ์„ ์–ธ ์‹œ ๋Œ€๊ด„ํ˜ธ์— ๋ฐฐ์—ด๊ธธ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ ์ง€ ์•Š๋”๋ผ๋„ ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ์œผ๋กœ 3๊ฐœ๋ฅผ ์ธ์ง€ํ•˜๊ณ  ๋ฐฐ์—ด ๊ธธ์ด๋ฅผ 3๊ฐœ๋กœ ์žก๊ฒŒ ๋œ๋‹ค. ๋งŒ์•ฝ arr ์„ ์–ธ๋ถ€์—์„œ ์ดˆ๊ธฐํ™”๋ฅผ ๋บ€๋‹ค๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค.

์ฝ”๋“œ ์ƒ์—์„œ ๋ฐฐ์—ด์˜ ๋ณ€์ˆ˜ d๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ ‘๊ทผํ•  ๊ฒฝ์šฐ, ๋ฉ”๋ชจ๋ฆฌ์ƒ์˜ 5๊ฐœ์˜ ์—ฐ๊ฒฐ๋œ double์˜ 40byte ์ค‘ ์ฒซ ๋ฒˆ์งธ ์ฃผ์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋•Œ๋ฌธ์— changeVal์— ๋ฐฐ์—ด์ด๋ฆ„์œผ๋กœ๋งŒ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„ฃ์–ด๋„ ์‹ค์ œ ๊ฐ’์ด ๋ฐ”๋€๋‹ค. changeVal์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํฌ์ธํ„ฐ๋ณ€์ˆ˜๋กœ์จ ์‹ค์ œ ๋„ฃ๋Š” ์ธ์ž๊ฐ’์€ ์ฃผ์†Œ๊ฐ€ ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค. ๋ฐฐ์—ด์˜ ์ด๋ฆ„ ์ž์ฒด๊ฐ€ ์‹œ์ž‘์ฃผ์†Œ๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. *(arr+1)๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ arr์€ ๋ฐฐ์—ด์˜ ์‹œ์ž‘์ฃผ์†Œ์ด๋ฉฐ +n์„ ํ•˜๋ฉด n๋ฒˆ์งธ ๊ฐ’์ด ์žˆ๋Š” ๊ณณ์˜ ์ฃผ์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋‚˜๋Š” ๊ฐ’์„ ์ถœ๋ ฅํ•˜๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— ํฌ์ธํ„ฐ์˜ ๊ฐ’์— ์ ‘๊ทผํ•˜๋Š” *์—ฐ์‚ฐ์ž๋ฅผ ๋ถ™์˜€๋‹ค. ํฌ์ธํ„ฐ์— ๋Œ€ํ•œ ์‰ฌ์šด ์„ค๋ช…์„ ๋ณด๊ณ  ์‹ถ์œผ๋ฉด ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•˜์ž.

  ํด๋ž˜์Šค ๋˜ํ•œ ๋ฉค๋ฒ„๋ณ€์ˆ˜์˜ size๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ„๋‹ค. ๋งŒ์•ฝ ๋‚ด๊ฐ€ ๋งŒ๋“  ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„๋ณ€์ˆ˜๊ฐ€ int 1๊ฐœ, double 1๊ฐœ์ธ ๊ฒฝ์šฐ, 12byte๋ฅผ ์ฐจ์ง€ํ•˜๋ฉฐ 3๊ฐœ์˜ ๋ฐฐ์—ด๋กœ ๋งŒ๋“ค์—ˆ์„ ๋•Œ 36byte๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ€๊ฒŒ ๋œ๋‹ค.

  int arr[3][5]์™€ ๊ฐ™์ด 2์ค‘ ๋ฐฐ์—ด ๋˜๋Š” ๊ทธ ์ด์ƒ n์ค‘ ๋ฐฐ์—ด๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœํ•˜๋Š” ์‚ฌ๋žŒ ์ž…์žฅ์—์„œ ์ง๊ด€์ ์ด์ง€ ์•Š์œผ๋ฉฐ ๋นˆ๋„๊ฐ€ ๋‚ฎ์•„์„œ ์ž์„ธํžˆ ๋‹ค๋ฃจ์ง€ ์•Š๊ฒ ๋‹ค.

 

 

โœ… std::array์™€ std::vector

  ๋ชจ๋˜ C++์—์„œ๋Š” C์—์„œ ์“ฐ๋˜ ์ผ๋ฐ˜ ๋ฐฐ์—ด์„ ์“ฐ๋Š” ๊ฒƒ ๋ณด๋‹ค๋„ Standard library๋ฅผ ์ถ”์ฒœํ•œ๋‹ค. std::array์™€ std::vector์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ ๊ณ ์ •๊ธธ์ด ๋ฐฐ์—ด๊ณผ ๊ฐ€๋ณ€๊ธธ์ด ๋ฐฐ์—ด์— ์žˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ๋‘˜ ๋‹ค ๊ธฐ๋ณธ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ๋‹จ์—์„œ๋Š” std::array๋Š” ์„ ์–ธ ์‹œ ๊ธธ์ด๋ฅผ ์ง€์ •ํ•ด ์ฃผ๊ณ , std::vector๋Š” ๊ธธ์ด๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š๋‹ค. ๋‹ค์Œ ์˜ˆ์‹œ๋ฅผ ๋ณด์ž.

 

#include <array>
#include <vector>
#include <iostream>

class Point
{
public:
    Point(double _x, double _y) : x(_x), y(_y)
    double getX() const { return x; }
    double getY() const { return y; }
private:
    double x;
    double y;
};

int main()
{
    std::array<int, 5> arr = { 1, 2, 3, 4, 5};
    std::vector<Point> vec;

    arr[2] = 11;

    Point p1(5.1, -3.8);
    vec.push_back(p1);

    vec.push_back(Point(-1.1, 2.2));

    std::cout << "arr size: " << arr.size() << ", arr[2] : " << arr[2] << endl;
    std::cout << "vec size: " << vec.size() << ", vec[1] : " << vec[1].getX() << "," << vec[1].getY() << endl;
}

// ์‹คํ–‰๊ฒฐ๊ณผ: arr size: 5, arr[2] : 11
//          vec size: 2, vec[1] : 5.1,-3.8

 

array๋Š” ์„ ์–ธ์‹œ ๊ณ ์ • ๊ธธ์ด์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ๋‘ ๋ฒˆ์งธ ํ…œํ”Œ๋ฆฟ ์ธ์ž์— ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” array, vector์— ๋“ค์–ด๊ฐˆ ํƒ€์ž…์„ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.

 

std::array์™€ std::vector๋Š” ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„๋œ ๊ฒƒ์ด๋ฏ€๋กœ ์ธํ„ฐํŽ˜์ด์Šค ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฝค๋‚˜ ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ์ด ๋งŽ๊ธฐ๋„ ํ•˜๊ณ  ๊ฒ€์ฆ๋œ ์ปจํ…Œ์ด๋„ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•  ๋•Œ ์ฐธ๊ณ ํ•ด์„œ ์‚ฌ์šฉํ•˜์ž. cppreference์˜ ๊ณต์‹ ๋ฌธ์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

https://en.cppreference.com/w/cpp/container/array

 

std::array - cppreference.com

template<     class T,     std::size_t N > struct array; (since C++11) std::array is a container that encapsulates fixed size arrays. This container is an aggregate type with the same semantics as a struct holding a C-style array T[N] as its only non-s

en.cppreference.com

https://en.cppreference.com/w/cpp/container/vector

 

std::vector - cppreference.com

template<     class T,     class Allocator = std::allocator > class vector; (1) (2) (since C++17) 1) std::vector is a sequence container that encapsulates dynamic size arrays. The elements are stored contiguously, which means that elements can be acces

en.cppreference.com

 

๋‚˜๋„ ๋ฐฐ์—ด์„ ์จ์•ผํ•˜๋Š” ๊ฒฝ์šฐ๋Š” 100% array์™€ vector๋งŒ ์‚ฌ์šฉํ•œ๋‹ค. C์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋„ ๊น”๋”ํ•˜์ง€ ์•Š๊ณ , ์ง๊ด€์ ์ด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ standard library๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์žˆ์–ด ์ด์ ์ด ํ›จ์”ฌ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์“ธ ์ด์œ ๊ฐ€ ์—†๋‹ค.

 

 

 

๋Œ“๊ธ€