자료형의 관점을 가지면서 주소를 담는 변수
int* _ptr = nullptr;
int 자료형의 주소 값을 가지는 변수
_ptr
float f = 5.f
// 강제로 int 타입 주소로 형변환하면?
int* _iptr = (int*)&f;
_iptr포인터가 참조하는 값은 5가 나올 것 같지만 f의 주소가 가리키는 값에 들어 있는 값은 실수형 방식으로 표현된 5.f입니다.
_iptr이 보는 관점은 int형 방식이므로 정수형 관점으로 값을 바라보기 때문에 실수형 방식으로 표현된 5.f 값을 정수형 방식으로 보게 됩니다.

f의 메모리 공간에 들어있는 값. 0x40a00000 형태의 값이 들어있는 것을 확인할 수 있습니다.

즉 해당 값을 int 자료형 관점의 값으로 바라보게 된다면 나오는 값은 다음과 같습니다.
#include <iostream>
int main()
{
int i = 100;
const int* _iptr = &i;
}
여기서 const int _iptr을 해석해 보자면
const int: 상수 관점으로 int 자료형을 바라보는.
*: 포인터 입니다.
#include <iostream>
int main()
{
int i = 100;
const int* _iptr = &i;
// 불가능!
// *_iptr = 120;
// 가능!
i = 120;
// 가능!
int x = 150;
_iptr = &x;
}
상수 관점으로 자료형을 바라보기에 안에 역참조시 안에 들어있는 데이터를 변경할 수는 없습니다.
그러나 주소를 상수 관점으로 바라보는 것은 아니기에 주소값은 변경이 가능합니다.
#include <iostream>
int main()
{
int i = 100;
int* const _iptr = &i;
}
int*: int 자료형 관점으로 바라봅니다.
const _iptr: _iptr을 상수 관점으로 바라봅니다.
변수의 이름은 주소를 별명으로 부르는 것과 같습니다.
이를 해석하자면 int 자료형 관점으로 바라보고 주소를 상수 관점으로 바라보는 포인터입니다.
#include <iostream>
int main()
{
int i = 100;
int* const _iptr = &i;
// 가능!
*_iptr = 120;
// 가능!
i = 120;
// 불가능!
int x = 150;
_iptr = &x;
}
안에 들어있는 데이터를 상수 관점으로 바라보는 것이 아닌 주소를 상수 관점으로 바라봅니다
해당 포인터는 안에 들어있는 데이터를 역참조해서 값을 변경할 수 는 있지만 자신이 가지고 있는 주소를 변경하는 행위는 불가능합니다.
#include <iostream>
int main()
{
int i = 100;
const int* const _iptr = *i;
}
const int*: int 자료형을 상수관점으로 바라봅니다.
변수는 주소의 별칭입니다.
const _iptr: 변수명_iptr에 해당하는 주소를 상수 관점으로 바라봅니다.
즉 안에 들어있는 자료형도 상수 관점으로 바라보고, 가지고 있는 주소값도 상수 관점으로 바라보는 것이 상수를 가리키는 상수 포인터입니다.
#include <iostream>
int main()
{
int i = 100;
int* const _iptr = &i;
// 불가능!
*_iptr = 120;
// 가능!
i = 120;
// 불가능!
int x = 150;
_iptr = &x;
}
안에 들어있는 데이터를 역참조해서 값을 변경하는 것도, 자신이 가지고 있는 주소값을 변경하는 것도 불가능한 포인터입니다.
#include <iostream>
int main()
{
void* _vptr = nullptr;
}
c++ 에서 void 타입은
타입 없음으로 정의됩니다.
#include <iostream>
int main()
{
int i = 100;
void* _vptr = &i;
}
void 포인터는 다른 자료형의 주소를 가져올 수 있습니다.
타입이 다른 자료형인데 왜 void pointer는 다른 자료형을 가져올 수 있을까요?
이것을 이해하기 위해서는 pointer의 특성을 이해해야 합니다.

