어린 마음이 포인터 개념을 배워야합니까?


89

C 마스터 Dennis Ritchie 가 C로 포인터를 도입 한 이유는 무엇 입니까? 그리고 VB.NET이나 Java 또는 C #과 같은 다른 프로그래밍 언어가 왜 그것들을 제거 했습니까? Google에서 몇 가지 요점을 찾았으며 귀하의 의견도 듣고 싶습니다. 현대 언어에서 포인터 개념을 제거하는 이유는 무엇입니까?

사람들은 C가 기본 언어이고 포인터는 C를 강력하고 훌륭하게 만들고 C를 여전히 현대 언어와 경쟁하게 만드는 개념이라고 말합니다. 그렇다면 왜 더 현대적인 언어로 포인터를 제거 했습니까?

포인터에 대한 지식이 새로운 프로그래머에게 여전히 중요하다고 생각하십니까? 사람들은 요즘 VB.NET 또는 Java를 사용하고 있습니다. C보다 고급 기능을 지원하고 (포인터 개념을 사용하지 않음) 현재 많은 사람들이 고급 기능을 지원하므로 C를 무시하고이 언어를 선택합니다. 나는 C로 시작하라고 말합니다. 그들은 C에서 불가능한 VB.NET 또는 Java에서 고급 작업을 수행 할 때 포인터의 개념을 배우는 것이 낭비라고 말합니다.

어떻게 생각해?

업데이트 :

Google에서 읽은 의견은 다음과 같습니다.

  1. 초기 컴퓨터는 너무 느리고 최적화되지 않았습니다.

  2. 포인터를 사용하면 주소에 직접 액세스 할 수 있으므로 함수 호출에서 주소를 복사하는 대신 시간을 절약 할 수 있습니다.

  3. 포인터를 사용하면 보안이 크게 악화되므로 Java 및 C #에 포인터가 포함되어 있지 않습니다.

이것들과 내가 찾은 것 이상. 여전히 유용한 답변이 필요합니다. 대단히 감사하겠습니다.


52
Java에는 포인터가 없습니까? 그건 사실이 아니야. Java의 모든 객체 참조는 기본적으로 포인터입니다.
quant_dev

20
quant_dev의 의미는 Java는 투명하게 사용되는 포인터로 가득 차 있지만 프로그래머는 명시 적으로 사용할 수 없습니다.
sakisk

9
다음은 Joel Spolsky의 관련 기사입니다. joelonsoftware.com/articles/fog0000000319.html
Joe Internet

11
"C 마스터 데니스 리치 (Dennis Ritchie)는 왜 c에 포인터를 도입 했습니까?" c에서는 포인터가 소개 되지 않았 으며, 이름을 포함하여 어셈블리 연습에서 바로 나왔습니다.
dmckee

14
@quaint_dev : Java에는 실제로 포인터가 없습니다. 참조는 포인터가 할 수있는 모든 것을 할 수는 없으므로 참조의 관점에서 포인터를 이해하려고 시도하는 것은 좋은 방법이 아닙니다. 포인터는 산술을 할 수 있습니다. 참조는 할 수 없습니다. (Java를 사용해야 할 때마다 실제로 제한되는 한계)
Billy ONeal

답변:


128

당시에는 개발자들이 금속에 훨씬 더 가까이 다가 가고있었습니다. C는 본질적으로 어셈블리를 대체 할 수있는 수준이 높았으며, 이는 하드웨어와 거의 비슷하기 때문에 코딩 문제를 해결하는 데 효율적인 포인터가 필요했습니다. 그러나 포인터는 날카로운 도구이므로 부주의하게 사용하면 큰 손상을 입을 수 있습니다. 또한 포인터를 직접 사용하면 당시에는 문제가되지 않았던 많은 보안 문제에 대한 가능성을 열어줍니다 (1970 년 인터넷은 몇 개의 대학에 걸쳐 수십 대의 컴퓨터로 구성되어 있었으며 그렇게 불리지 않았습니다. ...), 이후 점점 더 중요해졌습니다. 따라서 오늘날 고급 언어는 원시 메모리 포인터를 피하도록 의식적으로 설계되었습니다.

"VB.Net 또는 Java에서 수행되는 고급 작업은 C에서는 불가능합니다"라고 말하는 것은 매우 제한적인 관점을 보여줍니다.

