본문 바로가기
[ CODING STUDY ]/》C언어 공부

C언어 18장_3(포인터, 다중포인터, 다차원 배열)

by MRG 2020. 5. 15.
728x90
반응형

▣ 안녕하세요^^
저번 시간에 포인터 두 번째 장 숙제 잘해보셨나요??
여러분들에 무거운 얼굴이 보이네요 ^^;;;



▣ 하지만 여러분들은 지금 이 장을 열었다는 건
완벽하게 이해하지는 못해도 
어쨌든 끝까지 포기하지 않고 하고 계시다는 이야기겠죠?
잘하시고 계십니다. 
포기하지 마세요!!!
할 수 있습니다!!!
제가 이번장에서 포인터를 끝내도 다른 부분을 진행할 때 
아니면 많이 틀리는 예제들이나 문제들을 한번 같이 공부해보는 장도 
만들겠습니다.
그러니 한 번에 이해하지 못했다고 해서 실망하지 마세요.



▣ 그리고 제가 계속 말씀드리지만,
꼭 제 블로그로만 공부를 끝내시면 안 됩니다.
모든 분들이 가르치는 방법과 노하우와 그리고 경험이 다르기 때문에
꼭 좋은 여러 강사님들 자료를 보시면서 함께 공부해주세요.
제가 틀린 게 있다면 댓글 남겨주시거나 메일 보내주셔서
피드백해주시면 더 좋습니다. 
저도 함께 공부하고 있습니다.^^
아이들을 가르치지만 코딩은 정답이 없다고 생각하시 때문에
계속 새로운 자료와 새로운 강사분들 선생님들을 보면서
공부하면 정말 많은 걸 배웁니다.
항상 그러니 여러분들도
코딩 공부 계속해주세요.



▣ 자 이제 본론으로 들어가서 포인터 3장을 진행해보겠습니다.
오늘 하는 내용도 직접 실습을 하시면서 
공부해주세요. 

 

 

▣ 자 먼저 다중 포인터를 진행하겠습니다. 
우선 위에 있는 코드를 똑같이 작성해주시고 
함께 하나하나 코딩을 해석해보겠습니다.



저번장에 했던 포인터 변수 만드는 법 기억하시죠?
혹시 이게 기억 안 난다고 하시면 저번장을 다시 복습해주세요.



포인터는 주소를 저장하는 변수라고 말씀드렸고,
그 안에 주소를 넣어서 그 넣은 주소를 따라 
우리가 값을 바꾸거나 할 수 있다고 했습니다.



▣ 그럼 코드 중에 int** pNum2가 있죠?
같은 포인터일 거 같긴 한데 이건 무엇일까요?
겁먹을 필요 없습니다. 
쉽게 생각하면 포인터에 포인터를 넣는 변수라고 생각하시면 될꺼같습니다.
밑에 그림을 한번 볼까요?

 

 

▣ 포인터 변수 안에 배열에 주소를 넣고 그 과정이 어떻게 되는지를 
그림으로 표현한 겁니다.
기억하시죠?
위에 그림을 다시 해석해보면
*pList라는 포인터 안에 &aList에 주소를 넣게 되면 aList 0번째 주소 기준가 들어간다고 말씀드렸습니다.
그래서 저 그림처럼 빨간색으로 pList가 기준 주소를 가리킨다.
그래서 *(pList+1) 값을 20으로 바꾸면 1번째 배열 주소를 따라가 그 값을 바꾼다라고 했습니다.
여기까지는 이해가 되시죠?



▣ 다시 위에 코드로 돌아가면 int**pNum2에는 
*pNum에 주소를 넣었습니다.
그럼 *pNum값 안 에는 당연히 &number에 주소가 들어있겠죠?
다시 정리하면 pNum2안에는 pNum에 주소가 들어있고 pNum값 안에는 number에 주소가 들어있습니다.
포인터 안에 포인터가 들어있다는 건
주소 안에 주소가 들어있다고 생각하시면 됩니다.
그래서 저기 위에서처럼 pNum2에 값을 확인해보면
pNum에 주소가 들어있는 걸 확인할 수 있습니다.

 

 