c++ 에서 각 포인터의 크기는 자료형과 관계 없이 모두 동일합니다.
32비트 운영체제 환경에서는 4byte, 64비트 운영체제 환경에서는 8byte 크기입니다.
각 자료형과 관계없이 포인터의 크기가 동일한 이유는 포인터가 메모리의 주소값만을 가지는 특성때문에 자료형과 관계없이 들어있는 값은 메모리의 주소값이기 때문입니다.
#include <iostream>
int main()
{
int i = 100;
void* _vptr = &i;
}
다시 돌아와서 해당 포인터의 특성을 이용하여 c++ 에서는 void 타입 pointer가 다른 자료형의 주소를 가질 수 있도록 구성되어있습니다.
#include <iostream>
int main()
{
int i = 100;
void* _vptr = &i;
// 불가능!
*_vptr;
}
데이터를
타입없음관점으로 바라보기 때문에 데이터에 대한 직접적인 참조가 불가능합니다.
#include<iostream>
void vFunc(void* _vptr)
{
std::cout << "int 자료형 값?: " << *(int*)_vptr << std::endl;
}
int main()
{
int i = 100;
vFunc(&i);
short sh[2] = {2, 2};
vFunc(sh);
}
void pointer는 c++에서의 다형성과 일반성을 제공하기 위함입니다.
하지만 이러한 void 타입 포인터를 사용할 때는 주의할 점이 있습니다.
void 포인터는 타입에 대한 정보를 가지고 있지 않기 때문에 올바른 타입으로 캐스팅하지 않으면 잘못된 메모리 접근으로 인한 오류가 발생할 수 있습니다.
이러한 유연성은 적절한 타입 캐스팅과 주의깊은 사용이 필요합니다.
구조체안의 멤버 변수가 포인터 타입인 경우
#inlcude <stdio.h>
typedef struct person {
std::string name;
int age;
double* height; // 포인터 멤버 변수
}Person;
int main() {
// 구조체 변수 생성
Person person1;
// 동적으로 double 변수 할당
person1.height = new double;
*(person1.height) = 175.5;
// 데이터 출력
std::cout << "Person1: " << person1.name << ", " << person1.age << " years old, Height: " << *(person1.height) << " cm" << std::endl;
// 메모리 해제
delete person1.height;
return 0;
}
#include <iostream>
// 예제를 위한 구조체 정의
typedef struct point {
int x;
int y;
}Point;
int main() {
// 구조체 포인터 변수 생성 및 동적 할당
Point* pointPtr = new Point;
// 포인터를 통한 멤버 변수 접근
pointPtr->x = 5;
pointPtr->y = 10;
// 데이터 출력
std::cout << "Point Coordinates: (" << pointPtr->x << ", " << pointPtr->y << ")" << std::endl;
// 메모리 해제
delete pointPtr;
return 0;
}
#include <iostream>
// 전방 선언
struct B;
// 예제를 위한 구조체 정의
typedef struct A {
int dataA;
B* bPtr; // B 구조체를 가리키는 포인터
}A;
typedef struct B {
int dataB;
A* aPtr; // A 구조체를 가리키는 포인터
}B;
int main() {
// 구조체 변수 생성
A aInstance;
B bInstance;
// 포인터 설정
aInstance.bPtr = &bInstance;
bInstance.aPtr = &aInstance;
// 데이터 출력
std::cout << "A Data: " << aInstance.dataA << ", B Data: " << aInstance.bPtr->dataB << std::endl;
std::cout << "B Data: " << bInstance.dataB << ", A Data: " << bInstance.aPtr->dataA << std::endl;
return 0;
}
#include <stdio.h>
typedef struct node {
int data;
struct node* prev_link;
struct node* next_link;
}Node;
int main()
{
Node ob1; // Node1
// 초기화
ob1.prev_link = NULL;
ob1.next_link = NULL;
ob1.data = 10;
Node ob2; // Node2
ob2.prev_link = NULL;
ob2.next_link = NULL;
ob2.data = 20;
Node ob3; // Node3
ob3.prev_link = NULL;
ob3.next_link = NULL;
ob3.data = 30;
// Forward links
ob1.next_link = &ob2;
ob2.next_link = &ob3;
// Backward links
ob2.prev_link = &ob1;
ob3.prev_link = &ob2;
printf("%d\t", ob1.data);
printf("%d\t", ob1.next_link->data);
printf("%d\n", ob1.next_link->next_link->data);
printf("%d\t", ob2.prev_link->data);
printf("%d\t", ob2.data);
printf("%d\n", ob2.next_link->data);
printf("%d\t", ob3.prev_link->prev_link->data);
printf("%d\t", ob3.prev_link->data);
printf("%d", ob3.data);
return 0;
}
함수에 대한 포인터입니다
int (*funcPtr)();
int (*varPtr)(int, int);
int foo()
{
return 10;
}
int add(int x, int y)
{
return x + y;
}
int main()
{
// foo 호출 -> 암시적 호출
funcPtr();
// foo 호출 -> 명시적 호출
(*funcPtr)();
// add(int x, int y) 호출
varPtr(5, 5);
}
void sort(int* array, int size, bool isAscending, void (*select_sort)(int*, int, bool)
{
(*select_sort)(array, size, isAscending);
}
typedef void (*SortType)(int*, int, bool)
void sort(int* array, int size, bool isAscending, SortType sort_type)
{
sort_type(array, size, isAscending);
}
using SortType void(*)(int*, int, bool);
void sort(int* array, int size, bool isAscending, SortType sort_type)
{
sort_type(array, size, isAscending);
}
#include <functional>
void sort(int* array, int size, bool isAscending, std::function<void*(int*, int,bool)> sort_type)
{
sort_type(array, size, isAscending);
}
(문제를 푼뒤 코드로 확인해 주세요.)
다음 문제에서 출력될 숫자의 결과를 알려주세요.
#include <iostream>
int main()
{
char c[2] = {2, 2};
std::cout << *(short*)c << std::endl;
}
다음 문제에서 출력될 결과를 알려주세요.
#include <iostream>
int main()
{
int i = 100;
const int* _iptr = &i;
i = 150;
std::cout << *_iptr << std::endl;
}
다음 문제에서 int 자료형 i를 출력시키기 위한 구문을
?위치에 작성해주세요.
#include <iostream>
int main()
{
int i = 100;
void* _vptr = &i;
std::cout << ? << std::endl;
}
다음 문제에서 출력될 결과를 알려주세요.
#include <iostream>
int main()
{
char c[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << (int)*(char*)((short*)c + 2) << std::endl;
}
std::function을 이용해서 다음
?빈칸을 채워주세요.
?
void sort(int* array, int size, ? sort_type)
{
sort_type(array, size);
}
[현재 작성 중]