우선,이 모든 언어들 (어셈블리도)은 Turing이 완료되었으므로 이론적으로는 한 언어로 가능한 모든 것이 가능합니다. VB.Net 또는 Java 코드가 컴파일되고 실행될 때 어떤 일이 발생하는지 생각해보십시오. 결국 머신 코드로 변환 (또는 맵핑)됩니다. 머신이 이해하는 유일한 것은 기 때문입니다. C 및 C ++와 같은 컴파일 된 언어에서는 실제로 하나 이상의 실행 파일 / 라이브러리로서 원래 상위 소스 코드와 동등한 전체 머신 코드를 얻을 수 있습니다. VM 기반 언어에서는 프로그램의 전체 동등한 머신 코드 표현을 얻는 것이 더 까다 롭고 불가능할 수도 있지만 결국 런타임 시스템과 JIT의 깊은 리 세스 내에 어딘가에 있습니다.

물론 어떤 솔루션이 특정 언어로 실현 될 수 있는지는 완전히 다른 질문입니다. 현명한 개발자는 어셈블리에서 웹 응용 프로그램을 작성하지 않을 것입니다. 저수준 언어, 일반적으로 C로 구현됩니다.

질문에 답하기 위해

당신은 젊은이들에게 포인터에 대한 지식이 중요하다고 생각합니까?

포인터 뒤에있는 개념은 간접적 입니다. 이것은 매우 중요한 개념이며 모든 훌륭한 프로그래머는 특정 수준에서 이해해야합니다. 누군가가 더 높은 수준의 언어로만 작업하더라도 간접적 인 참조와 참조는 여전히 중요합니다. 이것을 이해하지 못한다는 것은 매우 강력한 도구를 사용할 수 없어 장기적으로 문제 해결 능력을 심각하게 제한한다는 것을 의미합니다.

내 대답은 그렇습니다. 정말 좋은 프로그래머가 되려면 포인터도 이해해야합니다 (재귀뿐만 아니라 신진 개발자를위한 다른 전형적인 걸림돌입니다). 당신은 그것으로 시작할 필요가 없습니다-요즘 C가 제 1 언어로 최적이라고 생각하지 않습니다. 그러나 어느 시점에서 간접 지향에 익숙해 져야합니다. 그것 없이는 우리가 사용하는 도구, 라이브러리 및 프레임 워크가 실제로 어떻게 작동하는지 이해할 수 없습니다. 그리고 도구가 어떻게 작동하는지 이해하지 못하는 장인은 매우 제한적입니다. 공평하게도, 더 높은 수준의 프로그래밍 언어로도 이해할 수 있습니다. 좋은 리트머스 테스트 중 하나는 이중 연결 목록을 올바르게 구현하는 것입니다. 선호하는 언어로 할 수 있다면 간접적 인 이해가 충분하다고 주장 할 수 있습니다.

그러나 다른 것이 아니라면, 우리는 그들이 가지고있는 말도 안되는 간단한 도구를 사용하여 믿을 수없는 것들을 만들 수 있었던 옛 프로그래머들에 대한 존중을 배우기 위해 노력해야합니다. 우리는 모두 거인의 어깨에 서 있으며, 우리 자신을 거인이라고 가장하기보다는 이것을 인정하는 것이 좋습니다.


5
이것은 좋은 대답이지만 실제로 "젊은 마음이 포인터 개념을 배워야합니까?"라는 질문에 대답하지 않습니다.
팔콘

11
+1 좋은 답변입니다. 나는 튜링 완전성 논쟁을 버릴 것입니다-실제 프로그래밍의 경우 나중에 언급했듯이 빨간색 청어입니다. 계산 성 이론, 즉 turing complete는 실제로 가능한지 또는 인간적으로 가능한지 여부와 상관없이 동일한 알고리즘을 구현하는 잠재적 프로그램의 (많은 언어의 경우 무한한) 공간에 프로그램이 있음을 의미합니다. 단지 그것이 결국 모든 머신 코드임을 지적하는 것은 어리석은 짓을하지 않으면서도 그 요점을 증명해줍니다. "한 언어로 모든 것을 할 수 있습니다. 하하 르!" 씨.

5
"그리고 자신의 도구가 어떻게 작동하는지 이해하지 못하는 장인은 매우 제한적입니다."
quick_now

6
또한 포인터 (및 확장 참조)의 메커니즘을 이해하지 못하면 얕은 / 심층 데이터 구조 복사의 개념을 이해하지 못하므로 심각한 추적하기 어려운 버그가 발생할 수 있습니다. "현대적인"고급 언어로도.
Mavrik

1
C는 유닉스를위한 휴대용 어셈블러, 즉 금속에 가깝 도록 설계되었습니다 .

39

나는 당신이 다를 필요가 있다고 생각합니다.

Java 및 기타 고급 언어는 포인터를 제거하지 않았습니다. 그들이 한 것은 평범한 포인터 산술을 제거하는 것이 었습니다.

