이 시점에서는 컴규조에 대한 약간의 강의가 필요할 듯 싶습니다..
저도 포인터가 명확히 잡히지 않았을 무렵.. 컴퓨터 구조론을 듣게 되었지요.
그런 후에 CPU에서 주소지정할 떄, direct 방식과 indirect방식등.. 여러가지 주소 지정 방식에 대한 교수님의 강의를 듣는 와중에 C의 포인터도 이런거구나 하는 걸 깨달았죠.. ~_~
pointer를,
그냥 한두번 설명해서 이해 못하는 사람에게
이해시키기란,
정말... 하늘의 별따기 입니다.
차라리,
(그런 사람이라는 생각이라고 생각되는 사람이라면)
pointer 빼고, 나머지를 다 가르쳐 주고, 프로그램도 만들게 하고, 자바에 C에 어셈에 펄에 운영체제에 드라이버에 뭐에 뭐를 다 가르쳐 주고,
문서작업도 시키고, 설계도 시키고, 포팅도 시키고, 별의 별 일도 다 시키고,
한... 5년 지나서, 그사람이 나름 괜찮은 엔지니어가 되었다 싶을 때에
'근데... pointer라는게 있는데....'
이렇게 접근하시는 것이 어떨찌....
저번 학기에 학교 리포트로 C로 subtring을 만들었었는데요.
처음엔 주어진 문자 배열을 for 문으로 간단히 자르는 것 부터 시작했었습니다.
그러다가 원본을 둔 채 자른 문자열만 리턴 할려니 그게 생각대로 잘 안되더군요.
그래서 결국 몇 단계를 더 거쳐서 malloc()까지 가게 됐던 기억이 나네요.
이렇게 단계를 거치면서 포인터와 메모리 할당에 대한 이해가 커졌습니다~
포인터는 포인터 의미 그대로 가르쳐야 한다고 생각합니다.
괜히 다른 예를 들어서 가르쳐 봤자, 그 다른 예의 개념이랑 헷갈려서 혼돈만 가중시키는 것 같은...
배열을 통해 가르치는 경우도, 만약 c++을 배워야 한다면 c++ 언어 자체가 워낙 모호한 언어라,
[] 연산자 오버로딩 때문에, 머리 속이 많이 복잡해 질 것 같네요...
첫째는 단일 객체의 별칭으로, 두번째는 배열이라는 컬렉션을 횡단하는 대리자로 말이죠. 만일 포인터를 어셈블리 수준에서 이해하고자 한다면 그 둘의 의미차를 없앨 수 있죠. 그래서 포인터를 이해할려면 어셈블리를 이해해야 한다는 말이 나옵니다. 이 경우의 문제점은 C 표준입장에서는 정의되지 않은 행동을 떠올릴 수 있는 수준에서 이해한다는 것이죠.
하지만 저같은 경우는 C++의 STL 반복자를 통해 포인터의 배열횡단대리자의 의미를 이해했습니다. 이 경우 두가지 의미를 분리해서 이해해야 하는데 C 포인터를 표현할 때는 동일한 표현기법이 나와서 헷갈릴 수 있다는게 문제죠.
C 언어의 역사를 생각할 때 어셈블리 수준에서 이해하는게 맞기는 한 거 같습니다. C를 창시했던 분들은 다들 어셈블리를 잘 하셨겠죠.
구체적으로 사람들이 어려워하는 부분을 따져보면
포인터라기보다는 다른 문제인 경우가 많습니다.
초보때는 포인터가 어려워서라기 보다는
한꺼번에 생소한 지식이 많이 쏟아져 들어오다보니까
질리는 타이밍에 때마침 포인터를 배워서 인 경우가 허다하죠.
그들은 포인터를 모르지만 사실 변수도 잘 모릅니다.
구조체도 모르고 함수도 모르죠.
그냥 그만둘 타이밍에 포인터를 배웠을 뿐입니다.
학기에 비유하면 중간고사 마치고 수강철회 할무렵? ㅋㅋㅋ
중수때는 포인터의 개념을 몰라서라기 보다는
그저 문법적인 문제에 대해 공부가 얕아서인 경우가 허다합니다.
복잡한 선언의 해석이라던가
복잡한 수식 내부에서 데이터 타입이 변화해 나가는 흐름이라던가.
이제 좀 익숙해졌다 싶은 단계에서는
보통 하드웨어 구조와 관련된 문제에서
많이 난관을 겪죠.
대표적인 걸로 memory alignment이나 구조체 패딩 같은거.
그리고 이때의 문제점이라면 너무 자신감이 넘쳐서
잘 새로운 지식을 받아들이려 하질 않습니다.
이식성 관련한 문제는 그래서 얘기하기가 무척 까다롭죠.
그런 문제를 접하는 사람은 대개 전문가 급인데
자기가 문제없이 써오던 코드가 틀렸다고 하면
당연히 받아들이려 하질 않죠.
제가 보기에는, 한 카테고리로 묶일 문제가 아닌데
포인터로 한꺼번에 묶어서 말하는 경향이 있는듯 싶습니다.
그리고 그 덕분에 필요 이상으로 포인터의 어려움에 대한 뻥과 과장이 심해지고
점차 프로그래밍 계의 도시전설로 발전해 나가는 느낌입니다.
gardner님 말씀대로 포인터를 모른다기보다, 다른 것들도 모르는 상황에서 포인터까지 배우려고 하니 어려워하는 것인듯 합니다.
보통 사람들이 포인터를 완전히 이해했다, 고 말하는 상황이면
컴퓨터 구조를 이해하여 메모리와 CPU의 관계를 완전히 이해한 후 이더군요.
관점을 바꿔서 생각하면, 컴퓨터를 배우는 방법은 두가지인거 같습니다.
컴퓨터의 관점에서 사람쪽으로 접근하는가.
사람의 관점에서 컴퓨터쪽으로 접근하는가.
실력이 늘면 늘수록, 컴퓨터 관점에서 사람쪽으로 접근하는 쪽을 선호하게 되는거 같습니다. 그게 간결하니까요. 애매하지 않다고 해야하나.
그럴거면 논리회로부터 시작하여 래치 & 플립플롭 배우고, 컴퓨터 구조 배우고, 기계어 배우고, 어셈블리 배우고, 그리고 C언어를 배우는게 맞습니다.
그런데 이렇게 배우면 프로그래밍을 못하니까 재미가 없습니다.
그래서 중간쯤 되는 C언어를 배우고, C언어에서부터 컴퓨터로, C언어에서부터 사람으로 배워들어가는 것 같습니다.
이런 관점에서 보면, 배열을 배우고, 배열 내부에서 Index값 이용하는걸 배운 뒤 포인터를 가르치는것도 좋다고 봅니다.
어떻게 생각하면 엑셀이야말로 컴퓨터를 이해하기 가장 좋은 방법인거 같기도 합니다.
셀 하나하나가 메모리, =C4+C6 등으로 지칭하는건 포인터, 셀에 데이터도 기록하면서 sum, avg등을 이용하는 부분을 소스코드, 데이터를 넣은 네모난 영역을 배열, 배열을 넘어 데이터를 추가해서 sum 함수등이 고려하지 못하는 것을 memory leak 등으로.
얼마전에 은행에 입사하신 선배님이 있는데, 갑작스레 C를 배워야 하는 경우가 생겼습니다. 그때 스스로 저런식으로 컴퓨터를 이해하더군요.
링크드 리스트나
링크드 리스트나 트리 같은 ADT를 설명하는 시점이 되면 먹히지 않을 것 같은데요. implicit array를 사용하기 어려운 경우도 많으니까요.
http://kldp.org/node/31840
이런 설명이 필요할 시점도 오겠죠.
예전에 Homological
예전에 Homological Algebra 공부하다가 거기에 나온 Homomorphism과 집합의 원소의 관계가 C언어의 포인터와 변수가 갖는 관계와 같은걸 발견한 적이 있습니다.
물론... Homological Algebra를 공부하는게 C보다 더 어렵겠지만...말이죠 -_-
-----------------------
snowall의 블로그입니다.
http://snowall.tistory.com
피할 수 있을때 즐겨라! http://melotopia.net/b
제가 예전에 썼던
제가 예전에 썼던 글과 같은 관점(?)도 있습니다.
http://kldp.org/node/98933#comment-461949
-----
오늘 나의 취미는 끝없는, 끝없는 인내다. 1973 法頂
-----
오늘 나의 취미는 끝없는, 끝없는 인내다. 1973 法頂
음.....
이 시점에서는 컴규조에 대한 약간의 강의가 필요할 듯 싶습니다..
저도 포인터가 명확히 잡히지 않았을 무렵.. 컴퓨터 구조론을 듣게 되었지요.
그런 후에 CPU에서 주소지정할 떄, direct 방식과 indirect방식등.. 여러가지 주소 지정 방식에 대한 교수님의 강의를 듣는 와중에 C의 포인터도 이런거구나 하는 걸 깨달았죠.. ~_~
Case by Case, Man to Man 인 것 같습니다.
같은 학과에 온다고 해도 생각하는 방식은 다들 다른 것 같아요. 결국 이해를 돕기 위한 방법이란 은유(metaphor)인데 적절한 은유는 그 사람이 이전에 어떤 경험을 했냐는 거에서 나오거든요.
어차피 결론은 메모리
배열이나 포인터나 메모리 구조 칠판에 쓱 그려주고
설명하면 끝인듯
어려운 얘기입니다.
pointer를,
그냥 한두번 설명해서 이해 못하는 사람에게
이해시키기란,
정말... 하늘의 별따기 입니다.
차라리,
(그런 사람이라는 생각이라고 생각되는 사람이라면)
pointer 빼고, 나머지를 다 가르쳐 주고, 프로그램도 만들게 하고, 자바에 C에 어셈에 펄에 운영체제에 드라이버에 뭐에 뭐를 다 가르쳐 주고,
문서작업도 시키고, 설계도 시키고, 포팅도 시키고, 별의 별 일도 다 시키고,
한... 5년 지나서, 그사람이 나름 괜찮은 엔지니어가 되었다 싶을 때에
'근데... pointer라는게 있는데....'
이렇게 접근하시는 것이 어떨찌....
포인터를 모를
포인터를 모른다면 어셈부터 막힐 겁니다.
자료형과 수식으로 이해시키면 될것 같습니다.
자료형과 수식의 개념이 있다면 정의를 통해서 이해시키면 될것 같습니다.
포인터 자료형이란 무엇이다. 이것은 어떻게 정의된다. 그리고 수식에서는 어떻게 사용한다.
이정도면 되지 않을까 생각합니다.
..............
옛날에 별표를 앞에 붙여야 되냐.. 뒤에 붙여야 되냐. 이런것도 있었죠..
저는 앞에 붙이는게.. 좀더 이해하기 좋았습니다..
1. int* a;
2. int *a;
============================================================
선한 인간이냐 악한 인간이냐는 그사람의 의지에 달렸다. -에픽테토스-
의지 노력 기다림은 성공의 주춧돌이다. -파스퇴르-
============================================================
============================================================
선한 인간이냐 악한 인간이냐는 그사람의 의지에 달렸다. -에픽테토스-
의지 노력 기다림은 성공의 주춧돌이다. -파스퇴르-
============================================================
저는 포인터를
저는 포인터를 이해하는 데 가장 좋은 방법은 strcpy, strcat, strcmp 를 직접 구현해 보는것이 가장 좋다라고 생각합니다.
substring은 어떨까요?
저번 학기에 학교 리포트로 C로 subtring을 만들었었는데요.
처음엔 주어진 문자 배열을 for 문으로 간단히 자르는 것 부터 시작했었습니다.
그러다가 원본을 둔 채 자른 문자열만 리턴 할려니 그게 생각대로 잘 안되더군요.
그래서 결국 몇 단계를 더 거쳐서 malloc()까지 가게 됐던 기억이 나네요.
이렇게 단계를 거치면서 포인터와 메모리 할당에 대한 이해가 커졌습니다~
포인터는...
포인터는 포인터 의미 그대로 가르쳐야 한다고 생각합니다.
괜히 다른 예를 들어서 가르쳐 봤자, 그 다른 예의 개념이랑 헷갈려서 혼돈만 가중시키는 것 같은...
배열을 통해 가르치는 경우도, 만약 c++을 배워야 한다면 c++ 언어 자체가 워낙 모호한 언어라,
[] 연산자 오버로딩 때문에, 머리 속이 많이 복잡해 질 것 같네요...
_________________________________________________________
nineye's blog
전 포인터를 생각할 때
전 포인터를 생각할 때 핫케이크를 생각했습니다. 커다란 핫케잌이 있고, 그 위에 시럽이 있잖아요.
시럽은 맛만보고 사라지는 value고, 실체는 reference 가능한 빵덩어리다 :) 이런 어렵군요 -_-
저는 반대로
저는 반대로 생각합니다.
포인터를 먼저 확실히 숙지시킨 후에 배열을 포인터로 설명해야 한다고 생각합니다.
Teach Yourself C++의 저자와 같은 생각인데요
이유는 [] 연산자는 주소값 개념이 확실히 자리잡은 다음에 배워야 한다고 생각하기 때문입니다.
포인터* 와 덧셈+ 만 알면 배열 []은 아는 범위에서의 확장으로 설명이 가능한 잇점도 있구요.
a[b] == b[a] == *(a+b)
.
그리고 백문이 불여일견이라고,
경험상 포인터를 설명하는데 가장 좋은방법은..
디버거로 포인터가 저장된곳과 가리키는 곳을 보여주면서
*a = 3;
a = 3;
과 같은 간단한 코드를 한줄한줄 실행시키며
디버거로 해당부분의 메모리 view를 띄워 확실히 보여주는게 제일 효과가 좋았습니다.
흠... 포인터가 어려운 것은 두가지 의미로 쓰이기 때문입니다.
첫째는 단일 객체의 별칭으로, 두번째는 배열이라는 컬렉션을 횡단하는 대리자로 말이죠. 만일 포인터를 어셈블리 수준에서 이해하고자 한다면 그 둘의 의미차를 없앨 수 있죠. 그래서 포인터를 이해할려면 어셈블리를 이해해야 한다는 말이 나옵니다. 이 경우의 문제점은 C 표준입장에서는 정의되지 않은 행동을 떠올릴 수 있는 수준에서 이해한다는 것이죠.
하지만 저같은 경우는 C++의 STL 반복자를 통해 포인터의 배열횡단대리자의 의미를 이해했습니다. 이 경우 두가지 의미를 분리해서 이해해야 하는데 C 포인터를 표현할 때는 동일한 표현기법이 나와서 헷갈릴 수 있다는게 문제죠.
C 언어의 역사를 생각할 때 어셈블리 수준에서 이해하는게 맞기는 한 거 같습니다. C를 창시했던 분들은 다들 어셈블리를 잘 하셨겠죠.
이거 좋은
이거 좋은 지적입니다.
저도 iterator라는걸 접하고는 늘상 써오던 a[i]나 *p++가 아 이렇게 따로 추상화가 되는구나 하고 문화적 충격을 느꼈습니다.
로우레벨 좋아하시는 분들 많은데, 이런 경우 오히려 지나치게 로우레벨한 접근이 전체적인 관점으로 보는걸 방해하는게 아닌가 싶습니다.
..
메모리에 저장된 구조체의 모양을 하나 그려주고 거기에서 포인터엑세스나 헥스 덤프등을 해보는 것은 어떨까요? 너무 쉬워보이긴 하지만 윗분 말씀처럼 링크드 리스트 정도 되는 것으로 샘플을 올리면 꽤 도움이 될 것 같습니다.
A rose is a rose is a rose..
제 생각에는...
제 생각에는 포인터를 손짓으로 이해하면 될 듯 합니다.
"저 케잌(struct Cake)을 아이의 입에 갖다 댈 것인가.. 아니면 케잌에다 먹으라고 손짓(struct Cake *)을 할 것인가.."
이렇게 하면 이해하기 쉬우리라 생각도 될 것 같은데요.;;
학교다니는 10년동안
학교다니는 10년동안 늘 신입생에게 가르친 경험을 삼아서 말씀드리면, 안가르치는게 답이라는 겁니다.
20명 중에 한명 이해할까말까... 그나마 이해하는 녀석은 컴퓨터에 대해서 나름 알고 있던 녀석들이라는 거죠.
그냥 함수형언어 가르쳐주는게 포인터 설명안해도 되고 가장 좋았습니다.
------------------------------
How many legs does a dog have?
------------------------------
How many legs does a dog have?
포인터가 어렵다 어렵다 하는데
구체적으로 사람들이 어려워하는 부분을 따져보면
포인터라기보다는 다른 문제인 경우가 많습니다.
초보때는 포인터가 어려워서라기 보다는
한꺼번에 생소한 지식이 많이 쏟아져 들어오다보니까
질리는 타이밍에 때마침 포인터를 배워서 인 경우가 허다하죠.
그들은 포인터를 모르지만 사실 변수도 잘 모릅니다.
구조체도 모르고 함수도 모르죠.
그냥 그만둘 타이밍에 포인터를 배웠을 뿐입니다.
학기에 비유하면 중간고사 마치고 수강철회 할무렵? ㅋㅋㅋ
중수때는 포인터의 개념을 몰라서라기 보다는
그저 문법적인 문제에 대해 공부가 얕아서인 경우가 허다합니다.
복잡한 선언의 해석이라던가
복잡한 수식 내부에서 데이터 타입이 변화해 나가는 흐름이라던가.
이제 좀 익숙해졌다 싶은 단계에서는
보통 하드웨어 구조와 관련된 문제에서
많이 난관을 겪죠.
대표적인 걸로 memory alignment이나 구조체 패딩 같은거.
그리고 이때의 문제점이라면 너무 자신감이 넘쳐서
잘 새로운 지식을 받아들이려 하질 않습니다.
이식성 관련한 문제는 그래서 얘기하기가 무척 까다롭죠.
그런 문제를 접하는 사람은 대개 전문가 급인데
자기가 문제없이 써오던 코드가 틀렸다고 하면
당연히 받아들이려 하질 않죠.
제가 보기에는, 한 카테고리로 묶일 문제가 아닌데
포인터로 한꺼번에 묶어서 말하는 경향이 있는듯 싶습니다.
그리고 그 덕분에 필요 이상으로 포인터의 어려움에 대한 뻥과 과장이 심해지고
점차 프로그래밍 계의 도시전설로 발전해 나가는 느낌입니다.
gardner님 말씀대로
gardner님 말씀대로 포인터를 모른다기보다, 다른 것들도 모르는 상황에서 포인터까지 배우려고 하니 어려워하는 것인듯 합니다.
보통 사람들이 포인터를 완전히 이해했다, 고 말하는 상황이면
컴퓨터 구조를 이해하여 메모리와 CPU의 관계를 완전히 이해한 후 이더군요.
관점을 바꿔서 생각하면, 컴퓨터를 배우는 방법은 두가지인거 같습니다.
컴퓨터의 관점에서 사람쪽으로 접근하는가.
사람의 관점에서 컴퓨터쪽으로 접근하는가.
실력이 늘면 늘수록, 컴퓨터 관점에서 사람쪽으로 접근하는 쪽을 선호하게 되는거 같습니다. 그게 간결하니까요. 애매하지 않다고 해야하나.
그럴거면 논리회로부터 시작하여 래치 & 플립플롭 배우고, 컴퓨터 구조 배우고, 기계어 배우고, 어셈블리 배우고, 그리고 C언어를 배우는게 맞습니다.
그런데 이렇게 배우면 프로그래밍을 못하니까 재미가 없습니다.
그래서 중간쯤 되는 C언어를 배우고, C언어에서부터 컴퓨터로, C언어에서부터 사람으로 배워들어가는 것 같습니다.
이런 관점에서 보면, 배열을 배우고, 배열 내부에서 Index값 이용하는걸 배운 뒤 포인터를 가르치는것도 좋다고 봅니다.
좀 엉뚱한
좀 엉뚱한 이야기인데, 엑셀로 포인터를 이해한 경우도 있습니다.
어떻게 생각하면 엑셀이야말로 컴퓨터를 이해하기 가장 좋은 방법인거 같기도 합니다.
셀 하나하나가 메모리, =C4+C6 등으로 지칭하는건 포인터, 셀에 데이터도 기록하면서 sum, avg등을 이용하는 부분을 소스코드, 데이터를 넣은 네모난 영역을 배열, 배열을 넘어 데이터를 추가해서 sum 함수등이 고려하지 못하는 것을 memory leak 등으로.
얼마전에 은행에 입사하신 선배님이 있는데, 갑작스레 C를 배워야 하는 경우가 생겼습니다. 그때 스스로 저런식으로 컴퓨터를 이해하더군요.
저는 C++ 반복자 먼저
저는 C++ 반복자 먼저 이해하고 나서 포인터를 이해했습니다. 그 뒤로는 명확해져서 혼동하지 않습니다.
—홍민희 (VLAAH, LangDev)