나는 C 프로그래밍 초보자에게 포인터를 설명하는 데 최근에 기쁨을 느꼈으 며 다음과 같은 어려움에 부딪쳤다. 포인터를 사용하는 방법을 이미 알고 있다면 전혀 문제가되지 않을 수 있지만 다음 예제를 분명하게 살펴보십시오.
int foo = 1;
int *bar = &foo;
printf("%p\n", (void *)&foo);
printf("%i\n", *bar);
절대 초보자에게는 출력이 놀랍습니다. 2 행에서 방금 * bar를 & foo로 선언했지만 4 행에서 * bar는 실제로 & foo 대신 foo입니다!
혼란은 * 기호의 모호성에서 비롯됩니다. 2 행에서 포인터를 선언하는 데 사용됩니다. 4 행에서 포인터가 가리키는 값을 가져 오는 단항 연산자로 사용됩니다. 다른 두 가지가 맞습니까?
그러나이 "설명"은 초보자에게 전혀 도움이되지 않습니다. 미묘한 차이를 지적하여 새로운 개념을 소개합니다. 이것을 가르치는 올바른 방법이 될 수 없습니다.
Kernighan과 Ritchie는 어떻게 설명했습니까?
단항 연산자 *는 간접 또는 역 참조 연산자입니다. 포인터에 적용되면 포인터가 가리키는 객체에 액세스합니다. […]
포인터 ip의 선언은
int *ip
니모닉으로 만들어졌습니다. 그것은 표현*ip
이 정수 라고 말합니다 . 변수 선언 구문은 변수가 나타날 수있는 표현식 구문과 유사합니다 .
int *ip
"" *ip
를 반환하는 것처럼 읽을 int
까요? 그런데 왜 선언 후 과제가 그 패턴을 따르지 않습니까? 초보자가 변수를 초기화하려면 어떻게해야합니까? int *ip = 1
(읽기 : *ip
는를 반환 int
하고 int
is는 1
) 예상대로 작동하지 않습니다. 개념적 모델은 일관된 것처럼 보이지 않습니다. 여기에 뭔가 빠졌습니까?
*
선언에서 "포인터 선언"을 의미하는 토큰, 표현식에서 역 참조 연산자이며이 두 가지가 동일한 기호를 갖는 다른 일을 나타낸다 는 사실을 항상 주장했습니다. (곱셈 연산자와 동일-동일한 기호, 다른 의미). 혼란 스럽지만 실제 상황과 다른 것이 더 나빠질 것입니다.
int* bar
별이 실제로 식별자의 일부가 아닌 유형의 일부라는 것이 더 분명해집니다. 물론 이것은 당신과 같은 직관적이지 않은 것들과 다른 문제를 낳습니다 int* a, b
.
*
문맥에 따라 두 가지 다른 의미를 가질 수 있습니다. 같은 글자가 단어에 따라 다르게 발음 될 수있는 것처럼 많은 언어를 배우는 것을 어렵게 만듭니다. 모든 단일 개념 / 작업에 고유 한 기호가있는 경우 훨씬 더 큰 키보드가 필요하므로 기호가 적절할 때 기호가 재활용됩니다.
int* p
) 의 일부로 별표를 강조 하면서 포인터가 포함될 때 같은 줄에 여러 선언을 사용하지 않도록 학생 에게 경고하십시오 . 학생이 포인터의 개념을 완전히 이해했으면 int *p
is 구문이 동일 하다는 것을 학생에게 설명하고 여러 선언으로 문제를 설명하십시오.