실제로 Java는 여전히 보호 되고 제한된 포인터 산술을 허용합니다 : 배열 액세스. 평범한 오래된 C에서 배열 액세스는 역 참조입니다. 그것은 당신이하고있는 일을 명확하게 전달하기 위해 다른 표기법, 구문 설탕입니다.
여전히와 array[index]같습니다 *(array+index). 그 때문에 index[array]일부 C 컴파일러가 경고를 줄 수 있다고 가정하더라도 마찬가지 입니다.
결과적으로는에 pointer[0]해당합니다 *pointer. "배열에 대한 포인터"가 배열의 첫 번째 항목의 주소이고 이후 요소의 주소가 색인을 추가하여 계산되기 때문입니다.

Java에서는 일반 포인터 산술 (참조 및 역 참조)이 더 이상 존재하지 않습니다. 그러나 포인터가 존재합니다. 그들은 그것들을 참조라고 부르지 만 그것이 무엇인지 변경하지는 않습니다. 그리고 배열 액세스는 여전히 똑같습니다. 주소를보고 인덱스를 추가하고 해당 메모리 위치를 사용하십시오. 그러나 Java에서는 해당 인덱스가 원래 할당 한 배열 범위 내에 있는지 확인합니다. 그렇지 않으면 예외가 발생합니다.

이제 Java 접근 방식의 장점은 임의의 바이트를 임의의 메모리 위치에 맹목적으로 쓰는 코드가 없다는 것입니다. 버퍼 오버플로를 확인하지 않으면 런타임이 자동으로 수행하므로 안전성과 보안이 향상됩니다.

이것의 단점은 단순히 덜 강력하다는 것입니다. C에서 메모리 안전 프로그래밍을 수행 할 수 있습니다. Java에서 안전하지 않은 프로그래밍의 속도와 가능성을 활용하는 것은 불가능합니다.

실제로, 포인터 나 포인터 산술에 대해서는 어려운 것이 없습니다. 그것들은 일반적으로 복잡한 방식으로 설명되지만 모든 포인터는 하나의 거대한 배열 (메모리 공간)에 대한 인덱스입니다. 값을 참조하는 모든 것은 인덱스를 찾을 수있는 인덱스를 제공하는 것입니다. 지정된 인덱스의 값 (이것은 유형에 따라 메모리의 값이 다른 크기라는 점을 고려하지 않기 때문에 조금 단순화되었습니다. 그러나 실제 개념의 일부가 아닌 상황의 세부 사항입니다)

IMHO, 우리 일의 모든 사람들은 그것을 이해할 수 있거나 단순히 잘못된 분야에 있습니다.


13
+1 Java 및 C #에는 여전히 포인터가 있으며 물론 NullPointerExceptions
jk가 있습니다.

5
가비지 수집기가 물건을 움직일 때 시간이 지남에 따라 참조가 다른 영역을 가리킬 수도 있습니다. 포인터는 일반적으로 정적입니다.

