변수와 포인터의 차이점은 무엇입니까?


10

OO와 함수형 프로그래밍의 차이점을 설명하는 기사를 읽는 동안 함수 포인터를 발견했습니다. 컴퓨터 과학 학위 (2003 년)를 마치고 얼마 동안 지났기 때문에 메모리를 새로 고칠 포인터를 찾았습니다.

포인터는 메모리 주소에 대한 참조를 포함하는 변수입니다. 그러한 데이터가 존재하는 경우 해당 메모리 주소에 포함 된 데이터를 가리키는 것으로 간주 할 수 있습니다. 또는 기사의 경우와 같이 코드 섹션의 진입 점을 표시하고 해당 코드를 호출하는 데 사용할 수 있습니다.

이것이 변수와 다른 이유는 무엇입니까? 변수는 메모리 주소의 기호 이름이며 컴파일러는 이름을 실제 주소로 바꿉니다. 이는 변수에 메모리 위치에 대한 참조가 포함되며 해당 데이터가있는 경우 해당 주소의 데이터를 가리키는 것으로 간주 될 수 있습니다.

차이가있는 경우 (런타임에 포인터를 재 할당 할 수 없거나 다른 값이 아닌 기호 변수 이름 만 할당 할 수 있음) 이것이 특정 유형의 변수 인 포인터 유형을 의미하지 않습니까? 마찬가지로 정수 유형으로 선언 된 변수는 컴파일에 의해 사용될 수있는 것으로 제한됩니다.

내가 여기서 무엇을 놓치고 있습니까?


4
포인터는 사실상 변수의 내용이 주소라는 의미 론적 해석 인 유형입니다. 물론 두 개의 주소가 있으며 포인터의 주소 (예 : 변수가 저장된 위치)와 포인터가 참조하는 주소 (변수의 주소에있는 실제 데이터)가 있습니다. 포인터는 참조 유형입니다 .
Luke Mathieson

답변:


8

귀하의 질문은 여러 가지 문제에 대해 신중한 구분이 필요하기 때문에 여러 가지면에서 흥미 롭습니다. 그러나 당신의 비전은 본질적으로 올바른 것 같습니다. 내 답변을 편견을 피하기 위해이 답변을 대부분 작성하기 전에 참조를 읽지 않았습니다.

첫째, 귀하의 진술 Variables are symbolic names for memory addresses은 거의 정확하지만 개념과 일반적인 구현을 혼동합니다. 변수는 실제로 변경할 수있는 값을 포함 할 수있는 컨테이너입니다. 일반적으로,이 컨테이너는 컴퓨터에 메모리 공간의 블록으로 구현되며, 변수는 정보가 많거나 적은 표현이 필요한 객체를 포함 할 수 있으므로 주소 와 크기가 특징 입니다.

그러나 나는 구현 기법과는 별도로 언어의 의미론에 대해 더 추상적 인 관점을 고려할 것입니다.

따라서 변수는 추상적 관점에서 컨테이너 일뿐입니다. 이러한 컨테이너에는 이름이 필요하지 않습니다. 그러나 언어에는 종종 식별자를 연관시켜 명명 된 변수가 있으므로 변수의 사용은 식별자로 표시 할 수 있습니다. 변수는 실제로 다양한 앨리어싱 메커니즘을 통해 여러 식별자를 가질 수 있습니다. 변수는 더 큰 변수의 하위 부분 일 수도 있습니다. 예는 배열 변수의 셀로, 배열 변수와 셀의 인덱스를 지정하여 이름을 지정할 수 있지만 앨리어싱을 통해 식별자와 연결될 수도 있습니다.

의미 적으로로드 될 수있는 다른 단어를 호출하지 않도록 의도적으로 다소 중립적 인 단어 컨테이너 를 사용하고 있습니다. 실제로 는 wilipedia에 설명 된 참조 개념과 비슷 하며 종종 메모리 주소와 혼동됩니다. 단어 포인터 자체 는 종종 메모리 주소로 이해되지만, 대부분의 고급 언어를 고려할 때 의미가 있다고 생각하지 않으며, 부적절하게 부적절하기 때문에 참조하는 토론 논문에서 부적절 할 수 있습니다 (주소가 사용될 수는 있지만). 특정 구현을 참조하십시오. 그러나 C와 같은 언어에는 구현 개념 및 기계 아키텍처에 훨씬 더 가까운 언어에 적합합니다.

