포인터

sungyeon_park·2024년 1월 10일
0

목적 : 내가 까먹었을때나 앞으로 백준문제 풀때 포인터를 좀 더 자세히 알아보기 위한 참고자료로 쓰기

배열과 포인터

포인터와 배열은 주소값을 갖는다.

예를 들면 int a[4]; 에서 a는 배열이고 a[0]의 주소값을 갖고 있다.
그리고 int *p; 에서는 p는 포인터이고 배열과 달리 아직 주소값을 갖고 있지 않다.

a[0]의 주소가 1000번지이고 int a[4]; (크기가 4인 배열)이라면 a[i]의 주소는 1000 + 4 x i 가 된다.

배열의 인스턴스

배열의 인스턴스는 상수(constant : 변하지 않는 값)이다. assignment(=)의 왼쪽 피연산자가 될 수 없다.

int a[4];
int *p;
p = a;

에서 a=a+2; 또는 a++; a--;는 모두 틀린 경우다.

포인터의 인스턴스

p는 포인터 인스턴스이고 포인터 인스턴스는 변수임으로(변할 수 있음)
p+=3; 또는 p--;++p;는 모두 옳은 문장이다.


int *p(포인터)의 경우 아직 할당되지 않은 메모리를 참조하는 이유로 프로그램 오류가 발생할 수 있다.
포인터는 선언된후 사용되기 전에 메모리를 할당받은 인스턴스의 주소를 공유하거나 스스로 사용할 메모리를 할당 받아야 한다.

int ***p; 는 3차원 배열로 생각 될 수 있다. (1차원의 3개 있는 것이라고 볼 수 있다 : 포인터의 포인터의 포인터)

예)

int ***ppp = new int**[2];

for (int i=0; i<2; i++){
	ppp[i] = new int*[3];
	for(int j=0; j<3;j++){
		ppp[i][j] = new int[4]; .... 

포인터의 동적할당

배열에 대한 메모리는 정적으로 할당되고 포인터에 대한 메모리는 동적으로 할당된다.

#include <iostream>
using namespace std;
int main() {
    int n;
    cout << "Enter the size of the array: ";
    cin >> n;
    // 동적으로 배열을 할당한다.
    int* array = new int[n];
    //
    for (int i = 0; i < n; i++) {
        array[i] = i;
    }
    //
    for (int i = 0; i < n; i++) {
        cout << array[i] << " ";
    }
    cout << endl;
    // 할당된 메모리를 해제한다.
    delete[] array;
    return 0;
}

포인터 외에 map은 키와 값을 저장하는 컨테이너로 학과와 학생수, 혹은 계좌번호와 보유잔고 등의 과제를 다룰때 용이하게 쓸 수 있을것 같다.

#include <iostream>
#include <map>
#include <string>
using namespace std;
//
int main() {
    map<string, int> 학과;
    int n;
    cout << "학과의 수를 입력하세요: ";
    cin >> n;
//
    for (int i = 0; i < n; i++) {
        string 학과이름;
        int 학생수;
        cout << "학과 이름과 학생 수를 입력하세요: ";
        cin >> 학과이름 >> 학생수;
        학과[학과이름] = 학생수;
    }
    cout << "\n학과와 학생 수:\n";
    for (auto& 학과정보 : 학과) {
        cout << "학과: " << 학과정보.first << ", 학생 수: " << 학과정보.second << "\n";
    }
    return 0;
}

for(auto&)문은 자바의 for-each문처럼 범위기반 for문이다.
읽기 전용이면 const auto&를 사용하는게 좋다고 한다.

포인터를 이용한 학과, 학생수 입력

#include <iostream>
#include <string>

using namespace std;

struct 학과정보 {
    string 학과이름;
    int 학생수;
};

int main() {
    int n;
    cout << "학과의 수를 입력하세요: ";
    cin >> n;

    학과정보* 학과 = new 학과정보[n];
    
    for (int i = 0; i < n; i++) {
        cout << "학과 이름과 학생 수를 입력하세요: ";
        cin >> 학과[i].학과이름 >> 학과[i].학생수;
    }
    cout << "\n학과와 학생 수:\n";
    
    for (int i = 0; i < n; i++) {
        cout << "학과: " << 학과[i].학과이름 << ", 학생 수: " << 학과[i].학생수 << "\n";
    }

    delete[] 학과;
    
    return 0;
}

추가적인 이용방법 : 포인터를 함수처럼 이용하기

int add(int a, int b){return a+b;}
int sub(int a, int b){return a-b;}

void main(){
  int (*f[2])(int,int);
  f[0]=add;
  f[1]=sub;
  
  int a, b;
  cin >> a >> b;
  for(int i=0;i<2;i++){
	 cout << (*f[i])(a,b) << endl;
  }
}

출처: < < 자료구조와 알고리즘 > 저자: 김종현>

profile
박성연

0개의 댓글