3
+1 : 이것! 그리고 포인터 (일반적으로)에 대한 두 가지 어려운 점이 있다고 생각합니다 : 간접 (C, C #, Java 등에서 발생) 및 포인터 산술 ( 같은 방식으로 Java에서는 발생 하지 않음 ). 내 의견으로는 모두 배울 수있는 중요한 개념이며 모두 초보자를위한 주요 장애물이다. 그러나 혼동해서는 안됩니다. 간접적으로 포인터 산술 없이 발생할 수 있습니다 .
Joachim Sauer

2
실제로 는 물체의 크기 (C)를 이미 고려 back2dos했기 때문에 처음이었습니다 (array + index).
Matthew Flaschen

4
@CyberSkull, 대답은의 구문 상당을주고 있었다 array[index], 그입니다 *(array+index). 컴파일러가 내부적으로 작업하는 방식을 보여주고 싶다면 명시 적으로 바이트에 대해 이야기하거나 어셈블리를 제공 할 수 있습니다.
Matthew Flaschen

24

포인터의 개념은 일반적인 컴퓨터 프로그래밍 지식 체계에서 중요합니다. 개념을 이해하는 것은 언어가 직접 지원하지 않더라도 모든 언어의 프로그래머 또는 프로그래머에게 좋습니다.

포인터는 데이터 구조 (링크 된 목록) 및 데이터베이스 디자인 (외부 키)에서 사용됩니다.

VB 및 C #과 같은 언어는 "참조"를 통해 데이터를 메소드에 전달할 수 있는데, 이는 포인터 유형으로 생각할 수 있습니다.

알고리즘의 효율성을 위해서는 메모리에서 데이터가 할당되는 위치 (스택 대 힙)를 이해하는 것이 여전히 중요합니다.

제 생각에는 기본을 배우는 것이 중요합니다.


일반적인 개념이 도움이되지만 포인터가 필요한 상황을 찾지 못했습니다 (주로 Java와 PHP를 사용하도록 허가 됨). 내 C ++ 과정이 포인터에 대해 생각 해낸 유일한 예는 그것들을 사용하여 높은 수준의 프로그래밍 언어로 존재하는 목록 및 사전과 같은 더 복잡한 데이터 구조를 만드는 것입니다.
Ben Brocka

2
올바른 방법이지만 데이터를 메소드에 전달할 때 경우에 따라 변수에 대한 포인터를 전달할 가능성이 있습니다. 그러나 포인터의 개념은 소프트웨어 언어에서의 구현에 관계없이 유용하다고 생각합니다.
NoChance

1
@SirTapTap : 당신이 어떤 종류의 과정에서 C ++를 배운다면, 그들은 당신에게 C ++을 가르치기 때문입니다. C ++를 사용하는 가장 좋은 방법은 아닙니다. 포인터 산술은 일반적으로 C ++에 대한 지식을 모르고 알 수 있기 때문에 광택이 있습니다. 그러나 일반 컬렉션을 반복하는 것과 같은 것조차도 실제 / 아이디 오 매틱 C ++의 포인터로 수행됩니다. (표준 템플릿 라이브러리의 작동 방식의 기초이므로)
Billy ONeal

@BillyONeal Pointers는 거의 절반의 과정이었습니다. 실제로 프로그래머로서 (스마트) 포인터를 실제로 사용하는 것을 결코 찾지 못했습니다. 내가 한 일에서 메모리를 직접 제어 할 필요가 없었기 때문입니다. 물론 코스가 제대로 교육되지 않았을 가능성이 항상 있습니다. 제가 가장 좋아하는 것은 아닙니다.
Ben Brocka

1
@SirTapTap : 실용 : STL의 모든 컬렉션과 알고리즘. std::sort, std::partition, std::find, 등 그들은 포인터와 함께 작동, 그들은 포인터 (반복자)처럼 행동 객체와 함께 작동합니다. 그리고 그들은 모든 일반 컬렉션을 처리합니다. 연결된 목록, 동적 배열, deques, 트리 또는 다른 종류의 사용자 정의 모음. 포인터가 없으면 그런 추상화를 할 수 없습니다.
Billy ONeal

19

예, 그렇습니다, 그렇습니다 그리고 그렇습니다 !!!

기본 사항을 모른다면 절대로 어렵고 이상하고 어렵고 복잡한 문제를 해결할 수 없습니다.

그리고 기초를 정말 잘 이해하면 구직 시장에서 훨씬 더 시장성이 있습니다.


나는 10 년 동안 프로그래밍을 한 챕터와 함께 한 번 일했으며 포인터가 어떻게 작동하는지 전혀 몰랐습니다. 나는 (더 많은 후배) 그를 교육하는 화이트 보드에서 몇 시간을 보냈다. 그것은 내 눈을 뜨었다. 그는 너무 많은 기본적인 것들에 대한 아이디어가 없었습니다.

가능한 한 많이 알아 두십시오.


그러나 기본은 무엇입니까? 어셈블리, 이진 코드?
SiberianGuy

5
"가능한 많은 것을 아는 것"이라는 일반적인 관점이 건전한 것이지만, "만약 당신이 겪는 정말 힘들고, 이상하고, 어렵고 복잡한 문제를 해결할 수 없을 것"이라는 생각에 의문을 가질 것입니다. 포인터를 이해하지 못합니다. 이것은 어쨌든 이러한 "매직"포인터를 사용하여 모든 어려운 문제를 해결할 수 있음을 의미합니다. 포인터 사이의 개념을 아는 것이 유용하지만 많은 프로그래밍 분야에 직접적으로 필요한 것은 아닙니다.
Dan Diplo

4
@Idsa : 아니, 훨씬 더 기본적인 오늘날 많은 프로그래머들은 오늘날 goo 'ole'칩에서 트랜지스터와 로직 게이트가 어떻게 작동하는지 알지 못하며 전자가 어떻게 움직이는 지, 그리고 양자 불확실성이 소형화에 미치는 영향을 반드시 알고 있어야한다. 나는 cks, 립톤 및 들소부터 시작하지 않았습니다! 그리고 딸꾹질 들소 입자!
Lie Ryan

2
기본 사항 .... 물건이 저장되는 방법과 같은 것들. 바이트, 단어, 부호있는 방식과 부호없는 방식의 차이 포인터 작동 방식 캐릭터가 무엇인가. 사물이 ASCII로 코딩되는 방식 (현재는 유니 코드) 간단한 구조 만 사용하여 메모리에 연결된 목록을 만드는 방법 문자열이 실제로 작동하는 방식 이 작은 것들로부터 더 큰 것들이 자랍니다.
quick_now

5
당신이 할 수있는 한 많은 것을 아는 것이 좋은 원칙이지만, 말 앞에 카트가 있다고 생각합니다. 훌륭한 개발자는 훌륭한 개발자이기 때문에 가능한 모든 것을 배우려고 노력합니다. 지식에 대한 열망은 훌륭한 개발자의 특성입니다. 좋은 개발자의 원인이 아닙니다. 외출하고 배우는 것만 큼 좋은 개발자가되지는 않습니다. 그것은 당신을 걷는 백과 사전으로 만들 것입니다. 훌륭한 개발자라면 문제를 해결하기 위해 얻은 지식을 적용 할 수 있습니다. 그러나 아직 훌륭한 개발자가 아니었다면 지식은 그다지 도움이되지 않습니다.
corsiKa

18

예, 이해가 중요합니다.

몇 달 전에 저는 C #으로 프로그래밍하고 있었고 목록의 사본을 만들고 싶었습니다. 물론 내가 한 일은 NewList = OldList;수정하기 시작했다 NewList. 두 목록을 인쇄하려고 할 때 복사본이 아닌 NewList포인터에 불과하기 때문에 둘 다 동일했기 때문에 OldList실제로 OldList모든 것이 바뀌 었습니다 . 그 사실을 알아내는 데 너무 오래 걸리지 않았지만, 반 친구 중 일부는 그렇게 빠르지 않았으며 왜 이런 일이 일어나고 있는지 설명해야했습니다.

예:

List<int> a = new List<int>();
a.Add(2);
a.Add(9);
a.Add(8);
a.Add(1);
List<int> b = new List<int>();
b = a; //Does not make a copy, b is just a synonym!
b.Sort();
for (int i = 0; i < a.Count; i++)
{
    Console.WriteLine("a: " + a[i] + " b: " + b[i]);
}

물론 결과는 다음과 같습니다.

a: 1 b: 1
a: 2 b: 2
a: 8 b: 8
a: 9 b: 9

사용 방법을 아는 것이 그렇게 중요하지는 않지만 이해하는 것이 중요합니다!


2
대신 왜 그것들을 사용하고 언제 사용해야하는지가 가장 중요합니다 :)
niko

