C++/Arrays

C++ Arrays

Soul-Learner 2016. 12. 21. 10:05

C++ 프로그래밍, 배열 ( Arrays )


C언어의 표준인 C99 표준에서는 별다른 방법을 사용하지 않고도 배열의 동적인 메모리 할당이 가능하도록 되어있다.

C++에서도 new 연산자를 사용하지 않고도 런타임에도 배열의 크기를 결정할 수 있다. 아직까지 컴파일러에 따라서 차이가 있지만 필자가 사용하고 있는 개발환경에서는 문제없이 작동하고 있다. C++ 컴파일러 스펙 C++14부터는 거의 모든 컴파일러에서 이와 같은 방법이 지원될 전망이라고 한다.

테스트 환경 : Windows 8, Eclipse, MinGW, 컴파일러 스펙: C++11

Visual Studio 2017에서는 아직 지원안됨

new 연산자를 사용하지 않고도 배열의 메모리를 동적으로 할당하는 예제

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    cout << "C++ 배열 사용하기" << endl;

    // 배열의 메모리 할당은 컴파일 타임 혹은 런타임에 크기를 결정할 수 있다
    int num[3];
    num[0] = 1;
    num[1] = 2;
    num[2] = 3;

    int sz = sizeof(num);           // 4x3 = 12 bytes
    cout << "배열에 할당된 메모리의 크기:" << sz << endl;

    // 동적으로 배열의 메모리 크기를 결정하기 위해 임의의 수를 추출하여 배열의 크기로 사용한다
    srand(time(NULL));
    int len = rand() % 10 + 1;      // 임의의 수 추출
    cout << "배열의 방 수:" << len << endl;

    int score[len];
    sz = sizeof(score);                  // 배열의 전체 메모리 할당 크기
    int elemCnt = sz/sizeof(score[0]);   // 배열의 원소 수 (방의 갯수)

    cout << "동적으로 할당된 배열의 메모리 사이즈:" << sz << endl;
    cout << "동적으로 할당된 배열의 원소 수(방의 갯수):" << elemCnt << endl;

    // 동적으로 할당된 배열의 원소 초기화
    int value = 0;
    for(int i=0;i<len;i++) {
        score[i] = ++value;
    }

    // 동적으로 할당된 배열의 원소 확인
    for(int i=0;i<len;i++) {
        cout << "score[" << i << "]=" << score[i] << " " ;
    }

    return 0;
}


배열을 초기화하는 또 다른 방법 ( 한 행에 선언과 원소 초기화를 동시에 하는 방법 )

#include <iostream>

using namespace std;

int main()
{
    cout << "C++ 배열 사용하기" << endl;

    int num[3]; //배열변수 선언 및 메모리 할당(4x3=12바이트)
    num[0] = 1; //원소 초기화
    num[1] = 2;
    num[2] = 3;

    // 배열의 방 수 구하기
    int len = sizeof(num)/sizeof(num[0]);
    cout << "배열의 방 수:" << len << endl;

    cout << "[0]=" << num[0] << ", [1]=" << num[1] << ", [2]=" << num[2] << endl;

    // 변수 선언, 메모리 할당, 원소 초기화를 한 라인에 모두 하는 예
    int point[2] = {100,200};
    cout << "[0]=" << point[0] << ", [1]=" << point[1] << endl;

    int credit[] = {4, 5, 7}; // 첨자가 필요 없다
    cout << "[0]=" << credit[0] << ", [1]=" << credit[1] << endl;

    return 0;
}


다차원 배열(Multidimensional Array)의 선언 및 사용

#include <iostream>

using namespace std;

int main()
{
    cout << "C++ 다차원 배열 사용하기" << endl;

    // C++에서 다차원 배열과 1차원 배열의 메모리 구조는 동일한 1차원으로 구성된다
    // 다만, 개발자를 위해 다차원 첨자를 사용한다는 점만 다를 뿐이다
    int point[2][2];    // int point[4] 과 동일한 구조

    point[0][0] = 1;
    point[0][1] = 2;

    point[1][0] = 3;
    point[1][1] = 4;

    cout << point[0][0] << point[0][1] << point[1][0] << point[1][1] << endl;

    int num[2][2] = { {1,2},{3,4} };
    cout << num[0][0] << num[0][1] << num[1][0] << num[1][1] << endl;

    // 선언과 동시에 초기화할 때는 첫번째 첨자는 생략가능
    int score[][2] = { {1,2},{3,4} };
    cout << score[0][0] << score[0][1] << score[1][0] << score[1][1] << endl;

    return 0;
}


배열을 함수의 파라미터로 전달하는 경우

배열변수에는 배열의 메모리가 할당된 주소가 저장되어 있기 때문에 배열의 이름은 포인터 상수로 취급된다.

함수가 파라미터에 배열을 선언한 경우에 내부에서는 포인터 변수로 변환되어 사용된다. 그러므로 배열을 받는 함수에서는 배열의 메모리 크기를 알아 낼 수가 없다. 포인터 변수의 메모리 크기는 4바이트이며 포인터 변수가 메모리를 가리킬 때 포인터 변수를 이용하여 배열 전체의 메모리 사이즈를 확인한다면 4바이트로 나타나기 때문에 배열을 받아 들이는 함수 안에서는 배열의 전체 메모리 크기나 방의 갯수를 확인할 수가 없다. 그러므로 배열을 파라미터로 전달하려면 배열변수와 함께 배열의 방수도 파라미터로 전달해야 하는 것이다

#include <iostream>

using namespace std;

// 배열을 파라미터로 선언한 경우, 내부에서는 포인터 변수(int* num)로 처리된다
int sum(int num[], int len) {
	//배열을 생성한 블럭 밖에서는 배열의 방의 갯수를 확인할 수 없다
	int sz = sizeof(num)/sizeof(num[0]);     // 1(포인터 변수는 4바이트이므로)
	cout << "2. num 배열의 방 수:" << sz << endl;

	int sum = 0;
	for(int i=0;i<len;i++) {
		sum += num[i];
	}
	return sum;
}

int main()
{
    cout << "C++ 배열을 함수에 전달하기" << endl;

    int num[4] = {1,2,3,4};

    //배열을 생성한 블럭에서는 배열의 방의 갯수를 확인할 수 있다
    int len = sizeof(num)/sizeof(num[0]);
    cout << "1. num 배열의 방 수:" << len << endl;

    //배열을 함수에 전달한다. C++에서 배열의 이름은 포인터를 저장한 상수로 취급된다
    int total = sum(num, len);
    cout << "num 배열 원소의 합계:" << total << endl;

    return 0;
}