포인터의 사용 사례와 장점은 무엇입니까? [닫은]


10

나는 종종 포인터의 장점을 보려고 애 쓰고있다 (저수준 프로그래밍 제외).

String 또는 char [] 대신 char *를 사용하는 이유 또는 포인터 산술의 이점은 무엇입니까?

그렇다면 포인터의 장점과 사용 사례는 무엇입니까?


6
이것은 약간의 엘리트 주의자처럼 들릴 것이지만, IMHO 포인터의 장단점에 대해 문의해야한다면, 아마도 그것들이 필요하지 않을 것입니다.
Jas

3
아마! 그러나 질문은 여전히 ​​유효합니다!
Zolomon

1
많은 프로그래밍 언어가 C 의미에서 실제 포인터를 갖는 것은 아니기 때문에 이것은 실제로 언어에 구애받지 않습니다.
David Thornley

답변:


6

동적 메모리 위치, 많은 데이터 구조 및 대량의 데이터를 효율적으로 처리하려면 포인터가 필요합니다. 포인터가 없으면 모든 프로그램 데이터를 전역 적으로 또는 함수로 동등하게 할당해야하며, 데이터의 양이 원래 허용했던 것 이상으로 증가했다면 의지 할 필요가 없습니다. 나는 절대적 인 것을 사용하는 것을 망설이지 만 모든 현대 컴퓨터 언어에는 포인터가 어떤 형태 또는 다른 포인터가 있다는 것을 알고 있습니다.

포인터를 사용하는 대부분의 언어에는 포인터 인 특정 종류의 참조와 그렇지 않은 특정 종류의 참조가 있으며 표기법상의 차이는 없습니다. Lisp cons셀은 포인터가 아니지만 포인터 쌍입니다 fixnum. Java에서 클래스 인스턴스에 사용되는 변수는 포인터이지만 int그렇지 않습니다. 언어 구문은이를 반영하지 않습니다.

C는 포인터가 선택적이고 명시 적이며 명시적인 포인터 산술을 허용한다는 점에서 특이합니다. 그것은 쓰기에 완벽하게 가능 struct foo bar; struct foo * baz;하고, 메모리를 할당 한 번을 위해 baz당신은 모두 사용할 수 있습니다 barbaz나타내는 struct foo들. 포인터는 선택 사항이므로 표기법의 차이가있는 것이 좋습니다. (그것은 주어진, 스마트 포인터를 위해 C ++에 필수적 boost::shared_ptr<foo> bar;, bar.reset()하나의 의미를 가지고 있으며, bar->reset()가능성이 많은 다른 일을하는 것입니다.)

(실제로, ^파스칼 과 같이 C가 처음 개발 될 때 명시 적 포인터가 종종 다른 언어로 사용되었습니다 . C는 오늘날 가장 일반적으로 사용되는 것보다 오래된 언어로 표시됩니다.)

C의 디자인 목표 중 하나는 Unix를 작성하는 것이 었으며, 따라서 자세한 방법으로 메모리 위치를 처리해야했습니다. (C는 실제로 설계 될 때 일반적으로 사용되는 시스템 구현 언어 군 중 하나이며, 다른 예로는 제어 데이터 컴퓨터의 경우가 있습니다. C는 큰 타격을 입힌 언어입니다.) 따라서 C 포인터를 직접 조작 할 수 있습니다. 메모리 주소를 할당하고 새로운 주소를 계산합니다. 이로 인해 C에서 일부 설계 결정을 내 렸습니다. C 배열은 포인터 산술에 크게 의존하고 있으며 실제로 많은 상황에서 배열이 포인터로 붕괴됩니다. 참조로 변수를 C 함수에 전달하는 것은 포인터로 수행됩니다. 다른 현대 언어와 같은 형식으로 배열과 참조 변수를 전달할 필요가 없었으므로 C는 그 변수를 얻지 못했습니다.

따라서 오늘날 대부분의 언어에서 사실을 상기시키지 않고 포인터를 계속 사용한다는 대답이 있습니다. C에서는 C ++의 경우 C ++에서는 포인터를 사용하여 저수준 작업을 수행하거나 특별한 표기법이없는 고급 작업을 수행합니다.


아주 좋은 답변
케이트 그레고리

