C++ ArrayAndPointer

m._.jooong·2023년 4월 26일
0

C++

목록 보기
21/23

1. 배열과 포인터


#include <iostream>

/** 문자열 관련 라이브러리*/
#include <string>
/** 배열의 사이즈를 알기 위한 라이브러리*/
#include <array>

/** C++ 표준 라이브러리 사용합니다. */
using namespace std;

int main()
{
    /**
   1. 배열과 포인터
   2. 배열포인터
   3. 포인터배열
   */

   /** 1. 배열과 포인터*/
    int intValue1 = 10;
    /** 포인터 변수를 선언하고 초기화를 합니다. */
    int* intPtr1 = &intValue1;

    cout << "intPtr1 : " << *intPtr1 << ", intPtr1 address : " << intPtr1 << endl;

    *intPtr1 = 20;

    cout << "intPtr1 : " << *intPtr1 << ", intPtr1 address : " << intPtr1 << endl;

    cout << endl;
    cout << endl;

    // 주소값을 확인
    // int타입의 무게는 4바이트이다
    // 주소값은 16진수이다.

    // 포인터 변수에 1을 더한 값이 출력된 것을 볼 수 있다
    // intPtr1 + 1의 주소값 : intPtr1의 주소값에 4바이트를 더한 값
    cout << "intPtr1의 주소값 : " << intPtr1 << endl;
    cout << "intPtr1 + 1의 주소값 : " << intPtr1 + 1 << endl;
    cout << endl;
    cout << endl;

    /** 배열을 선언하면 배열의 시작주소(배열의 0번째 인덱스 값의 주소입니다. )가 반환됩니다. */

    /** 문장을 추가해 줍니다. */
    int intArr1[] = { 1, 3, 5, 7, 9, 11, 13, 15, 17 };

    cout << "intArr1[0] value : " << *intArr1 << endl;          // 0번째 인덱스의 값
    cout << "intArr1[0] value : " << intArr1[0] << endl;        // 0번째 인덱스의 값

    cout << "intArr1[1] value : " << *(intArr1 + 1) << endl;    // 1번째 인덱스의 값
    cout << "intArr1[1] value : " << intArr1[1] << endl;        // 1번째 인덱스의 값

    cout << "intArr1[0] address : " << intArr1 << endl;         // 0번째 인덱스의 주소값
    cout << "intArr1[0] address : " << &intArr1[0] << endl;     // 0번째 인덱스의 주소값

    cout << "intArr1[1] address : " << intArr1 + 1 << endl;     // 1번째 인덱스의 주소값
    cout << "intArr1[1] address : " << &intArr1[1] << endl;     // 1번째 인덱스의 주소값

    /** 다음과 같은 표현도 가능합니다. */
    cout << "intArr1[1] address : " << &intArr1[0] + 1 << endl;

    cout << "" << endl;
    cout << "" << endl;

    /**
    반복문으로 주소값을 출력해 봅니다.
    문장을 추가해 줍니다.
    */

    /** foreach문에서 인덱스를 사용해 봅니다. */

    for (int i : intArr1)
    {
        cout << "intArr1[" << i << "] address : " << &intArr1[i] << endl; // 잘못된 값입니다. 
    }
    cout << endl;
    cout << endl;

    int index = 0;

    for (int i : intArr1)
    {
        cout << "intArr1[" << index << "] address : " << &intArr1[index] << endl;
        index++;
    }
    cout << endl;
    cout << endl;

    for (int i = 0; i < size(intArr1); i++)
    {
        cout << "intArr1[" << i << "] address : " << &intArr1[i] << endl;
    }
    cout << endl;
    cout << endl;

    char charValue2 = 'L';
    int intValue2 = 1024;
    double doubleValue2 = 3.14;

    /** 포인터 변수의 사이즈는 4바이트 입니다. 확인해 봅니다. */
    cout << "charValue2 size : " << sizeof(charValue2) << endl;
    cout << "charValue2 ptr size : " << sizeof(&charValue2) << endl;

    cout << "intValue2 size : " << sizeof(intValue2) << endl;
    cout << "intValue2 ptr size : " << sizeof(&intValue2) << endl;

    cout << "doubleValue2 size : " << sizeof(doubleValue2) << endl;
    cout << "doubleValue2 ptr size : " << sizeof(&doubleValue2) << endl;

    cout << endl;
    cout << endl;

    /** 배열의 요소를 출력해 봅니다. */
    int intArr2[9] = { 1, 2, 3, 4,5, 6, 7, 8, 9 };

    for (int i = 0; i < size(intArr2); i++)
    {
        cout << intArr2[i] << " ";
    }
    cout << endl;
    cout << endl;

    for (int i = 0; i < size(intArr2); i++)
    {
        cout << *(intArr2 + i) << " ";
    }
    cout << endl;
    cout << endl;

    for (int* ptr = intArr2; ptr < intArr2 + size(intArr2); ptr++)
    {
        cout << *ptr << " ";
    }
    cout << endl;
    cout << endl;
    
    /** 배열의 사이즈를 알아보도록 합니다. */
    cout << "array size : " << sizeof intArr2 / sizeof intArr2[0] << endl;      // array size : 9

    cout << "array size : " << size(intArr2) << endl;                           // array size : 9

    cout << "array size : " << sizeof(intArr2) / sizeof(intArr2[0]) << endl;    // array size : 9

}