5
" NewList단지 포인터이었다 OldList" , 정확히 말하면 모두 - NewListOldList같은 언급, 단지 포인터이었다 List객체입니다.
Péter Török

또한 새로 만든 목록에 대한 b참조가 더 이상 없으며 이제 가비지 라는 것을 이해해야합니다 .
TMN

14

개념의 포인터! = 산술의 포인터! = 구문의 포인터

첫 번째는 항상 깊고 얕은 사본에 대한 이해가 필요하고 참조로 전달하거나 값으로 전달하는 등의 이해가 필요한 경우 항상 중요합니다. 다른 두 가지는 언어 사용이 허용하는 경우에만 중요합니다.


1
요즘에는 포인터 구문 / 수학이 아닌 기본 참조 개념 만 알아야합니다. 나는 C에서 포인터 (산술 및 구문 사용)를 다시 배웠습니다. 내가 지금 프로그래밍하는 언어는 안전하지 않은 작업을 수행 할 수있는 C 스타일 포인터를 다루지 않습니다. 파이썬 이유 하나는 이해할 수 a=[1,2]; b=a; a.append(3)모두 그 ab모두가는가 동일한 객체를 참조 [1,2,3]C에서와 같이 재료를 모르고 i배열 th 요소가 참조 할 수 arr[i]또는 i[arr]모두 그대로 *(arr+i). 언어가 i[arr]사용 되지 않는 것을 선호합니다 .
dr jimbob

" 다른 두 언어는 당신이 사용하는 언어로 당신이 그것들을 사용할 수있는 경우에만 문제가됩니다. " 용어 du jour는 정의 상으로는 내일 사용되는 언어와 거의 같지 않습니다. 그리고 내일 당신은 포인터 가능 언어에 직면 할 수 있습니다. 결론? 더 나은 사람은 지금, 영원히 영원히 그것을 파악합니다. 그렇게 어렵지는 않지만 그만한 가치가 있습니다.
JensG

14

C 마스터 Dennis Ritchie가 C로 포인터를 도입 한 이유는 무엇입니까?

포인터는 여러 가지 방법으로 사용할 수있는 매우 강력한 메커니즘이기 때문입니다.

그리고 VB.NET이나 Java 또는 C #과 같은 다른 프로그래밍 언어가 왜 그것들을 제거 했습니까?