실제로, 구현 레벨에서 변수 또는 값을 보면, "머신 레벨 포인터"의 몇 가지 복잡한 간접 시스템이있을 수 있지만, 사용자에게 보이지 않는 추상적 인 관점이 있습니다. 개발할 수 있습니다. 대부분의 프로그래밍 언어의 경우 사용자는 구현에 대해 걱정하거나 알 필요가 없습니다. 구현에 따라 구현 언어가 크게 다를 수 있습니다. 명시 적으로 이진 코딩과 거의 직접적인 관련이있는 어셈블리 언어를 대체하는 고급 언어로, 기계 아키텍처에 의도적으로 가까운 C와 같은 일부 언어의 경우에는 사실이 아닐 수 있습니다. 상황.

언어 사용자가 알아야 할, 때로는 그보다 더 작아야하는 것은 값과 관련 작업, 포함 할 수있는 위치, 이름과 연결될 수있는 방법, 명명 시스템 작동 방법, 새로운 방법 값의 종류 등 정의

따라서 또 다른 중요한 개념은 식별자와 명명입니다. 엔터티 (값)의 이름 지정은 식별자를 값 (일반적으로 선언)과 연결하여 수행 할 수 있습니다. 그러나 다른 명명 된 값에 연산을 적용하여 값을 얻을 수도 있습니다. 이름을 재사용 할 수 있으며 사용 컨텍스트에 따라 주어진 식별자와 관련된 항목을 결정하는 규칙 (범위 지정 규칙)이 있습니다. 정수 (예 : 정수)와 같은 일부 도메인 값의 이름을 지정하기 위해 리터럴이라고하는 특수 이름도 있습니다.612) 또는 부울 (예 : true )입니다.

변하지 않는 값과 식별자를 연관시키는 것을 보통 상수라고합니다. 리터럴은 그런 의미에서 상수입니다.

"값 컨테이너"는 값으로 간주 될 수 있으며 식별자와의 연관은 일반적으로 "순진한"의미의 변수입니다. 따라서 변수가 "컨테이너 상수"라고 말할 수 있습니다.

이제 식별자를 값과 연결 (일정한 선언)하거나 변수에 값을 할당하는 것, 즉 컨테이너 상수로 정의 된 컨테이너에 값을 저장하는 것의 차이점이 무엇인지 궁금 할 것입니다. 본질적으로 선언은 구문 엔티티 인 식별자를 의미 엔티티 인 값과 연관시키는 표기법을 정의하는 오퍼레이션으로 볼 수 있습니다. 할당은 상태를 수정하는, 즉 컨테이너의 값을 수정하는 순수한 의미 론적 작업입니다. 어떤 의미에서, 선언은 의미 론적 엔티티에 대한 명명 메커니즘을 제공하는 것 외에 의미 론적 효과가없는 메타 개념이다.

실제로, 할당은 프로그램이 실행될 때 동적으로 발생하는 의미 론적 연산 인 반면, 선언은보다 구문적인 특성을 가지며 일반적으로 실행과 관계없이 프로그램의 텍스트에서 해석됩니다. 이것이 정적 범위 지정 (즉, 텍스트 범위 지정)이 일반적으로 식별자의 의미를 이해하는 자연스러운 방법 인 이유입니다.

결국, 포인터 값은 컨테이너의 또 다른 이름이고 포인터 변수는 컨테이너 변수, 즉 다른 컨테이너를 포함 할 수있는 컨테이너 (일정한) 컨테이너라고 할 수 있습니다 (일부에서 부과하는 게임에 제한이 있음) 유형 시스템).

코드와 관련하여 [pointers] might indicate the entry point to a section of code and can be used to call that code. 실제로 이것은 사실이 아닙니다. 코드 섹션은 종종 (무상 또는 구현 관점에서) 단독으로 무의미합니다. 높은 수준의 관점에서 볼 때 코드에는 일반적으로 식별자가 포함되어 있으며 이러한 식별자는 선언 된 정적 컨텍스트에서 이러한 식별자를 해석해야합니다. 그러나 본질적으로 동적 (런타임) 현상 인 재귀로 인해 동일한 정적 컨텍스트가 중복 될 수 있으며 정적 컨텍스트의 적절한 동적 인스턴스에서만 코드를 실행할 수 있습니다. 이것은 약간 복잡하지만 그 결과 올바른 개념은 코드 조각과 식별자를 해석 할 환경을 연결하는 클로저 개념이라는 것입니다. 클로저는 올바른 의미 론적 개념, 즉 적절하게 정의 가능한 의미 론적 가치입니다. 그런 다음 클로저 상수, 클로저 변수,