▣ 제가 이렇게 **pNum2에 값을 바꾸면 어떻게 될까요?
쉽게 설명하면 *은 주소라고 생각을 하고
*주소 안에 *또 주소 안을 찾아가서 그 값을 바꾸게 됩니다.
그래서 ** 포인터 안에 포인터라고 이야기를 하는 겁니다.
이게 다중 포인터입니다. 

 

▣ 다시 그림으로 설명하겠습니다.
number에 10에 값이 들어있고 
number 주소는 100번지라고 예를 들겠습니다.
*pNum는 주소가 200번지, *pNum2는 주소가 300번지라고 예를 들어보겠습니다.
위에 코드처럼 해석한다고 하면
*pNum포인터 변수 안에는 number에 주소 값 100이 들어있겠죠?
그래서 *pNum을 출력하면 그 주소를 보고 따라가 그 값을 출력하게 됩니다. 
그 값은 당연히 number겠죠?
**pNum2를 하게 되면 안에 들어있는 *별 하나 주소를 따라가고 
또 그 안에 있는 *주소를 따라가 10이라는 값을 찾아가 대입해서 100으로 바꿀 수 있게 됩니다.
아시겠죠? ^^;;



▣ 다시 이야기하지만 포인터는 변수이고 그 안에 주소 값이 들어있다.
주소가 적혀있는 종이다 라고 생각해주세요.
* 이 기호는 포인터 변수를 선언하기도 하지만 
* 그 포인터 안에 있는 주소를 찾아가는 기호라고 생각해주세요.



▣ 꼭 위에 있는 부분은 그림을 따라 그려서 이해하셔도 되고 
직접 제가 한 것처럼 코딩을 직접 해보셔서 이해할 수 있게 
breakPoint를 찍어서 디버깅으로 하나하나 메모리를 살펴보고 확인해주세요.
꼭 하셔야 합니다.

 

▣ 자 이번에는 포인터 배열을 만들어보겠습니다. 
간단하게 생각하시면 됩니다. 
int *aList 포인터를 붙어서 하면 저렇게 포인터 배열이 만들어집니다.
직접 해보셔야 합니다.



그리고 우리가 일반적으로 배열을 만들면
int aList [10]라고 한다면 

 

 

▣ 이렇게 위에 있는 코드처럼 됩니다.
하지만 둘에 차이를 모르시겠죠?
저도 이렇게 보니 차이를 모르겠네요 ^^;;
그럼 char형으로 다시 만들어보겠습니다.

 

▣ 이렇게 코드를 해보면 확실히 차이를 보실 수 있습니다.
둘 다 char형식입니다.
aList는 char형식 5개를 만들어 문자 하나하나 대입한 걸 볼 수 있고
char*pList는 3개에 char형 안에 주소들이 들어있는 걸 볼 수 있습니다.
조금 차이를 아시겠죠?

 

▣ 그럼 그 주소를 따라가면 아까
초기값을 지정해준 문자열이 들어있는 메모리를 볼 수 있습니다.
조금 어렵죠?



그럼 그림으로 설명을 해 드겠습니다. 

 

▣ aList배열은 이렇게 위에 그림처럼 
aList라는 변수를 5개 만드는데 그 자료형이 char인 것입니다. 
하지만

 

▣ char *pList는 이렇게 char*형 포인터로 char형식을 저장하는 메모리에 주소를 저장합니다.
3개에 주소는 각각
우리가 아까 초기값을 주었던 문자열 값에 기준 주소를 의미합니다.
결국 포인터 변수에는 주소 만들어있는 것입니다.
두 개에 차이를 아시겠죠?



▣ 직접 두 가지 차이를 코드를 통해서 하나하나 breakpoint로 확인하면서 
공부해주세요.

 

 

▣ 자 이번에는 2차원 배열을 포인터에 넣어보겠습니다.
그런데 위에 방법처럼 코드를 하고 디버깅을 했습니다.
그런데 오류가 나오죠?
먼저 다시 2차원배열을 살펴보겠습니다.

 

 