1
C / C ++의 포인터와 Java의 Reference 사이에서 파악할 수없는 차이점을 가장 잘 설명하기 때문에이 대답을 받아들입니다.
OliverS

Java가 Gosling (Java의 주요 작성자)에 의해 인식 된 "con"을보다 명확하게 설명하기 위해 포인터를 사용하지 않는 이유에 대한 간단한 설명을 추가하는 것이 좋습니다.
귀도 안 셀미

10

복잡한 데이터 구조. 포인터가없는 연결된 목록 또는 이진 트리와 같은 것을 만들 수 없습니다.

포인터의 "pros"와 "cons"는 없습니다. 그것들은 망치와 같은 도구 일뿐입니다.


5
Java에는 포인터가 없습니다. 그러나 링크 된 목록과 이진 트리를 작성할 수 있습니다. 참조 (Java에서와 같이)와 포인터 (C에서와 같이)에는 차이가 있습니다.
StartClass0830

7
참조와 포인터 사이에는 차이가 없습니다. 포인터 산술은 C에 따라 다릅니다. 포인터가 있지만 포인터 산술이없는 다른 언어가 있습니다 (예 : Pascal).
zvrba

1
포인터와 참조는 당신이 생각하는 것과 동의어가 아닙니다. 차이점을 보려면 이것을 읽으십시오. stackoverflow.com/questions/57483/…
StartClass0830

4
이 목록의 처음 두 항목을 해결하기 위해 Java 참조를 다시 할당 할 수 있으며 null을 가리킬 수 있습니다. 포인터의 특징은 다른 객체를 간접적으로 참조 할 수 있다는 것입니다. 내 리트머스 테스트는 : 당신이 순환 데이터 구조 (자바 참조로 할 수있는)를 만들 수 있다면 그것은 포인터입니다. (C ++ 참조를 사용하여 순환 데이터 구조를 구축 할 수는 없습니다.)
zvrba

1
포인터와 참조에는 차이가 있습니다. 예를 들어 C #에는 둘 다 있습니다. ( blogs.msdn.com/b/ericlippert/archive/2009/02/17/… )
Steven Evers

2
  • 포인터를 사용하면 런타임에 메모리를 할당 및 할당 해제 할 수 있습니다.
  • 또한 복사하지 않고 허용 범위 밖에서 큰 데이터 구조를 사용할 수 있습니다.

C ++, Java 및 기타 동일한 유형의 언어에 대한 참조는 '안전 포인터'입니다. 그리고 이러한 참조는 Java에서 많이 사용됩니다.


1
C ++의 참조는 안전한 포인터가 아닙니다. C ++의 참조는 포인터와 전혀 관련이 없습니다. C ++의 참조는 aliases 입니다. 에 할당 NULL할 수 없으며 생성 된 후에는 수정할 수 없습니다.
Billy ONeal

@Billy : C ++ 참조는 일반적으로 포인터를 사용하여 구현되며 어떤면에서는 비슷하게 작동하므로 사람들은이를 일종의 제한된 포인터로 생각합니다.
David Thornley

2

대부분의 컴퓨터 프로그램은 메모리의 값을 검사하고 변경해야합니다 (오래된 사람에게는 엿보기 및 찌르기라고 함). 결과를 예측할 수 있도록 메모리에서 해당 값의 위치를 ​​제어해야합니다 (일부 경우 순서가 중요합니다. 실행 가능 코드로드가 한 예입니다). 따라서 메모리의 위치를 ​​나타내는 데이터 유형이 있어야합니다. 프로그래밍 환경에서 추상화로 숨기더라도 여전히 존재합니다.


2

char*포인터의 미묘한 예입니다. 아마도 std::string(또는 유니 코드 / ANSI / 멀티 바이트 특수성을 처리하는 더 나은 유형)을 사용 하는 것이 좋습니다 char*. 포인터의 거의 모든 다른 예를 들어 ( Employee*, PurchaseOrder*, ...) 그러나, 많은 이점이있다 :

  • 단일 함수보다 큰 범위-힙에 객체를 할당하고 오랫동안 포인터를 전달하십시오.
  • 값별 복사 비용이 없기 때문에 큰 객체를 더 빠르게 호출합니다.
  • 함수가 전달 된 매개 변수를 변경하도록하는 한 가지 방법
  • 전체 객체 대신 주소 만 복사하는 컬렉션에서 공간과 시간 절약