포인터는 여러 가지 방법으로 오용 될 수있는 매우 위험한 메커니즘이기 때문입니다.

프로그래머는 포인터에 대해 배워야한다고 생각하지만 교육적인 관점에서 보면 포인터를 일찍 소개하는 것은 현명하지 않습니다. 그 이유는 그것들이 매우 다양한 목적으로 사용되기 때문에 왜 특정 상황에서 포인터를 사용하고 있는지 초보자로 말하기가 어렵습니다.

다음은 포인터가 사용되는 불완전한 목록입니다.

  • 동적 할당 ( new T)
  • 재귀 데이터 구조 ( struct T { T* next; /* ... */ };)
  • 배열에 대한 반복자 ( for (T* p = &a[0]; p != &a[0] + n; ++p) { ... })
  • 객체에 대한 공유 액세스 ( T* new_pointer = existing_pointer;)
  • 아형 다형성 ( T* pointer_to_base = pointer_to_derived;)
  • 참조 별 레거시 호출 ( mutate(&object);)
  • 선택적 유형 ( if (p) { /* ... */ })

이러한 모든 개념에 단일 메커니즘을 사용하면 숙련 된 프로그래머의 힘과 우아함, 프로그래밍에 익숙하지 않은 사람에게 큰 혼란 가능성이 있음을 알 수 있습니다.


" C 마스터 Dennis Ritchie가 C로 포인터를 도입 한 이유는 무엇 입니까? 포인터는 여러 가지 방법으로 사용할 수있는 매우 강력한 메커니즘이기 때문입니다." -사실은 모르겠지만 C 언어로 래핑되는 기계 명령어와 관련이 있다고 생각합니다 .C의 전임자는 포인터로 생각하는 데 사용되므로 어쩌면 그랬을 것입니다. 그가 잘 알려진 강력한 메커니즘을 사용하지 않았다면 놀랍습니다. 다른 어떤 것도 1978 년이나 1960 년대에는 너무 멀었을 것입니다.
JensG

12

왜? 양식 디자이너와 코드 생성기를 사용하여 거대한 시스템을 작성할 수 있습니다. 충분하지 않습니까? (반어)

그리고 이제 진지하게, 포인터는 많은 영역에서 프로그래밍의 중요한 부분은 아니지만 사람들이 내부의 작동 방식을 이해할 수 있도록합니다. 그리고 내부의 작동 방식을 이해하는 사람이 아무도 없다면 SQL2020, Windows 15 및 Linux 20.04가 30 개 이상의 추상화 계층을 실행하는 가비지 수집 가상 머신으로 작성되고 JavaScript를 통해 IDE를 통해 생성 된 코드가 작성됩니다. .

이것은 내가보고 싶은 것이 아닙니다.

그렇습니다, 그들은 반드시해야합니다!


2
좋은 유머! +1하고 완전히 동의합니다.
heltonbiker

7

Java와 C # 모두 포인터를 제거하지 않았으며 거의 ​​동일한 참조가 있습니다. 제거 된 것은 포인터 산술로, 입문 과정에서는 생략 할 수 있습니다.
포인터 나 참조의 개념 없이는 사소한 응용 프로그램을 수행 할 수 없으므로 교육 할 가치가 있습니다 (동적 메모리 할당 없이는 수행 할 수 없음).

C ++과 Java에서 다음을 고려해보십시오 .C #에서는 크게 다르지
aClass *x = new aClass();
aClass x = new aClass();
않습니다. 포인터와 참조 사이에는 큰 차이가 없습니다.
필요하지 않은 경우와 높은 수준의 모델로 프로그래밍 할 때는 포인터 산술을 피해야하므로 큰 문제가 없습니다.


6

전문 프로그래머는 포인터를 숙달해야합니다.

프로그래밍을 알고 자하는 사람들은 그 존재와 의미에 대해 배워야하지만 반드시 사용해야하는 것은 아닙니다.

프로그래밍을 통해 개인적인 문제를 해결하고 싶은 사람들 (나 같은 파이썬 스크립트를 많이 사용하는 사람들)은 그것들을 전혀 무시할 수 있습니다.

글쎄, 그건 내 의견이다 ...; o)


3

가변 주소 포인터는보다 일반적인 간접 개념의 특정 사례입니다. 간접 (indirection)은 대의원 및 콜백과 같은 많은 구성에서 대부분의 현대 언어에서 사용됩니다. 간접 개념을 이해하면 이러한 도구를 가장 잘 사용하는시기와 방법을 알 수 있습니다.


3

틀림없이 그렇습니다 ! 프로그램하는 모든 사람들은 포인터와 간접적 인 이해를 이해해야합니다.