2. 배열포인터

#include <iostream>

/** 문자열 관련 라이브러리*/
#include <string>
/** 배열의 사이즈를 알아오기 위한 라이브러리*/
#include <array>

/** C++ 표준 라이브러리 사용합니다. */
using namespace std;


int main()
{
    /**
    1. 배열과 포인터
    2. 배열포인터
    3. 포인터배열
    */

    /** 2. 배열포인터*/
    int intArr1[9] = { 1, 2,3, 4, 5, 6, 7, 8, 9 };
    int* intPtr1 = intArr1;

    for (int i = 0; i < size(intArr1); i++)
    {
        cout << *(intPtr1 + i) << " ";
    }
    cout << endl;
    cout << endl;

    for (int i = 0; i < size(intArr1); i++)
    {
        cout << intPtr1[i] << " ";
    }
    cout << endl;
    cout << endl;

    // 3번째 문장이 헷갈립니다. 다음과 같이 이해하면 된다
    // intArr1[i] => *(intArr1 + i) => *(intPtr1 + i) => *(i + intPtr1) => i[intPtr1]
    for (int i = 0; i < size(intArr1); i++)
    {
        cout << i[intPtr1] << " ";
    }
    cout << endl;
    cout << endl;

    /**
    포인터와 배열의 관계에 대해서 정리하기.
    */
    intPtr1 = &intArr1[0];
    cout << "intPtr1 : " << &intArr1[0] << endl;        //intPtr1 : 012FF718

    intPtr1 = &intPtr1[0];
    cout << "intPtr1 : " << &intPtr1[0] << endl;        //intPtr1 : 012FF718

    *intPtr1 = intArr1[0];
    cout << "*intPtr1 : " << intArr1[0] << endl;        //*intPtr1 : 1

    *intPtr1 = intPtr1[0];
    cout << "*intPtr1 : " << intPtr1[0] << endl;        //*intPtr1 : 1

    cout << endl;
    cout << endl;

    /* 그러면 intPtr1 +1 의 값은?*/
    cout << "intPtr1 : " << intPtr1 << endl;
    /** intPtr1 포인터 변수에 sizeof(*intPtr1)을 더한 주소값입니다. */
    cout << "intPtr1 + 1 : " << intPtr1 + 1 << endl;
    cout << endl;
    cout << endl;

    /*반복문으로 주소값 출력하기*/
    for (int i = 0; i< size(intArr1); i++)
    {
        cout << "address : " << &intArr1[i] << endl;
    }
    cout << endl;
    cout << endl;

    /* 배열이 아닌 포인터 주소로 알아보니 에러 발생*/
    // for(int i = 0; i < size(intPtr1); i++)
    // {

    // }

    /** double 타입으로 테스트를 해 봅니다.*/
    double doubleValue1[5] = { 3.14, 3.14, 3.14, 3.14, 3.14 };

    for (int i = 0; i < size(doubleValue1); i++)
    {
        cout << "double address : " << &doubleValue1[i] << endl;
    }

    cout << endl;
    cout << endl;

    cout << "size of double : " << sizeof(doubleValue1[0]) << endl;

    cout << endl;
    cout << endl;

    /** string 타입으로 테스트를 해 보도록 합니다.*/
    string stringValue1[] = { "Jane", "Tom", "James", "Emma", "Smith" };

    for (int i = 0; i < size(stringValue1); i++)
    {
        cout << "string address : " << &stringValue1[i] << endl;
    }
    cout << endl;
    cout << endl;

    cout << "size of string : " << sizeof(stringValue1[0]) << endl;

    cout << "size of string address : " << sizeof(&stringValue1[0]) << endl;

    cout << endl;
    cout << endl;

    /**
    배열포인터에 대해서 알아 봅니다.
    배열포인터는 배열 자체를 가리키는 포인터 입니다.
    */
    int intArr3[3] = { 1, 2, 3 };
    /** 사이즈가 3인 int타입의 배열을 가리키는 포인터를 선언합니다. */
    int(*arrPtr3)[3];

    arrPtr3 = &intArr3;

    /** 반복문으로 값 출력하기 */
    for (int i = 0; i < size(intArr3); i++)
    {
        /**
        배열포인터가 가리키는 값은 배열입니다.
        (arrPtr3) : 배열포인터입니다.
        *(arrPtr3) : 배열포인터가 가리키는 값은 배열입니다.
        (*arrPtr3)[i] : 배열에 인덱스로 접근합니다.
        */
        cout << "*(arrPtr3)[" << i << "] : " << (*arrPtr3)[i] << endl;
    }
    cout << endl;
    cout << endl;

    // 문장 추가
    int intArr4[5] = { 1, 2, 3, 4, 5 };
    /** int타입의 요소를 5개 가지고 있는 배열을 가리키는 배열포인터를 선언합니다. */
    int(*arrPtr4)[5];

    arrPtr4 = &intArr4;

    cout << "size of intArr4 : " << sizeof(intArr4) << endl;
    cout << endl;
    cout << endl;

    for (int i = 0; i < size(intArr4); i++)
    {
        cout << "intArr4[" << i << "] 주소값 : " << *arrPtr4 + i << endl;
    }
    cout << endl;
    cout << endl;

    for (int i = 0; i < size(intArr4); i++)
    {
        cout << "intArr4[" << i << "] 값 : " << (*arrPtr4)[i] << endl;
    }
    cout << endl;
    cout << endl;
}

