티스토리 뷰

반응형

 

* 다차원 포인터란?

'*'이나 []의 갯수가 하나가 아닌 여러개를 가지는 변수(포인터)

 

 

* 포인터 분석 순서
1. 먼저 포인터 변수를 찾아라
2. 포인터를 파악하면 포인터의 오른쪽부터 읽어라
3. 오른쪽을 읽으면 포인터의 왼쪽을 읽어라

 

 

* 포인터 코드 분석

1. 정체 파악
2. 나머지는 용도
3. 읽는 법은 이름을 기준으로 오른쪽부터 읽어야 함. 정체 파악하면 읽는거 멈춰야함. 2번 읽으면 안됨

 

 

ex1)

int *p;
1. p옆은 ; 끝이므로 *로 간다. *p는 포인터 이므로 int로 간다.

2. 정체 : 포인터

3. 용도 int 타입
>> int *p는 int타입을 가진 포인터이다.

 

 

ex2)

int *p[3];
1. p옆은 [3]첨자, 3개짜리 배열이다.int *로 간다.

2. 정체 : 배열

3. 용도 : int 타입 포인터
>> int 포인터가 3개 있는 배열이다.

 

 

ex3)

int **p;

1. p 옆은 ;끝이므로 *로 간다. *p는 포인터다. 왼쪽으로 가면 int *다.
2. 정체 : 포인터

3. 용동 int 타입 포인터

>> int 포인터를 가리키는 포인터이다.

 

 

ex4)

int (*p)[3];

1. 괄호안부터 본다.(*p)는 포인터이다. [3]로 간다.

2. 정체 : 포인터

3. 용도 : 포인터를 가리키는 int 배열
>>한 행당 메모리 3개를 가지고 있는 int 배열을 가르키는 포인터
 

 

ex5)
int *(*p)(int **pp);

1.괄호안 (*p)부터 읽는다. int *(int **pp)는 함수를 가르키는 포인터 형태다.

2. 정체 : 포인터

3. 용도 : 포인터의 포인터를 인자로 같는 int 타입 함수

>> 포인터의 포인터를 인자로 같는 int 타입 함수를 가리키는 포인터의 포인터이다.

 

 

* 아래 코드를 보고 다차원 포인터의 쓰임을 알아보자

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <iomanip>
using namespace std;
 
 
//
 
void main(int) {
 
    int a[2][3= { 6,5,4,3,2,1 };
    int i, j;
    int (*p)[3];//다차원 포인터
    //한행당 3개의 메모리를 가지고 있는 포인터
    //움직일때마다 3개 배열을 가진 덩어리 전체가 움직인다.
 
    p = a;//초기화//p라는 포인터가 a를 가르킴
 
    for ( i = 0; i < 2; i++)
    {
        for ( j = 0; j < 3; j++)
        {
            cout << a[i][j] << "\t" << p[i][j] << "\n";
            cout << *(a[i]+j)<<"\t" << *(p[i] + j) << "\n";
            cout << *(*(a + i) + j) << "\t" << *(*(p + i) + j) << "\n";
        }
        cout << endl;
 
    }
}
 
cs

 

 

* 다차원포인터를 이용한 성적프로그램(동적할당ver)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include<iostream>
using namespace std;
 
//함수 프로토타입 선언
void input(char(*name)[10], int(*sco)[4], int num);
void ex(int(*sco)[4], float *avg, int num);
void output(char(*name)[10], int(*sco)[4], float *avg, int num);
 
void main()
{
    char(*name)[10];//한 행당 10개 메모리인 배열을 가리키고 있는 name 포인터
    int(*sco)[4];//한 행당 10개 메모리인 배열을 가리키고 있는 sco 포인터
    float *avg;
    int num;
 
    cout << "몇명 입력할거야?" << endl;
    cin >> num;
 
 
    /*
    동적할당 하는 이유 
    1. 위에서 포인터를 선언 한 것이지 아직 공간을 할당 하지 않음
    2. 공간이 할당 된 것이 아니라서 배열에 동적할당으로 특정 값을 
        넣어준뒤 포인터와 시작주소를 연결할 수 있음.
    3. 시작주소를 잡으면 일일히 한 행당 10개씩의 메모리를 계산해서
        연산, 출력 하지 않아도 됨.
    */
 
    name = new char[num][10];//한사람당 10글자
    //동적할당을 통해 name의 시작주소를 한 행당 10개 메모리로 잡음
    sco = new int[num][4];//한사람당 국어,영어,수학,합계
    //동적할당을 통해 sco의 시작주소를 한 행당 4개 메모리로 잡음
    avg = new float[num];//한사람당 평균
 
    //주소 보내기
    input(name, sco, num);
    ex(sco, avg, num);
    output(name, sco, avg, num);
 

 

    delete[]name;
    delete[]sco;
    delete[]avg;
}
 
 
void input(char(*name)[10], int(*sco)[4], int num)
{//2차원 주소로 보냈으니 2차원 포인터로 받아야 한다.
    
    int i, j;
 
    for (i = 0; i<num; i++)
    {
        cout << "이름 입력:";
        cin >> name[i]; // *(name+i)
        //10개의 메모리를 잡고 있는 한 행씩 움직인다
 
        cout << "성적 입력:" << endl;
        for (j = 0; j<3; j++)
        {
            cin >> sco[i][j];
            // *(sco[i]+j),*(*(sco+i)+j)
            //4개의 메모리를 잡고 있는 한 행씩 움직인다
        }
 
    }
}
 
 
void ex(int(*sco)[4], float *avg, int num)
{
    int i, j;
    for (i = 0; i<num; i++)
    {
        sco[i][3= 0;
        //쓰레기값 처리. 한칸을 무조건 비워두면 안됨
 
        for (j = 0; j<3; j++)
        {
            sco[i][3+= sco[i][j];
        }
        avg[i] = sco[i][3/ 3.f;
    }
}
 
void output(char(*name)[10], int(*sco)[4], float *avg, int num)
{
    int i, j;
 
    //system("cls");
    for (i = 0; i<num; i++)
    {
        cout << "----------------------" << endl;
        cout << name[i] << endl;
        for (j = 0; j<4; j++)
        {
            cout << sco[i][j] << endl;
        }
        cout << avg[i] << endl;
    }
}
 
 
 
cs

 

 

* 메모리 할당 해제 하는 이유

1. 메모리 할당을 하고 난뒤 모든 기능을 수행하고 나면 남은 메모리들이 처치 곤란이 된다.

2. 좀비 메모리가 남으면 다른 프로그램을 실행할때 좀비 메모리가 그대로 축적되게 됨으로 메모리 공간이 줄어들게 된다.

3. 즉, 메모리 공간 낭비를 방지하기 위해 메모리 할당을 해제한다.

반응형
댓글
공지사항