사실, 포인터는 너무 중요하여 실제로는 가지고 있지 않은 것으로 보이는 대부분의 언어에는 실제로 만 있습니다. C # 및 Java의 참조 유형은 기본적으로 솔리드 객체로 위장한 포인터입니다.

이제 포인터 조작 ( p++포인터 또는 p += delta)은 완전히 다른 이야기입니다. 어떤 사람들은 그것이 위험하다고 생각하고 어떤 사람들은 그것이 위험하다고 생각합니다. 그러나 그것은 당신의 질문에서 더 멀어졌습니다.


1

데이터 구조와 프로그램 실행 공간을 줄이면 포인터가 더 빨라지고 오버 헤드가 줄어 듭니다. ( 'can'이라는 단어에 유의하십시오.)

일반적으로, 자체 할당을 수행하거나 사용자 대신 무언가를 수행하여 리소스를 할당 한 경우 완료되면 리소스를 해제해야합니다.

위의 작업을 수행하는 데 따른 부담은 런타임이 아닌 개발자에게 책임을 다시 부여하는 것입니다. 이것은 물건이 더 오래 살거나 경계를 넘어 더 적절한 시간에 처분되거나 가비지 수집기의 무게를 운반 할 필요가 없다는 점에서 더 많은 이점을 가지고 있습니다.

일반적으로 예외와 범위를 포함하는 이국적인 경우에는 정리가 수행되지 않는 코드를 피할 경우 좀 더주의를 기울여야하는 일부 경우가 있습니다. 현실적으로 이러한 케이스는 주위에 설계 될 수 있습니다. 우리는 수십 년 동안 관리 코드없이 살았습니다.

포인터를 "단단하게"만드는 것은 하드웨어 수준에서 무슨 일이 일어나고 있는지 이해하지 못하는 것입니다. 간접 지향에 지나지 않습니다.

포인터는 훨씬 더 원시적 인 액세스를 제공하며 이는 매우 유용하거나 영리하거나 필요할 수 있습니다. 당신은 어디를 가리켜 서 무엇이든 다룰 수 있습니다. 하나님과 같은 능력을 선으로 사용한다면 매우 좋습니다.

단점은 일반적으로 무언가를 놓는 것을 잊어 버렸거나, 한 번 이상 풀어 놓거나, 풀어 놓은 후에 무언가를 참조하거나, 아무데도 가리 키지 않을 때 무언가를 펜싱함으로써 낭비됩니다. 이러한 일들은 종종 엄청난 충돌을 초래하며 정직하게 말하면 포인터가 깨지기보다는 논리적 인 문제가 있음을 나타냅니다.

탄탄한 개발자라면 포인터를 사용하는 것이 다른 데이터 구조보다 문제가되지 않아야합니다. 다시 말하지만, 그것은 로켓 과학이 아니며 사람들은 눈을 깜박이지 않고 수십 년 동안 그것을했습니다. 요즘에는 덜 배우고 있습니다.

당신이 포인터가 필요하지 않다면, 훌륭한 가비지 콜렉션이 제공하는 대류 및 외설적 인 경우는 관리 환경에서 훨씬 더 훌륭하게 작동합니다. 메모리를 가져 와서 사용하고 버릴 수 있다는 것은 좋은 생각입니다. 언제나 나중에 그렇게 할 수 있다면 폐기 될 수 있다는 것을 알고 있습니다. 그것은 약간의 리프팅을 수행하는 런타임과 교환하면서 코더 부분의 코드가 약간 적습니다.


0

가장 좋은 대답은 실제로 질문에 포함되어 있습니다. 포인터는 저수준 프로그래밍을위한 것입니다. 물론 C를 사용하는 경우 포인터를 사용하지 않는 것은 한 손을 등 뒤로 묶는 프로그래밍과 비슷하지만 그에 대한 대답은 고급 언어를 대신 사용하는 것입니다.


-1

포인터는 가장 흥미로운 프로그래밍에 필요한 머신에 대한 가시성을 제공합니다. 대부분의 현대 언어는 단순히 당신에게서 거친 부분을 숨 깁니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.