함수는 일반적으로 일부 엔티티 (상수 및 변수)를 정의하거나 초기화하기위한 일부 매개 변수가있는 클로저입니다.

이 메커니즘의 사용에 대한 많은 변형을 건너 뜁니다.

클로저는 명령형 또는 기능적 언어로 OO 구조를 정의하는 데 사용할 수 있습니다. 실제로, OO 스타일 (아마도 이름 이전)에 대한 초기 작업은 그렇게 이루어졌습니다.

내가 빨리 훑어 본 참고 문헌은 유능한 사람이 작성한 흥미로운 것으로 보이지만 다양한 언어와 기본 계산 모델에 대한 상당한 경험이 없으면 쉽게 읽을 수 없습니다.

그러나 일관된 견해를 유지하는 한 많은 것들이 보는 사람의 눈에 있습니다. 관점이 다를 수 있습니다.

이것이 귀하의 질문에 대답합니까?

추신 : 이것은 긴 답변입니다. 그 중 일부가 부적절하다고 생각되면 어떤 부분인지 명시하십시오. 감사합니다.


나는 그것을 몇 번 읽어야했지만 내 질문에 대답한다고 생각합니다. 내 정의가 너무 구현 중심이지만, 포인터 변수의 특정 유형이 있다는 생각은, 즉 정확한 것 같다 "포인터 값이 컨테이너의 또 다른 이름이며, 포인터 변수는 컨테이너 변수" 내가하지 코드 블록의 주소를 포함하는 포인터와 클로저를 포함하는 컨테이너를 포함하는 컨테이너 사이의 구별을 얻으십시오. 정적 컨텍스트와 실행중인 프로그램의 차이점이 있습니까?
NectarSoft

1
@NectarSoft 구별은 코드 블록과 클로저 사이에만 있습니다. 내가 말하는 것은 그 자체로 어떤 맥락에서도 분리되어 있기 때문에 코드 블록은 대개 아무것도 의미하지 않는다는 것입니다. " 모메의 분노가 보르고 브보다 크면, 토브는 빠져 나간다 "고 말하면,이 모든 개념이 정의 된 문맥을 놓치므로 문장은 아무 의미가 없습니다. 이 정적 컨텍스트는 일반적으로 코드 조각을 둘러싸는 텍스트입니다. 문제는이 정적 컨텍스트 자체에 여러 런타임 인스턴스가있을 수 있으며 코드 조각은 그 중 하나만 참조해야한다는 것입니다.
babou

1
@NectarSoft (계속) 따라서 클로저 값은 코드 단편과이 단편에 의미를 부여하는 정적 컨텍스트의 동적 인스턴스의 연관입니다. 동일한 코드 조각을 동일한 정적 컨텍스트의 다른 동적 인스턴스와 연결하면 다른 폐쇄가 발생합니다. 일반적으로 코드는 컨텍스트에 속하는 변수를 사용할 수 있지만 해당 이름 (정적으로 정의 된)은 동일하게 유지되지만 컨텍스트의 각 동적 인스턴스에 대해 다른 변수가됩니다. 이것이 문제를 분명히합니까, 아니면 답변으로 예제를 작성해야합니까 (주석 형식이 제한되어 있습니까)?
babou

생각하기 위해 시간을 할애 할 다른 질문을 제기하면서 문제를 분명히합니다. 예를 들어, 각 클로저마다 별개의 포인터가 필요한 경우, 포인터는 동적 컨텍스트의 일부가되어 클로저 내에 속합니다! 또한 정적 코드 블록과 관련되고 포인터로 참조되는 이러한 각 컨텍스트는 필연적으로 자체 폐쇄의 변수이므로 폐쇄 경계 및 폐쇄 계층에 대해 궁금합니다. 그러나이 모든 것은 주제를 벗어난 것이므로 약간의 독서를하고 아마도 다시 한 번
멈출

@NectarSoft 실제로. 클로저를 작성할 때 코드와 관련된 컨텍스트를 해당 코드에 적절한 의미를 부여하는 데 필요한 것 (마이크로 관리 정보를 피하기위한 실제 제약 조건까지)으로 제한하려고합니다. 이것은 정적으로 결정될 수 있습니다.
babou

2

차이점은 정의와 응용에 따라 포인터는 다른 변수의 메모리 주소를 보유하는 특수 변수입니다. OO 용어에서 포인터는 variable이라는 일반 클래스에서 동작을 상속하는 것으로 간주됩니다.

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