태그 보관물: c#

c#

어린 마음이 포인터 개념을 배워야합니까? 이유는 무엇 입니까? 그리고

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 #에 포인터가 포함되어 있지 않습니다.

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



답변

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

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

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

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

질문에 답하기 위해

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

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

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

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


답변

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

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

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

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

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

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

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

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


답변

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

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

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

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

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


답변

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

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

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


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

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


답변

예, 이해가 중요합니다.

몇 달 전에 저는 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

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


답변

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

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


답변

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) { /* ... */ })

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