IVS/C 프로그래밍
[C++] 포인터
코곰_
2025. 1. 8. 14:50
포인터(Pointer)란?
- 값이 아닌 변수의 메모리 주소를 저장하는 변수
- * 연산자를 사용하여 값을 역참조(dereferencing)하거나, & 연산자를 사용하여 주소를 참조할 수 있다.
- 포인터를 사용하면 메모리의 주소를 직접 다룰 수 있어 효율적인 메모리 관리와 데이터 구조를 처리할 수 있다.
포인터의 선언
int* ptr; // 'ptr'은 int형 변수를 가리키는 포인터
- ptr은 int형 변수의 주소를 저장하는 포인터
포인터 변수의 참조(&)와 역참조(*)
- & (주소 연산자): 변수의 메모리 주소를 가져온다.
- * (역참조 연산자): 포인터가 가리키는 메모리 주소에 저장된 값을 가져온다.
#include <iostream>
using namespace std;
int main() {
int a = 10; // 정수 변수 a
int* ptr = &a; // a의 주소를 ptr에 저장 (ptr은 a를 가리키는 포인터)
cout << "a의 값: " << a << endl; // a의 값 출력
cout << "ptr이 가리키는 값: " << *ptr << endl; // ptr이 가리키는 값 출력 (a의 값)
cout << "a의 주소: " << &a << endl; // a의 주소 출력
cout << "ptr의 값 (주소): " << ptr << endl; // ptr의 값 (주소) 출력
return 0;
}
출력 예시:
a의 값: 10
ptr이 가리키는 값: 10
a의 주소: 0x7ffee36b7b2c (주소는 시스템에 따라 다를 수 있습니다)
ptr의 값 (주소): 0x7ffee36b7b2c
배열과 포인터
배열 이름은 배열의 첫 번째 요소에 대한 포인터로 간주할 수 있다.
#include <bits/stdc++.h>
using namespace std;
void abc(int *p){
printf("%d", p[1]); // 8
printf("%d", *(p+1)); // 8
}
void def(int arr[]){ //배열을 입력받은 것 같지만 배열포인터
printf("%d", arr[1]); // 8
printf("%d", *(arr+1)); // 8
}
int main(void)
{
int arr[3] = {7, 8, 9};
abc(arr);
def(arr);
return 0;
}
- arr: 배열의 첫 번째 요소에 대한 포인터
- *(ptr + i): 포인터 연산을 통해 배열 요소를 접근
포인터배열 vs 배열포인터
포인터 배열: 각 요소가 포인터인 배열
- 주소값을 저장하는 배열
int* arr[3]; // int형 포인터를 요소로 갖는 배열
배열 포인터: 배열을 가리키는 포인터
- 배열의 주소값을 저장하는 포인터
int (*ptr)[3]; // 크기가 3인 int 배열을 가리키는 포인터
포인터의 동적 메모리 할당
C++에서는 new와 delete 연산자를 사용하여 동적으로 메모리를 할당하고 해제할 수 있다. 이를 통해 힙(heap) 영역에서 메모리를 할당하고, 사용 후에는 반드시 delete로 해제해야 한다.
#include <iostream>
using namespace std;
int main() {
int* ptr = new int; // int 크기만큼 동적으로 메모리 할당
*ptr = 20; // 할당된 메모리에 값 저장
cout << "ptr이 가리키는 값: " << *ptr << endl; // 20 출력
delete ptr; // 동적으로 할당된 메모리 해제
return 0;
}
- new 연산자: 메모리를 동적으로 할당하고, 그 메모리의 주소를 반환
- delete 연산자: 동적으로 할당된 메모리를 해제
이중 포인터
포인터는 또 다른 포인터를 가리킬 수 있다. 이를 다중 포인터(multi-pointer)라고 한다.
#include <iostream>
using namespace std;
int main() {
int a = 10;
int* ptr = &a; // ptr은 a의 주소를 가리킴
int** ptr2 = &ptr; // ptr2는 ptr의 주소를 가리킴
cout << "a의 값: " << a << endl;
cout << "ptr이 가리키는 값: " << *ptr << endl;
cout << "ptr2가 가리키는 값: " << **ptr2 << endl; // **ptr2는 a의 값
return 0;
}
출력 예시:
a의 값: 10
ptr이 가리키는 값: 10
ptr2가 가리키는 값: 10
- ptr은 a의 주소를 가리키는 포인터이고, ptr2는 ptr의 주소를 가리키는 포인터
- **ptr2는 결국 a의 값을 가져온다.
① 배열 포인터 사용 예시
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int main(void)
{
// 배열포인터 이용
char (*st)[11] = (char(*)[11])malloc(sizeof(char) * 11 * 3);
for (int x = 0; x < 3; x++) {
scanf("%s", st[x]);
}
for (int x = 0; x < 3; x++) {
printf("%s", st[x]);
}
return 0;
}
② 이중 포인터 사용 예시
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int main(void)
{
char** st = (char**)malloc(sizeof(char*) * 3);
for (int x = 0; x < 3; x++) {
// 2중 포인터 안에 1중 포인터 11개
st[x] = (char*)malloc(sizeof(char) * 11);
}
for (int x = 0; x < 3; x++) {
scanf("%s", st[x]);
}
for (int x = 0; x < 3; x++) {
printf("%s", st[x]);
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef struct Node{
int a;
int b;
}Node;
Node abc(int* p, int* r, int arr[2], int tt, char t4){
int t1 = 10;
int t2 = 20;
*p = t1 + t2;
*r = t1 * t2;
arr[0] = t1 + t2;
arr[1] = t1 * t2;
Node answer = {t1+t2, t1*t2};
return answer;
}
int main(void)
{
Node t;
int S, M;
int arr[2];
Node ans = abc(&S, &M, arr, 1, 'A');
return 0;
}
1. int *p; 포인터 변수는 다른 변수의 주소값을 저장
2. P = &a; : 가르킨다 = dereferencing = 역참조
3. *p = 10;