포인터에 대한 좋은 설명은 무엇입니까? [닫은] 한 번했던 것처럼).

자신의 연구에서 (자신의 수업 또는 수업에 대한) 마지막으로 실제로 포인터를 이해했을 때 “ah ha”순간이 있었습니까? 특히 효과적인 초보자 프로그래머에 대한 설명이 있습니까?

예를 들어, 초보자가 C에서 처음 포인터를 만나면 컴파일 할 때까지 &s와 *s를 추가 할 수 있습니다 (내가 한 번했던 것처럼). 어쩌면 그것은 당신이나 당신의 학생을 위해 포인터를 “클릭”하게 만든 그림 또는 정말 동기가 좋은 예일 것입니다. 그게 뭐 였고, 그 전에 효과가 없었던 것 전에 무엇을 시도 했습니까? 주제 전제 조건 (예 : 구조체 또는 배열)이 있습니까?

즉,의 의미를 이해할 필요가 무엇 이었습니까 &들과 *안심을 사용할 수있을 때,? 구문과 용어 또는 사용 사례를 배우는 것만으로는 충분하지 않습니다. 어떤 시점에서는 아이디어를 내재화해야합니다.


업데이트 : 나는 지금까지 답변을 정말로 좋아합니다. 계속 오세요 여기에는 훌륭한 관점이 많이 있지만 개념을 내면화 한 후에 는 많은 사람들이 스스로 설명하고 슬로건이라고 생각 합니다. 나는 그것이 당신에게 떠오른 자세한 상황과 상황을 찾고 있습니다.

예를 들면 다음과 같습니다.

나는 C에서 문법적으로 포인터를 약간 이해했다. 나는 두 친구가 다른 친구에게 포인터를 설명하는 것을 들었다 struct. 첫 번째 친구는 ​​어떻게 참조하고 수정해야하는지에 대해 이야기했지만 다른 친구가 “더 효율적입니다”라는 짧은 친구의 의견이었습니다. 16 바이트 대신 4 바이트를 전달하는 것이 내가 마지막으로 필요로 한 개념적 전환이었습니다.



답변

그리드로서의 메모리 다이어그램

일반적으로 내가하는 일은 메모리를 “그리드”로 나타내므로 주소를 구성하고 다른 메모리 공간을 강조 표시하며 셀 값 (또는 그 이진 표현)을 쓰고 메모리의 포인터를 값에 연결할 수 있습니다 가리킨다. (그리고 여전히 단순화라고 언급하십시오).

일반적으로 대부분의 학생들에게 “오”순간입니다.

심볼 저글링

그런 다음 & 및 * 사용법을 잊어 버릴 때 매우 간단합니다. 수학이나 물리 계산과 같은 방식으로 제시하십시오. 거리를 km 단위로 시간 단위로 나누면 km / h 단위의 속도를 얻습니다. 안에있는 것은 밖에 있어야합니다. 단순한.

구조에 printf

이것으로 당신이 설명한 것을 시각적으로 나타내는 몇 가지 기본 예제를 수행하면 그들이 이해한다고 생각하는 것을 위로하거나 “아, 나는 이것을 얻지 못한다”고 말할 기회를줍니다.

광범위하다

간단한 유형에 대한 포인터를 다루고 주소 지정과 데이터 유형의 크기, 구조체, 배열 및 여러 수준의 차이점을 이해해야합니다.

그런 다음 포인터 산술을 시작하십시오.


부록 : 재귀

나는 일반적으로 시각적 표현을 사용하여 재귀를 비슷하게 설명합니다. 한 문자를 쓰는 미리 만들어진 함수를 사용하여 알파벳을 인쇄 한 다음 두 줄만 바꾸면 역순으로 인쇄하도록 요청하십시오.

보통 “무엇이 …?” 숫자 값을 인쇄하고 단계를 들여 쓰기 위해 printf에 다른 매개 변수 만 추가하면 안심할 수 있습니다.


대안 : Play-Doh 모델과 워터 컵

