Skip to content

Latest commit

 

History

History
317 lines (208 loc) · 6.79 KB

12.pointer.md

File metadata and controls

317 lines (208 loc) · 6.79 KB

포인터

일반 변수는 일반적인 값을 저장하지만, 포인터 변수는 주소값을 포함합니다.

모든 변수 타입은 포인터로 지정할 수 있습니다.

예를 들어 int변수의 주소는 int타입의 토인터 변수에 저장합니다.

참고로, 포인터는 스스로 아무 것도 못합니다.

포인터 크기

  • 32비트 : 4byte
  • 64비트 : 8byte

포인터 쉽게 알아보기

int *pointer= &i;

*을 붙히면 포인터 변수로 선언됩니다.

&를 붙히면 변수의 주소값이 나타납니다.

즉, int 타입의 포인터에 i의 주소값을 대입합니다.

포인터 간단 예제

포인터가 i를 가리키고 있으므로, 포인터에 100을 더해보겠습니다.

#include<iostream>

using namespace std;

int main() {
    int i = 0;
    int * pointer= &i;

    *pointer += 100;

    cout <<"i value : "<< i << endl;
    cout <<"i address : " << &i << endl;
    cout << "pointer value : " << pointer << endl;
    cout << "pointer address : " << &pointer << endl;

    return 0;
}

더하고 출력해보면, i에 100이 들어가있는 것을 확인할 수 있습니다.

그리고 i의 주소값이랑 포인터의 내용이 같다는 것도 확인할 수 있습니다.

배열과 포인터

배열은 주소값이 기본적으로 출력됩니다.

그리고 포인터는 배열에 접근할 수 있습니다.

#include<iostream>

using namespace std;

int main() {
    int a[10] = { 1,2,3,4,5,6,7,8,9,10 };

    cout << "array address : "<<a << endl;
    cout << "array address : " << &a << endl;
    cout << "array[0] address : " << &a[0] << endl; 
    int *array_pointer = &a[0];
    cout << "array pointer[3] value : " << array_pointer[3] << endl;

    return 0;
}

포인터도 배열로 개별 지정해서 사용할 수 있습니다.

#include<iostream>

using namespace std;

int main()
{
    int a[4] = { 1,2,3,4 };
    cout << a[0] << a[1] << a[2] << a[3] << endl;

    int *pstr[4];

    pstr[0] = &a[0];
    pstr[1] = &a[1];
    pstr[2] = &a[2];
    pstr[3] = &a[3];

    cout << *pstr[0] << *pstr[1] << *pstr[2] << *pstr[3] << endl;

    return 0;
}

한번 실습해보시기 바랍니다.

포인트 배열과 배열 포인트의 차이점

  • 포인트 배열 : 데이터를 가리킬 수 있는 포인터 변수를 모아 놓은 배열을 가리킵니다.

  • 배열 포인터 : 데이터를 저장할 수 있는 2차원 배열을 가리킵니다.

포인터로 주소값 연산

메모리 주소값에 +,- 연산이 가능합니다.

다만, 1을 더하면 2가 되는게아니라 포인터 크기만큼 더해집니다.

#include<iostream>

using namespace std;

int main() {
    int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int *array_pointer = &a[0];

    cout << "array pointer address : " << &array_pointer << endl;
    cout << "array pointer address : " << &array_pointer + 2<< endl;

    return 0;
}

위와 같은 경우는 2를 더했으므로, 결과적으로 8이 증가합니다.

char 포인터

"text string"을 가리키는 포인터를 정의해주면, 포인터는 문자열의 주소를 가지게된다.

문자열이 같으면 같은 주소를 가진다.

주소값을 나타내려면 int로 형변환해야한다.

#include<iostream>

using namespace std;

int main() {
    char *text = "text string";

    cout << "char pointer value : " << text << endl;
    cout << "char pointer address : " << (int*)text << endl;

    text = "text text string";

    cout << "char pointer value : " << text << endl;
    cout << "char pointer address : " << (int*)text << endl;

    text = "text string";

    cout << "char pointer value : " << text << endl;
    cout << "char pointer address : " << (int*)text << endl;

    return 0;
}

구조체 포인터

구조체도 포인터로 지정할 수 있습니다.

온점대신 "->"를 이용해도 됩니다.

#include<iostream>

using namespace std;

struct student
{
    int score;
};

int main() {
    student korean_student = {};
    korean_student.score = 100;

    student *pointer_student = &korean_student;

    (*pointer_student).score = 70;
    pointer_student->score = 80;
    cout << "korean_student's value : " << korean_student.score << endl;
    cout << "korean_student's address : " << &korean_student.score << endl;

    return 0;
}

void 포인터

포인터의 타입을 따로 지정하지않아도 들어가는 값에 따라 타입이 변하는 포인터입니다.

#include<iostream>

using namespace std;

struct student
{
    int score;
};

int main() {
    int i = 0;
    student korean_student = {};
    korean_student.score = 100;
    void *v_pointer = &i;
    int *convert = (int *)v_pointer;
    *convert += 1000;
    cout << "i value : " << i << endl;
    cout << "void pointer i : " << v_pointer<< endl;
    v_pointer = &korean_student.score;
    cout << "void pointer score : " << v_pointer << endl;

    return 0;
}

이중 포인터

포인터의 주소값을 이중 포인터에 저장합니다.

#include<iostream>

using namespace std;

int main() {
    int myint = 1000;
    int *pint = &myint;
    int **ppint = &pint;

    cout << "myint : " << myint << endl;
    cout << "&myint : " << &myint << endl;

    cout << "pint : " << pint << endl;
    cout << "*pint : " << *pint << endl;
    cout << "&pint : " << &pint << endl;

    cout << "ppint : " << ppint << endl;
    cout << "*ppint : " << *ppint << endl;
    cout << "**ppint : " << **ppint << endl;
    cout << "&ppint : " << &ppint << endl;

    return 0;
}

비슷한 기능, 레퍼런스

다른 대상을 참조하게 만들어주는 기능입니다.

참조를 하게되면 그 대상에 접근하여 값을 변경할 수 있습니다.

단, 레퍼런스는 처음 레퍼런스 변수 생성시 참조하는 대상을 지정해주어야 합니다.

int num = 100;
int &ref = num;

ref = 123;

다만 포인터와 다르게 다른 대상을 자유롭게 옮기지는 못합니다.

함수 포인터

함수도 포인터로 지정해서 사용할 수 있습니다.

int output(int a){
    cout<< a+a << endl;
    return a + a
}

int main(){
    int(*pfunc)(int) = output;
    pfunc(10);
}

같은 타입의 함수는 언제든지 갈아탈수 있지만, 다른 타입은 다르게 지정해야합니다.

과제

  • 과제1 : void 포인터를 이용하여 임의로 생성한 int로 접근해서 값을 변경해보기

  • 과제2 : 포인터를 이용하여 임의로 생성한 int로 접근해서 값을 변경해보기

  • 과제3 : 아래 코드에서 이중 포인터를 이용하여 임의로 생성한 최초의 int(myscore)로 접근해서 값을 출력보기

#include<iostream>

using namespace std;

int main() {
    int myscore = 1000;
    //이곳을 완성합니다.
    int number = 0;

    cout << number << endl;
    return 0;
}