3. 포인터배열

#include <iostream>

/** 문자열 관련 라이브러리*/
#include <string>
/** 배열의 사이즈를 알기 위한 라이브러리*/
#include <array>

/** C++ 표준 라이브러리 사용합니다. */
using namespace std;

int main()
{
    /**
    1. 배열과 포인터
    2. 배열포인터
    3. 포인터배열

    포인터배열을 자세하게 알기 위해서는 이중 for문, 2차원 배열의 지식이 필요합니다.
    */

    /** 3. 포인터배열*/

    // 구구단 
    for (int i = 2; i <= 9; i++)
    {
        for(int j = 1; j <=9; j++)
        {
            cout << i << " * " << j << " = " << i * j << endl;
        }
        cout << endl;

    }
    cout << endl;
    cout << endl;

    /**
    Row : 행, Column : 열

    세로 크기(행)가 3이고 가로 크기(열)이 4인 int타입의 2차원 배열을 선언합니다.
    */
    int numArr[3][4] =
    {
        {11, 22, 33, 44},
        {55, 66, 77, 88},
        {99, 110, 121, 132}
    };

    // 11 : 세로 인덱스 0, 가로 인덱스 0인 요소 출력
    cout << "numArr[0][0] : " << numArr[0][0] << endl;
    // 77 : 세로 인덱스 1, 가로 인덱스 2인 요소 출력
    cout << "numArr[1][2] : " << numArr[1][2] << endl;
    // 99 : 세로 인덱스 2, 가로 인덱스 0인 요소 출력
    cout << "numArr[2][0] : " << numArr[2][0] << endl;
    // 132 : 세로 인덱스 2, 가로 인덱스 2인 요소 출력
    cout << "numArr[2][3] : " << numArr[2][3] << endl;
    cout << endl;
    cout << endl;

    /* 
    행을 구하는 공식
    현재 2차원 배열의 행( 세로 크기 )의 사이즈는 3이다
    2차원 배열의 세로 크기를 구할 때는
    배열이 차지하는 전체 공간을 가로 한 줄의 크기로 나눠 준다.
    */
    int row = sizeof(numArr) / sizeof(numArr[0]);
    cout << "row : " << row << endl;
    cout << endl;

    /*
    열을 구하는 공식
    현재 2차원 배열의 열( 가로 크기 )의 사이즈는 4이다
    2차원 배열의 가로 크기를 구할 때는
    가로 한 줄의 크기를 요소의 크기로 나눠 준다
    */
    int col = sizeof(numArr[0]) / sizeof(int);
    cout << "col : " << col << endl;
    cout << endl;

    /**
    반복문으로 2차원 배열의 요소들을 출력하기.
    세로 크기와 가로 크기를 이미 구해 놓았다.
    반복문으로 세로부터 반복한 뒤, 가로를 반복하면서 2차원 배열의 요소를 출력한다.
    */

    // 2차원 배열의 세로 크기만큼 반복
    for (int i = 0; i < row; i++)
    {
        // 2차원 배열의 가로 크기만큼 반복
        for (int j = 0; j < col; j++)
        {
            // 반복문의 지역변수 i와 증감문으로 1씩 증가하므로 
            // 2차원 배열의 세로 인덱스에는 i의 값을
            // 2차원 배열의 가로 인덱스에는 j의 값을 넣으면
            // 배열의 요소를 순서대로 접근할 수 있다.
            cout << numArr[i][j] << " ";
        }
        // 가로 요소를 출력한 뒤에 다음 줄로 넘어감
        cout << endl;

    }
    cout << endl;
    cout << endl;

    /** 포인터배열은 배열 하나가 아닌 여러개의 배열을 한번에 처리할 수 있는 엄청난 효율이 있다. */

    /**
    2차원 배열의 요소들을 역순으로 출력하기.
    이미 세로 사이즈(행), 가로 사이즈(열)은 미리 구해 놓았다.
    반복문의 초기값에 배열의 세로 크기와 가로 크기를 바로 넣어 버리면
    처음부터 배열의 인덱스를 벗어난 상태가 된다.
    배열의 인덱스는 0부터 시작하기 때문이다.
    따라서 마지막 요소의 인덱스는 요소의 개수에서 1을 빼준다.
    그리고 0까지 반복할 수 있도록 조건식을 i >= 0와 같이 해 준다.
    */
    
    // 세로 크기 - 1 부터 역순으로 반복
    for (int i = row - 1; i >= 0; i--)
    {
        // 가로 크기 - 1 부터 역순으로 반복
        for (int j = col - 1; j >= 0; j--)
        {
            // 2차원 배열의 인덱스에 반복문의 변수 i, j를 지정
            cout << numArr[i][j] << " ";
        }
        //가로 요소를 출력한 뒤에 다음 줄로 넘어갑니다.
        cout << endl;

    }
    cout << endl;
    cout << endl;

    /** 포인터배열 : 포인터들을 배열에 저장. */
    int num1 = 100;
    int num2 = 200;
    int num3 = 300;

    int intArr1[3] = { num1, num2, num3 };

    for (int i = 0; i < size(intArr1); i++)
    {
        cout << "address : " << &intArr1[i] << ", value : " << intArr1[i] << endl;
    }

    cout << endl;
    cout << endl;

    /* 포인터배열은 틀리다.*/
    int* arr[3] = { &num1, &num2, &num3 };

    for (int i = 0; i < size(arr); i++)
    {
        cout << "address : " << arr[i] << ", value : " << *arr[i] << endl;
    }
    cout << endl;
    cout << endl;

    /**
   1. 2차원 배열에 배열들의 요소들을 출력해 보았다.
   2. 정수값을 포인터배열에 저장해서 요소들을 출력해 보았다.
   3. 포인터배열의 장점은 하나가 아닌 여러개의 배열을 한번에 처리할 수 있는 장점이 있다.

    배열을 포인터배열에 저장해서 요소들을 출력하기.
   */

   /**
   2차원 배열에서는 세로 크기와 가로 크기가 동일했다.
   각각의 배열들의 사이즈가 클리더라도 포인터배열은 배열을 저장하는 것이고
   배열의 포인터를 저장하는 것이라 배열들의 사이즈가 틀리더라도 가능하다.
   */
    int intArr2[5] = { 1, 2, 3, 4, 5 };
    int intArr3[6] = { 10, 20, 30, 40, 50, 60 };
    int intArr4[7] = { 100, 200, 300, 400, 500, 600, 700 };

    /**
    포인터배열을 선언하고 각각의 주소값을 대입해 준다.
    배열의 이름은 배열의 시작주소(배열의 0번째 인덱스 값의 주소)이므로 배열이름으로
    주소값을 대입한 것과 동일하다.
    */
    int* ptrArr[3] = { intArr2, intArr3, intArr4 };

    /**
    세로 사이즈(행)를 구하기.
    세로 사이즈는 3이다.
    */
    int length = size(ptrArr);

    /**
    가로 사이즈(열)를 구하기.
    배열의 사이즈가 틀리니 가로 사이즈는 배열로 만들어 준다.
    가로 사이즈는 배열 {5, 6, 7} 이다.
    */
    int subLength[3] = { size(intArr2), size(intArr3), size(intArr4) };

    /** 포인터배열의 세로 사이즈만큼 반복. */
    for (int i = 0; i < length; i++)
    {
        /**
        포인터배열의 가로 사이즈만큼 반복.
        가로 사이즈는 배열 크기가 모두 달라서 subLength배열에서 인덱스로 접근합니다.
        */
        for (int j = 0; j < subLength[i]; j++)
        {
            /** 포인터 배열의 인덱스에 반복문의 i와 j를 지정합니다. */
            cout << ptrArr[i][j] << " ";
        }
        /** 가로 요소를 출력한 뒤에 다음 줄로 넘어갑니다. */
        cout << endl;
    }
    cout << endl;
    cout << endl;

    /** 문자열로 된 배열을 포인터배열에 추가해 줍니다. */
    string names[5] = { "Tom", "John", "Jane", "Smith", "James" };
    string nations[3] = { "Korea", "Japan", "China" };
    string animals[6] = { "Tiger", "Lion", "Dog", "Cat", "Ang", "Pig" };

    /**
    포인터배열에 각각의 주소값을 대입합니다.
    배열의 이름은 배열의 시작주소(배열의 0번째 인덱스 값의 주소)입니다.
    */
    string* ptrArr1[3] = { names, nations, animals };

    /** 세로 사이즈(행, Row)를 구합니다. */
    int strLength = size(ptrArr1);

    /**
    가로 사이즈(열, Column)를 구합니다.
    배열들의 사이즈들이 모두 틀려서 배열에서 가로 사이즈를 구합니다.
    */
    int strSubLength[3] = { size(names), size(nations), size(animals) };

    /** 포인터배열의 가로 사이즈만큼 반복합니다. */
    for (int i = 0; i < strLength; i++)
    {
        /** 포인터배열의 세로 사이즈만큼 반복합니다. */
        for (int j = 0; j < strSubLength[i]; j++)
        {
            /**
            반복문의 변수 i와 j는 증감문을 통해서 1씩 증가하므로 포인터배열의 세로 인덱스에는 i의 값을
            포인터배열의 가로 인덱스에는 j의 값을 넣으면 포인터배열의 요소를 순서대로 접근할 수 있습니다
            */
            cout << ptrArr1[i][j] << " ";
        }
        /** 가로 요소를 출력한 뒤에 다음 줄로 넘어값니다. */
        cout << endl;
    }
    cout << endl;
    cout << endl;

}

0개의 댓글