포인터는 모든 언어에서 대량의 데이터 액세스가 수행되는 방식입니다. 포인터는 모든 마이크로 프로세서의 하드웨어 기능입니다. Java, VB 및 C #과 같은 고급 언어는 기본적으로 언어 사용자의 포인터에 대한 참조에 대한 직접 액세스를 차단합니다. 참조는 언어의 메모리 관리 체계를 통해 객체를 참조합니다 (예 : 메타 데이터가있는 포인터 또는 메모리 테이블의 숫자 일 수 있음).

포인터의 작동 방식 을 이해하는 것은 컴퓨터가 실제로 작동하는 방식을 이해하는 데 필수적 입니다. 포인터는 참조보다 유연하고 강력합니다.

예를 들어, 배열이 인덱스 0에서 시작하는 이유는 배열이 실제로 포인터 산술을 위해 단축되기 때문입니다. 포인터가 어떻게 작동하는지에 대한 지식이 없으면 많은 초보 프로그래머는 배열을 얻지 못합니다.

int a, foo[10];
foo[2] = a;

포인터 산술의 2 행은 다음과 같습니다.

*(foo + sizeof(int) * 2) = a;

포인터를 이해하지 않으면 메모리 관리, 스택, 힙 또는 배열을 이해할 수 없습니다! 또한 함수와 객체가 전달되는 방법을 이해하려면 포인터와 역 참조를 이해해야합니다.

TL : DR : 포인터 이해는 컴퓨터가 실제로 작동하는 것을 이해하는 데 필수적 입니다.


2

프로그래머가 실행중인 직접 하드웨어를 덜 다루면서 포인터를 다루어야 할 필요성이 사라 졌다고 생각합니다. 예를 들어, 특수 하드웨어가 가진 640 바이트 메모리 모듈의 시퀀스에 완벽하게 맞는 방식으로 링크 된 목록 데이터 구조를 할당합니다.

포인터를 수동으로 처리하면 오류가 발생하기 쉽고 (메모리 누수 및 악용 가능한 코드로 이어짐) 올바르게 처리하는 데 시간이 많이 걸립니다. 따라서 Java 및 C # 등은 모두 가상 머신 (VM)을 통해 메모리와 포인터를 관리합니다. VM이 지속적으로 개선되고 있지만 이것은 원시 C / C ++를 사용하는 것보다 덜 효율적입니다.

C (및 C ++)는 여전히 고성능 컴퓨팅, 게임 및 임베디드 하드웨어 공간에서 여전히 널리 사용되는 언어입니다. Java의 참조 (포인터와 비슷한 개념) 로의 전환이 매우 쉽고 첫 번째 NullPointerException (실제로 NullReferenceException이라고해야 함)을 보았을 때 길을 잃지 않았으므로 포인터에 대해 배웠습니다. .

포인터가 여전히 많은 데이터 구조를 뒷받침하는 포인터의 개념에 대해 배우는 것이 좋습니다. 그런 다음 NPE와 같은 것이 등장하면 실제로 무슨 일이 일어나고 있는지 알고 있다는 것을 알고 작업하기를 좋아하는 언어를 선택하십시오. .


0

이것이 객관적인 진실입니다.

일부 언어는 직접 메모리 액세스 (포인터)를 지원하지만 일부는 그렇지 않습니다. 각 경우에 대한 적절한 이유가 있습니다.

  1. C 시절에 누군가가 여기에서 말했듯이 자동 메모리 관리는 오늘날처럼 정교하지 않았습니다. 어쨌든 사람들은 그것에 익숙해있었습니다. 당시 훌륭한 프로그래머들은 우리 세대보다 컴퓨터 프로그램에 대해 훨씬 더 깊이 이해했습니다 (21 세). 그들은 메인 프레임에서 펀치 카드와 대기 시간을 사용하여 컴파일 타임을 사용했습니다. 그들은 아마도 코드의 모든 비트가 존재하는 이유를 알고 있었을 것입니다.

  2. C와 같은 언어의 명백한 장점은 프로그램을보다 세밀하게 제어 할 수 있다는 것입니다. 요즘 실제로 언제 필요 합니까? OS 관련 프로그램 및 런타임 환경과 같은 인프라 응용 프로그램을 만들 때만 해당됩니다. 우수하고 빠르고 강력하며 안정적인 소프트웨어를 개발하려면 자동 메모리 관리가 가장 좋은 선택입니다.

  3. 사실 직접 메모리 액세스는 소프트웨어 개발 이력 과정에서 대부분 남용되었습니다. 사람들은 메모리가 누출 된 프로그램을 만들었고 실제로 중복 메모리 할당 때문에 느려졌습니다 (C에서는 모든 단일 할당에 대해 프로세스의 가상 메모리 공간을 확장하는 것이 쉽고 일반적입니다).

  4. 오늘날 가상 머신 / 런타임은 메모리 할당 및 해제에있어 프로그래머의 99 %보다 훨씬 나은 작업을 수행합니다. 또한, 적절한 시간과 장소에 할당 된 메모리를 확보하지 않기 때문에 프로그램에서 원하는 흐름에 추가적인 유연성을 제공합니다.

  5. 지식에 관해서. 프로그래머가 프로그래밍 환경이 어떻게 구현되는지 아는 것이 좋습니다. 가장 작은 세부 사항 일 필요는 없지만 큰 그림입니다.

