1. 참조자 VS 포인터

(개념이 확실하지 않아서 이게 뭐라고 둘이 헷갈렸음)

포인터는 변수의 주소값을 저장하고 있음

참조자는 어느 변수가 가리키는 값을 똑같이 가리키고 있음. 동일한 메모리 공간 가리킴. (&로 표시하지만 주소값을 가리키는 건 아님)

ex)

int num1 = 2021;

int *ptr = &num1;

itn &num2 = num1; // num2는 num1의 참조자


2. 함수의 호출방식

Call by value : 값을 인자로 전달하는 함수의 호출방식

Call by reference : 주소 값을 인자로 전달하는 함수의 호출방식. 주소값을 전달 받아 함수 외부에 선언된 변수에 접근.

 

Call by value로 정의된 함수의 내부에서는 함수외부에서 선언된 변수에 접근이 불가능하다.

따라서 두 변수에 저장된 값을 서로 바꿔 출력하려면 Call by reference로 main함수 외부를 작성해야 한다.

void SwapByRef(int *ptr1, int *ptr2)
{
    int temp = *ptr1;
    *ptr1 = *ptr2;
    *ptr2 = temp;	// call by reference
}

int main
{
	int num1 = 10;
    int num2 = 20;
    SwapByRef(&num1, &num2);
    cout << num1 << endl;	// 20 출력
    cout << num2 << endl;	// 10 출력
    
    return 0;
}

 


3. const

변수를 상수화 시킬 때 사용하는 키워드

상수화된 변수는 변경이 불가능하며, 포인터 변수에도 똑같이 작용한다.

 

1) 상수 변수

선언과 동시에 초기화하는 것은 가능하나 후에 상수의 값을 변경하려는 건 불가능하다.

"선언과 동시에 초기화"

const int MAX = 20;

 

2) 상수 포인터

int a = 1;

const int* p1 = &a; // "포인터 변수가 가리키는 주소의 값은 변경X, 주소값은 변경O"

                          // int* p1을 상수화, p1이 상수가 되어 가리키는 값이 상수가 됨.

int* const p2 = &a; // "포인터 변수가 가리키는 주소의 값은 변경O, 주소값은 변경X"

const int* const p2 = &a; // "포인터 변수가 가리키는 주소의 값은 변경X, 주소값은 변경X"

 

 

 

 

1. 정적할당 : 처음부터 끝까지 메모리를 들고 있는 것

2. 동적할당 : 개발자가 런타임 도중 원할 때 메모리를 할당하고 해제해주는 것

 

3. 포인터

: 변수의 주소를 저장하는 변수. (변수의 주소가 저장됨)

 

포인터는 변수a의 (메모리 공간의) 주소(200번)가 포인터에 저장된다.(200) 이 포인터는 해당 주소의 변수를 가리키고 그 변수 안에 값(5)이 저장되어 있다.

 

가리킬 변수의 자료형을 포인터 앞에 적어 선언한다.

 

<C에서 포인터>

#include <stdio.h>

int main()
{
	int a = 5;
	int *ptr_a; // 여기서 *는 포인터를 선언하기 위해 붙음
	ptr_a = &a; // &는 주소를 뜻함. 만약 주소를 200이라면

	printf("ptr_a에 저장된 값 : %d\n", ptr_a); // 200 출력
	printf("ptr_a가 가리키는 변수의 값 : %d\n", *ptr_a); // 5 출력. 여기서 *는 역참조?로 a 값 출력
	
	*ptr_a = 10; // ptr_a가 가리키는 변수의 값이 5에서 10으로 변경됨
	printf("ptr_a가 가리키는 변수의 값 : %d\n", *ptr_a); // 10
	printf("ptr_a가 가리키는 변수의 값 : %d\n", a); // 둘 다 같음. 10
    
    return 0;
}

프린트문에 *ptr_a는 역참조인가??

*(역참조) : (포인터로 가리킨) 해당 주소에 저장된 값?

 

#include <stdio.h>

// 각각 주소 임의로 설정함

int main()
{
    int a = 5;
    
    int *ptr;
    ptr = &a;
    
    int **ptr_ptr; // *(*ptr_ptr)과 같은듯?
    ptr_ptr = &ptr;
    
    printf("a = %d\n", a);   // 값 5
    printf("&a = %d\n", &a); // 주소 200
    
    printf("ptr = %d\n", ptr); // 값 200
    printf("&ptr = %d\n", &ptr); // 주소 300
    
    printf("ptr_ptr = %d\n", ptr_ptr); // 값 300
    printf("&ptr_ptr = %d\n", &ptr_ptr); // 주소 500
    printf("*ptr_ptr = %d\n", *ptr_ptr); // 값 200
    printf("**ptr_ptr = %d\n", **ptr_ptr); // 값 5
    
    return 0;
}

하 이건가..?

 

#include <stdio.h>

int main()
{
    int numArr[5] = { 11, 22, 33, 44, 55 };
    int *numPtrA; // *는 포인터 numPtrA를 선언하기 위함. 주소값
    //int *numPtrB;
    //int *numPtrC;
    
    numPtrA = numArr; // 배열의 첫번째 주소(numArr[0])?는 numArr다?
    
    //numPtrB =numPtrA + 1; // 주소 한칸씩 옆으로 옮기기, numArr[1] 주소?와 같음
    //numPtrC =numPtrA + 2; // numArr[2]와 같음
    
    //printf("%d\n", *numPtrB); // 22, *numPtrB는 numArr[1]값과 같음
    //printf("%d\n", *numPtrC); // 33, numArr[2]값
    printf("%d\n", *(numPtrA + 1)); // 22
    printf("%d\n", *(numPtrA + 2)); // 33
    printf("%d\n", *numPtrA + 1); // 12
    
    return 0;
}

 

<C++에서 포인터>

#include <iostream>
using namespace std;

int main()
{
    int *a = new int(5);	// *a는 int를 가르키는 포인터
    // (int)메모리 상의 공간에 5라는 값이 담기고 이 메모리의 주소가 200이라면 (메모리 할당)
    // 주소값 200을 a가 담고, 포인터 *a는 주소 200 안에 담긴 값 5를 가르킴
    
    cout << a << endl;	// 주소값 출력. 200
    cout << *a << endl;	// 실제로 저장된 값 출력. 5
    
    *a = 10; // 5가 저장된 걸 10으로 바꿔라
    
    cout << a << endl;	// 주소값 출력. 200
    cout << *a << endl;	// 실제로 저장된 값 출력. 10
    
    delete a;	// 할당했던 메모리가 해제되어 낭비가 되지 않음
}

200번지 메모리공간을 포인터 *a가 가르킴  

 

+ Recent posts