포인터(pointer)

포인터(pointer)와 함수포인터

ShadowEye 2021. 6. 21. 13:40

1. 포인터(pointer)

C언어에서 포인터(pointer)란 메모리의 주소값을 저장하는 변수이며, 포인터 변수라고도 부릅니다.

char형 변수가 문자를 저장하고, int형 변수가 정수를 저장하는 것처럼 포인터는 주소값을 저장합니다.

 

비유 해서 설명해보자면 아래와 같습니다.


택배 아저씨가 하는 일 !

  • 고객의 주소를 저장하고 있다가 해당 주소로 물건을 전달하는 일 !
  • 고객의 주소를 저장하고 있다가 해당 주소로 물건을 받아가는 일 !
  • ‘우리에게 ‘간접 접근’ 서비스를 제공한다.’

택배 아저씨가 있어서 우리가 편리한 점

  • 물품을 수령하기 위해 직접 구매처를 방문 하지 않아도 된다.
  • 반품을 위해 직접 구매처를 방문 하지 않아도 된다.

컴퓨팅 세계에서 택배 아저씨와 같은 일을 하는 변수 !

  • 포인터 변수 (포인터라고도 부름)
  • 메모리의 주소를 저장하고 있다가 해당 주소로 데이터를 전달 하는 일
  • 메모리의 주소를 저장하고 있다가 해당 주소로 데이터를 참조 하는 일


2. 포인터 연산자

C언어에서 포인터와 연관되어 사용되는 연산자는 다음과 같습니다.

 

1. 주소 연산자(&)

2. 참조 연산자(*)

 

2.1 주소 연산자(&)

주소 연산자는 변수의 이름 앞에 사용하여, 해당 변수의 주소값을 반환합니다.

'&'기호는 앰퍼샌드(ampersand)라고 읽으며, 번지 연산자라고도 불립니다.

 

2.2 참조 연산자(*)

참조 연산자는 포인터의 이름이나 주소 앞에 사용하여, 포인터에 가리키는 주소에 저장된 값을 반환합니다.

 

C언어에서 '*'기호는 사용하는 위치에 따라 다양한 용도로 사용됩니다.

이항 연산자로 사용하면 곱셈 연산으로 사용되며, 포인터의 선언 시나 메모리에 접근할 때도 사용됩니다.

 

3. 포인터의 선언

포인터의 선언은 다음과 같습니다

 

c++에서 포인터를 선언하기!!

	int num = 10;

	//int형 포인터 변수
	int* pNum = #
    
	cout << "num :\t" << num << endl;
	cout << "pNum :\t" << pNum << endl;

출력시

보시다시피 위에는 num의 값을 출력하고

아래에는 num의 값이 저장되어있는 주소값을 출력합니다.

 

4. 다차원 포인터 (주로 이중포인터)

다차원 포인터는 말그대로 2차원 이상의 포인터 변수를 의미합니다.

즉 변수의 주소값을 저장하고 있는 포인터의 주소값을 저장 하고 있는 포인터이지요

 

선언 형태는 다음과 같습니다.

 

 

c++에서 이중포인터를 선언하기!!

	int num = 10;

	//int형 포인터 변수
	int* pNum = &num;

	//int형 포인터 변수
	int** ppNum = &pNum;

	cout << "num :\t" << num << endl;
	cout << "pNum :\t" << pNum << endl;
	cout << "ppNum :\t" << ppNum << endl;

 



4. 주소의 가감산


주소의 가감산이란 변수에다가 참조연산자 * 나 주소 연산자 & 를 사용하여 포인터에있는 데이터값을 불러오거나 아니면 데이터가 저장되어있는 주소값을 구할때 사용합니다.

아래의 예제를 보면

 

	int a = 3;
	int* pa = &a;
	int** ppa = &pa;

	cout << "a :\t" << a << endl;
	cout << "&a :\t" <<&a << endl;
	cout << "pa :\t" <<pa << endl;
	cout << "&pa :\t" <<&pa << endl;
	cout << "*pa :\t" <<*pa << endl;
	cout << "*ppa :\t" << *ppa << endl;
	cout << "&ppa :\t" << &ppa << endl;
	cout << "ppa :\t" << ppa << endl;
	cout << "**ppa :\t" << **ppa << endl;

위의 예제를 출력해보면 다음과  같습니다.

 


a가 저장되어있는 주소값인 pa의 관계가 있습니다.

 

이는 a의 주소값을 구하는 연산자사용한 &a는 pa와 같다는걸 의미하며 

또다른뜻은 pa의 주소에 저장되어있는 데이터 값을 구하는 연산자를 사용한 *pa의 값은 a와 같다는 걸 의미합니다.

 

이처럼 연산자를 사용해서 값을 가져오거나 혹은 해당값의 주소를 가져오는게 가능합니다.

 

 

또한 이중포인터인 ppa에다가 참조연산자 *를 두번사용하면 원래 데이터인 a의 값을 구해오는게 가능합니다.

5. 함수 포인터

함수포인터는 함수의 시작 주소를 저장하는 변수입니다.

  • 자료형: 가리키는 대상이 되는 함수의 자료형을 설정 
  • 함수 포인터 이름: 괄호와 *을 반드시 사용 인수 자료형
  • 목록: 가리키는 대상이 되는 함수의 인수들의 자료형 목록

#include<stdio.h>

void add(double num1, double num2);
int main()
{

    double x = 3.1, y = 5.1;
    void(*pointer)(double, double); //함수 포인터 선언

    prinG("add!함수의 주소 :%x\n", add);
    prinG("함수 포인터의 주소 :%x\n", &pointer);

    pointer = add;
    pointer(x, y);//함수 포인터를 이용한 호출

    return 0;
}

void add(double num1, double num2)
{
    
   double!result; 
   result = num1 + num2;
   prinG("%lf+%lf=%lf입니다.\n", num1, num2, result);
}

위의 예제에서 보면 함수에대한 포인터를 선언하고 사용 방법은 기존의 함수와 매우 유사합니다.

 


5.1 함수 포인터의 필요성

일반적인 함수 호출 보다 빠른 처리 속도를 기대할수 있습니다

 

사용 분야

  • 컴파일러, 인터프리터, 게임 프로그래밍과 같은 시스템 프로그래밍 분야