포인터가 어떻게 작동하는지 아는 것이 흥미 롭다고 생각합니다. 다형성이 어떻게 구현되는지 아는 것과 같습니다. 프로세스가 메모리를 얻는 위치 및 방법 이것들은 개인적으로 항상 나에게 관심이 있었던 것들입니다. 나는 그들이 더 나은 프로그래머가되었다고 솔직하게 말할 수는 있지만, 좋은 프로그래머가되고 싶은 사람에게는 교육적 필요성이라고 말할 수는 없습니다. 어느 쪽이든, 더 많은 것을 아는 것은 종종 일을 더 잘 하게 할 것입니다.

  1. 내가 보는 방법은 Java 또는 C # 또는 이와 유사한 응용 프로그램을 만드는 것이라면 적절한 디자인 및 구현 기술에 중점을 두어야합니다. 테스트 가능한 코드, 깨끗한 코드, 유연한 코드. 그와 같은 순서로.

작은 세부 사항을 모두 모르더라도 만든 사람은 자신이 만든 것을 단순히 더 좋은 것으로 바꿀 수 있기 때문입니다. 적절하고 깨끗하며 테스트 가능한 디자인을 갖추었다면 대개 어려운 일이 아닙니다 (대개 대부분의 작업).

만약 내가 고급 응용 프로그램을 위해 누군가를 고용하려고하는 면접관이라면, 내가 가장 관심을 가질만한 것들이 될 것입니다.

저수준 지식은 보너스입니다. 디버깅하고 때로는 약간 더 나은 솔루션을 만드는 데 좋습니다. 전문적으로 당신을 흥미로운 사람으로 만듭니다. 그것은 당신에게 당신의 직장에서 약간의 존경을 부여합니다.

그러나 오늘날의 세상에서는 성스러운 요구 사항이 아닙니다.


-1

높은 수준의 OO 언어에서 대부분의 실제적인 목적으로 참조를 이해하는 것으로 충분하기 때문에 이러한 언어가 포인터로 참조를 구현하는 방법을 실제로 이해할 필요는 없습니다.

내가 말할 수있는 멋진 포인터 산술을 할 수있는 것보다 훨씬 더 기능적이고 현대적인 다중 패러다임 접근법이 있습니다.

하드웨어와 밀접한 관련이있는 전문 분야를 시도하기 전에 더 다양한 고수준 개념을 먼저 배우고 지사를 넓히기 위해 다양한 디자인의 언어를 배우도록 조언하는 것이 좋습니다.

캐싱 (메모리), SQL 최적화 또는 웹 서버 구성 조정이 거의 노력하지 않고 100 % 이상을 산출 할 수있을 때 웹 서블릿 또는 유사 코드를 5 % 이득으로 미세 최적화하려는 시도가 종종 실패하는 경우가 종종 있습니다. 대부분의 경우 포인터로 조정하는 것이 조기에 최적화 됩니다.


-1

확실히, 훌륭한 프로그래머가 되려면 포인터에 대한 철저한 개념이 필요합니다. 포인터 개념의 이유는 시간 제약으로보다 효율적이고 효과적으로 가치에 직접 액세스 할 수 있기 때문입니다 ...

또한 메모리가 매우 제한된 모바일 응용 프로그램을 고려할 때 며칠 동안 우리는 매우 신중하게 사용해야 사용자의 반응으로 작업이 매우 빨라야합니다.

포인터 개념으로 만 작동하는 Apple의 장치 또는 Objective C 언어를 고려하십시오. 목표 C에 선언 된 모든 변수에는 포인터가 있습니다. Objective C의 위키 를 거쳐야합니다.


오늘날 모바일 앱은 C가 고안 한 일부 데이터 센터보다 더 많은 메모리를 사용할 수 있습니다. 많은 모바일 앱은 포인터없이 Java 또는 html + javascript로 작성됩니다 (참조가 있음). 매우 전문화 된 프로그래머 중 일부만이 기본 OS 계층을 볼 수 있습니다.
Jürgen Strobel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.