:: 다차원 배열 ::


다차원 배열이란? 2차원 이상의 배열을 의미한다.

즉,2,3차원을 주로 사용한다. (4차원은 이해하기 까다로워 다루지 않는다)


ex) 2차원 배열의 선언


int array1[2][5]; // 세로가2, 가로가5인 int형 2차원 배열을 의미한다,

위에서 선언된 배열의 인덱스값은 아래와 같다.


1행 1열 [0][0]

1행  2열 [0][1]

 1행 3열 [0][2]

 1행 4열 [0][3]

 1행 5열 [0][4]

2행 1열 [1][0]

2행  2열 [1][1]

 2행 3열 [1][2]

 2행 4열 [1][3]

 2행 5열 [1][4]



그리고 이들의 할당된 메모리 형태는 아래와 같다.


 0x1000

 0x1004

 0x1008

 0x100C

 0x1010

 0x1014

 0x1018 0x101C

 0x10020

 0x1024


0x1014에서 0x0014의 의미: 16^1*1 + 16^0*4 = 16+4=20


이를 통하여 알수있는 사실은, 2차원 배열도 메모리상에서는 1차원 배열의 형태로 존재한다는 사실이다.


2차원 배열의 선언과 동시에 초기화는 아래와 같다.

int arr[2][2] = { {1,2}, {3,4} };     =   int arr[2][2] = {1,2,3,4}; //동일하다. 

1,2

3,4

의 형태로 선언된 2x2 행렬의 형태로 선언과 동시에 초기화 되었다.


만약 행과 열에 정의하지않는 요소가 존재한다면, "0"으로 채워진다. 배열과 동일하다.


:: 포인터의 포인터 ::


의미 : 포인터변수를 가리키는 또다른 포인터 변수를 말하며 흔히 '이중 포인터' or '더블 포인터'라 한다.


정의 :  int ** ptr; //int 형 이중 포인터 변수 ptr 선언


앞서 설명한 포인터의 개념과 별반 다를게 없는 개념이다.

포인터 변수는 주소값만을 저장하는 변수이고, 포인터 변수또한 가리키는 포인터변수의 주소값을 저장하는 변수이다.

예를들면, 중요한 문서의 이중봉투라고 볼수가 있겠다.

int main(void)

{


int number =1;

int *ptr = &number;

int **doptr = &ptr;


}

이들 변수들이 가리키는 참조관계는 아래와 같다.

doptr -> ptr -> number =1;


*doptr은 포인터변수 ptr을 의미한다.

**doptr 또는 *(*doptr) 은 변수 number을 의미한다.


따라서, 포인터변수들의 값을 Swap하는 함수의 형태는 아래와 같아야 한다.


void Swapfunction(int **dptr1, int **dptr2)

{

int *temp = *dptr1;

*dptr1 = *dptr2;

*dptr2 = temp;


}

어떤 객체의 값을 바꿔야 되는가에 대해서, 명확하게 생각해야만 실수가 없을 것이다.

그리고 사실 삼중포인터도 존재한다. int ***tpointer; 



:: 다차원 배열과 포인터와의 관계 ::


앞장 포인터 사용하기-1에서 배열이름과 포인터와의 관계에서 가장 주요하게 언급한것이 바로

배열 이름이 해당되느 자료형 포인터이므로 


예시)

int arr[2]; //int형 포인터 arr을 선언 = 배열 arr을 선언

prinft("&p", arr+1); 


여기서  출력되는 값은 arr+sizeof(int)의 값이 출력된다. 왜냐하면, 포인터형은 포인터를 대상으로 하는 가감산연산의 결과


에서 크기를 결정하기 때문이다. 즉, 포인터형이 같다면 증가 감소의 크기값도 동일 할것이다.


하지만 다차원 배열에서는 이것만을 고려해서는 안된다.


2차원 배열이름의 포인터형은 가로의 길이에 따라서 포인터의 크기가 달라지기 때문이다.


즉, 몇개의 열을 가지고 있는가에 따라서 "다차원 배열이름"+1 = 가진 열의 수만큼 행이 하나더 생성 되기때문이다.


따라서 이 문제가 다차원 배열이름의 포인터 형 결정을 어렵게 만드는 요인이다. 


int * ExA[3];  //포인터 배열,  int형 포인터 변수로 이루어진 배열을 선언한 것.

int (*ExB)[3]; //배열 포인터, 가로길이가 3인 2차원배열을 가르키는 포인터 변수를 선언한 것.


:: 함수 포인터와 void 포인터 ::


함수 포인터 : 메모리상에 저장된 함수의 주소 값을 저장하는 포인터 변수를 의미한다.  함수도 변수처럼 메모리 공간에 저장되어서 호출시 실행되기 때문이다.


형태 :  반환형 - 포인터변수이름 - 매개변수 (즉, 반환형과 매개변수가 포함된것이 포인터 형이다)


ex) int (*simplePtr) (int);


위의 예제는 함수포인터를 선언한 형태이다. 각각의 해체해보면,

int : 반환형이 int인 함수 포인터

*simplePtr : simplePtr 은 포인터

(int) : 매개변수 선언이 int 하나인 함수 포인터


그럼 예제를 확장시켜서, 실제 함수가 존재하고 이 함수의 주소값을 저장할수있는 함수포인터를 선언해보자.


int functionA(int num1, int num2)

{

생략..

}


int (*FPtr) (int, int);


FPtr=functionA; //함수포인터에 함수의 주소값이 저장되었다.


위의 functionA라는 함수의 주소값을 저장할수있는 함수포인터의 예제이다.

그래서 실제 사용은 아래와 같이 하면 같은 결과값이 나타난다.


FPtr(1, 2); // 이는 functionA(1, 2); 와 동일한 결과를 보인다.



만약 형타입도 없고, 매개변수도 없는 함수, 즉 Void타입을 함수 포인터로 선언할 경우는 아래와 같다.

void functionA(void)

{...}


void * ptr;  //void타입의 함수 포인터 선언.



+ Recent posts