저는 실제로 대학에 동료들과 함께 플레이도 페이스트를 사용하여 포인터와 메모리 액세스를 설명하는 비디오를 보여주었습니다. 프로그래밍을 이해하는 데 관심이있는 아주 어린 학습자들을 제외하고는 그 기법을 실제로 사용하지는 않았지만 (정말 포인터를 너무 일찍 사용하여 언어로 이끌지 않을 것입니다) 정말 놀랍고 똑똑했습니다. 기본적으로 메모리 공간을 나타내는 다른 더 큰 play-doh 볼에 부착 할 수있는 작은 play-doh 볼을 사용하고 서로 결합하여 (링크 된 데이터 구조와 같이) 서로 연결하거나 (연속 된 것처럼) 병합 할 수 있습니다 메모리 공간). 가리키는 메모리 공간에 다른 색상을 사용하면 포인터도 도움이됩니다. 하지만 여전히 그리드로서의 메모리가 더 잘 작동한다고 생각합니다. “map / grid”에서와 같이 포인팅이 실제로 “주소 지정”의 문제임을 분명히 알 수 있습니다. Play-doh 모드는 여전히 메모리에서 사물이 서로 “접촉”한다고 생각하는 데 혼란을 겪습니다.

Water Cup은 동료가 직접 사용했지만 그녀가 그것을 생각해 냈는지 모르겠습니다. 흥미로운 접근 방식 이었지만 많은 학생들이 설명에 의지하는 것을 보았습니다. DevSolo의 커피 컵 기술과 비슷한 것 . 그러나 학생들이 컨테이너, 데이터 구조, 포인터 및 배열을 혼동하게 만들면 실제로 오해의 소지가 있다고 생각합니다. 필자가 처음에 배열을 설명하는 흥미로운 접근법 일지 모르지만 아주 오래 가지 않을 것입니다.


답변

내가 한 번보다 더 현명한 사람 :

우 Jincang 수녀는 여섯 번째 Patriach Huineng에게 물었다. “나는 Mahaparinirvana 경전을 수년 동안 연구 해 왔지만, 아직 이해하지 못하는 분야가 많이 있습니다. 제발 밝히십시오.”

patriach는 “나는 문맹입니다. 저에게 문자를 읽어주세요. 아마도 그 의미를 설명 할 수있을 것입니다.”라고 대답했습니다.

수녀는“캐릭터조차 인식 할 수 없습니다. 그러면 어떻게 그 의미를 이해할 수 있습니까?”라고 말했습니다.

“진실은 단어와 관련이 없습니다. 진실은 하늘의 밝은 달에 비유 될 수 있습니다.이 경우 단어는 손가락에 비유 될 수 있습니다. 손가락은 달의 위치를 ​​가리킬 수 있습니다. 그러나 손가락은 달을보기 위해서는 손가락 너머로 응시해야합니까? “


답변

다이어그램이 매우 유용하다는 것을 알았습니다. 예:

이런 종류의 다이어그램은 포인터가 자신의 변수 였지만 다른 객체, 즉 배열이나 문자열의 위치 인 값을 포함하고 있음을 알 수있었습니다. 또한 연필로 할 때 종이나 칠판 / 화이트 보드에서 프로그램을 추적하는 데 사용할 수 있습니다.


답변

포인터에 대해 처음 “학습”했을 때, 나는 그것에 대해 약간의 추력을 가졌습니다. 내 대학은 Java를 중심으로 커리큘럼을 중심으로 등록하기 전에 오랫동안 결정을 내렸으므로 데이터 구조 교수가 C에 대해 하나의 강의를하고 포인터로 XOR-List를 구현하도록 요청했을 때 무언가에 들어간 것처럼 느꼈습니다. 방법은 내 머리.

나는 그 정의를 이해했다.

포인터는 변수의 주소를 포함하는 변수입니다

그러나 나는 여전히 개념의 큰 부분을 이해하지 못했습니다. 되돌아 보면 세 가지를 중심으로 생각합니다.

  1. 메모리 위치 정확히 무엇입니까 ? (컴퓨터 조직 수업을 들지 않았을 때)

  2. 어색한 구문 (Soum … 왜 “int * ip”과 같이 정확하게 정의 되었는가? 그리고 나서 변수를 “ip”로 지칭 하는가?)

  3. 변수를 사용하는 것보다 변수의 주소를 저장하는 것이 얼마나 유익합니까?

K & R 서적을 구매하고 포인터에 대한 이해를 얻을 수있는 모든 문제를 완수하기 전까지는 그렇지 않았습니다. 컴퓨터 조직 수업 (C를 배우기 전에 필요하다고 생각)을 오랫동안 완성했다는 사실 외에도 포인터가 함수, 배열, 구조체에 사용될 수 있다는 사실과 관련이 있습니다. 단지 일반적인 변수의 주소를 저장하는 것이 아니라 유용한 일을하는 것.