▣ 이렇게 3행 4열로 값을 저장을 했습니다.
그럼 주소에 개수도 총 12개가 됩니다. 
행과 형에 값이 3 x 4 이기 때문에 12개가 되겠죠?
그렇게 생각한다고 하면 *pList로 주소를 넣으려고 하면 당연히 안 되겠죠?
그럼 어떻게 해야 하느냐?
위에 1차원 배열을 만들었던 것처럼 포인터 변수가 3개이지만
각각 값을 넣을 수 있는 4개에 열에 값이 있으면 되는데
쉽게 생각하면 포인터에서도 행에 개수를 저장해주면 됩니다.

 

 

▣ 이렇게 코드를 해주면 포인터에 주소 값을 대입해서 같은 값을 가리키는 걸 알 수 있습니다.
저 코드를 해석해보면

 

 

▣ 먼저 연산자에 우선순위를 생각해봅시다. 
그럼 () [] 이 두 가지 연산자를 먼저 하겠죠?
같은 연산자일 경우 연산에 방향을 생각하시면 되는데요



▣ 그럼 () [] 이 두 가지는 왼쪽에서 오른쪽이기 때문에
먼저 () 안에 있는 연산자부터 진행합니다.
그럼 행 부분에 *pList 포인터를 변수를 만들게 되고
그다음에 []이 숫자를 하는데 char가 남아있죠. 
그럼 char자료형은 5개라는 의미가 됩니다.
1차원 배열을 만들었을 때처럼 요.
char형 5개가 있는데 그거에 개수는 *pList에 포인터 변수라고 생각하시면 될꺼같습니다.
char자료형이 5개인 배열에
개수는 (*pList)이다 라고 생각하시면 되겠네요
그래서 포인터는 5개짜리를 뒤에 표시를 해주면
포인터 변수 개수를 만들게 되는 것입니다.

 


▣ 자 다시 이렇게 확인을 해보면
char(*pList)에 aList [0][0]에 주소 값이 들어있는 걸 확인할 수 있고 
배열에 들어 있는 값도 동일한 주소를 가리키고 있다는 걸 볼 수 있습니다.



▣ 하지만 한 가지 다른 부분은 저번장에도 이야기했지만
포인터 변수는 4byte라는 점입니다.
어떤 포인터 자료형이든 4byte입니다.
32비트 일 경우이고 
64비트 일 경우에는 8byte입니다. 
이점 꼭 기억해주세요.



▣ 저 위에 있는 부분도 꼭 다른 배열을 만드셔서 
포인터 변수에 넣어주세요.
꼭 해보셔야 합니다.



▣ 자 이렇게 다중 포인터와 다중배열 포인터를 배워보았습니다.
많이 어렵죠?
네 많이 어렵습니다.
이중 삼중 포인터, 2차원 배열할 때 많이 헷갈립니다.



▣ 하지만 좀 더 쉽게 생각하면
코딩을 볼 때 어떤 걸 먼저 우선순위로 컴퓨터가 처리할지를 생각하시면 
좀 더 해석이 쉬워질 거고
포인터는 결국 주소를 저장해주는 변수다라는 이 부분을 꼭 기억해주세요.
포인 터튼 여기까지 다루겠습니다.



▣ 포인터와 배열에 활용은 제가 장을 진행하면서
계속 다루도록 하겠습니다.
어떻게 사용하는지
어떨 때 사용하는지를 함께 공부 해나 가야면 좋겠습니다.



▣ 꼭 위에 있는 실습들은 모두 다 꼭 해주세요.
breakpoint로 디버깅하셔서 어떻게 메모리에 저장되는지 직접 눈으로 확인하면서 
진행해주세요.
그래야 이해가 더 빠릅니다.
꼭 하셔야 합니다.
질문 있으시면 댓글 남겨주시고요.
그럼 다음장에서 뵙겠습니다.



▣ 포기하지 마세요!!! 저도 했습니다!!! 파이팅!!!

728x90
반응형

댓글