그러나 나의 “aha”순간은 K & R이 간단한 포인터를 정의하는 어색한 구문을 설명하는 방식이었습니다. 나는 책을 통틀어 노트를 작성했다 (이것은 나의 이해를 돕기 위해 그 책의 포인트를 내 말로 바꾸어 놓았다).

포인터는 변수에 대한 주소를 포함하는 변수입니다. 포인터는 ‘*’연산자를 사용하여 정의되고 역 참조됩니다 (포인팅 된 메모리 위치에 저장된 값을 나타냄). 표현은 니모닉입니다.

Ex.:
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */

나는 항상 머리에 너무 기초적인 무언가가 생길 때까지 고급 포인터 개념을 완전히 파악할 수 없다고 항상 느꼈습니다. 내가 (* 내가 생각한) “* ip”를 정의한 직후에 “* ip”가 존재하지 않는 이유는 그 임무를 마치고 나에게 끝없이 귀찮게했다. 이것을 마스터하는 것은 함수 포인터와 같은 포인터와 관련된 고급 개념과 다음과 같은 더 복잡한 정의에 필수적입니다.

char (*(x())[])()

대체로 포인터 개념에는 다음이 필요하다고 생각합니다.

  1. 컴퓨터에 메모리를 배치하는 방법과 메모리에 대한 기본적인 이해

  2. 포인터가 얼마나 강력한 지에 대한 지식 (학습을 위해 배우는 또 다른 추상적 인 개념이 아닌 실제 사용).

  3. 구어 적으로 “포인터의 정의”로 알려진 상형 문자 해독

따라서 포인터에 대해 배울 때 적어도 3 개의 “aha”순간이 있어야한다고 생각합니다. 나는 여전히 학생이므로 개념을 배우는 데 여전히 (상대적으로) 신선한 사람의 관점에 감사한다고 생각합니다.


답변

포인터는 바탕 화면의 응용 프로그램 바로 가기와 비슷합니다. 바로 가기를 삭제해도 대상이 여전히 존재합니다. 바로 가기를 시작하면 대상이 시작됩니다.

나는 항상 바탕 화면에 txt 파일을 만들고 파일에 대한 두 개의 바로 가기를 작성 하여이 작업을 설명합니다. 바로 가기를 복사하고 삭제하면 사람들이 ‘참조’의 개념을 이해하는 것을 볼 수 있습니다.

그룹이 바로 가기 뒤에있는 기본 사항을 이해하면 원하는대로 포인터 설명을 시작할 수 있습니다. 그들은 아마 그것을 쉽게 이해할 것입니다.


답변

8-10 년 전에 저는 커뮤니티 칼리지에서 “C”과정을 소개했습니다. 이것은 항상 재미있는 주제였습니다. 가장 잘 작동하는 것처럼 보였고, 이것은 동료와 몇 차례 논의한 후에 커피 컵과 손을 사용하는 것이 었습니다.

커피 컵 (또는 배열의 경우 행)의 비유를 변수로 사용했습니다 (무언가를 담을 수 있음). 그런 다음 손을 사용하여 무언가를 잡을 수도 있고 집게 손가락을 펴서 커피 잔을 가리 켰습니다.

가까운 손은 널이었고, (모의 총과 같은) 내 머리를 가리키는 손가락은 매달려있는 포인터였습니다.

그런 다음 몇 가지 데모와 디버거를 통한 트립으로 대부분 클릭했습니다.


답변

“포인터를 어떻게 이해 했습니까”라는 질문을들을 때 정말 걱정이됩니다. 나는 항상 개념이 매우 단순하고 프로그래머에게 큰 힘을 제공하는 언어의 논리적 진화라고 생각했습니다.

나를 걱정하는 것은 포인터의 개념을 이해하는 것이 결코 어렵다는 것입니다. “여러분이 언제 드디어 얻었습니까?”

나는 실제로 그것을 얻습니까? 어쩌면 내가 한 적이 없는가?

어쩌면 개념이 까다로운 것으로 보이는 이유는, 아직 접하지 않은 모든 사람들에게 포인터가 너무 어렵다는 것을 계속 알려주기 때문입니다. 여기에 당신이 배울 수있는 백 가지 방법이 있습니까?

그 아이디어를 버리는 것, 물론 개인적으로 나는 좋은 다이어그램을 좋아하고 Steve Gibson은 항상 무언가를 설명하는 환상적인 일을합니다 !