포인터 (컴퓨터 프로그래밍)
AdaEdit
Ada는 모든 포인터가 입력되고 안전한 형식 변환 만 허용되는 강력한 형식의 언어입니다. 모든 포인터는 기본적으로 null
로 초기화되며 null
포인터를 통해 데이터에 액세스하려고하면 예외가 발생합니다. Ada의 포인터를 액세스 유형이라고합니다. Ada 83은 액세스 유형에 대한 산술을 허용하지 않았지만 (많은 컴파일러 공급 업체가 비표준 기능으로 제공했지만) Ada 95는 패키지 System.Storage_Elements
.
BASICEdit
Windows 플랫폼 용 BASIC의 일부 이전 버전은 문자열 주소를 반환하는 STRPTR () 및 주소를 반환하는 VARPTR ()을 지원했습니다. Visual Basic 5는 또한 개체 인터페이스의 주소를 반환하는 OBJPTR ()과 함수의 주소를 반환하는 ADDRESSOF 연산자를 지원했습니다. 이러한 유형은 모두 정수이지만 해당 값은 다음과 같습니다. 포인터 유형에 의해 보유됩니다.
FreeBASIC 또는 BlitzMax와 같은 BASIC의 새로운 방언에는 완전한 포인터 구현이 있습니다. FreeBASIC에서는 ANY
포인터에 대한 산술 ( C “의 void*
와 동일)은 ANY
포인터가 바이트 너비 인 것처럼 처리됩니다. ANY
포인터는 C에서와 같이 역 참조 될 수 없습니다. 또한 ANY
와 다른 유형의 포인터간에 캐스팅해도 경고가 생성되지 않습니다.
dim as integer f = 257dim as any ptr g = @fdim as integer ptr i = gassert(*i = 257)assert( (g + 4) = (@f + 1) )
C 및 C ++ Edit
C 및 C ++에서 포인터는 주소를 저장하고 null 일 수 있습니다. 각 포인터에는 가리키는 유형이 있지만 포인터 유형간에 자유롭게 캐스트 할 수 있습니다 (함수 포인터와 개체 포인터 간에는 변환되지 않음). “void pointer”라는 특수 포인터 유형을 사용하면 -function) 객체이지만 직접 역 참조 할 수 없다는 사실에 의해 제한됩니다 (캐스트되어야 함). 주소 자체는 종종 충분한 크기의 정수 유형으로 포인터를 캐스트하여 직접 조작 할 수 있지만 결과는 구현에 의해 정의되고 실제로 정의되지 않은 동작을 유발할 수 있습니다. 이전 C 표준에는 충분히 큰 정수 유형이 없었지만 C99는 <stdint.h>
에 정의 된 uintptr_t
typedef 이름을 지정합니다. 그러나 구현시이를 제공 할 필요는 없습니다.
C ++는 C 포인터와 C 형변환을 완벽하게 지원합니다. 또한 컴파일 타임에 의도하지 않은 위험한 캐스트를 포착하는 데 도움이되는 새로운 유형 캐스팅 연산자 그룹을 지원합니다. C ++ 11부터 C ++ 표준 라이브러리는 스마트 포인터 (unique_ptr
, shared_ptr
및 weak_ptr
) 기본 C 포인터에 대한 안전한 대안으로 일부 상황에서 사용할 수 있습니다. C ++는 또한 단순히 참조 또는 참조 유형이라고하는 포인터와는 다른 참조 형식을 지원합니다.
포인터 산술, 즉 산술 연산을 사용하여 포인터의 대상 주소를 수정하는 기능입니다. 크기 비교)는 언어 표준에 의해 단일 배열 객체 (또는 그 바로 뒤에)의 범위 내에 유지되도록 제한되며 그렇지 않으면 정의되지 않은 동작을 호출합니다. 포인터에서 더하거나 빼면 크기의 배수만큼 이동합니다. 예를 들어, 4 바이트 정수 값에 대한 포인터에 1을 추가하면 포인터의 가리키는 바이트 주소가 4만큼 증가합니다. 이는 포인터가 연속 된 다음 요소를 가리 키도록 증가시키는 효과가 있습니다. 종종 의도 된 결과 인 정수 배열. gcc 및 기타 컴파일러가 iv에서 바이트 산술을 수행하지만 void 유형에 크기가 없으므로 포인터 산술을 void
포인터에서 수행 할 수 없습니다. 따라서 지정된 주소를 추가 할 수 없습니다. id = “2adc86b4af”> 는 비표준 확장으로, char *
인 것처럼 처리합니다.
포인터 산술은 프로그래머에게 다른 유형을 처리하는 단일 방법 : 바이트 단위의 실제 오프셋 대신 필요한 요소 수를 더하고 빼는 것입니다. (char *
포인터가있는 포인터 산술은 바이트 오프셋을 사용합니다. sizeof(char)
는 정의에 따라 1이기 때문입니다.) 특히 C 정의는 다음과 같이 명시 적으로 선언합니다. 구문 a
(배열 a
의 n
-번째 요소)는 동일합니다. *(a + n)
로, a + n
가 가리키는 요소의 내용입니다. 이는 n
가 a
와 동일하며 a
와 같이 쓸 수 있음을 의미합니다. 또는 3
도 마찬가지로 배열의 네 번째 요소 a
에 액세스 할 수 있습니다.
강력하지만 포인터 산술은 컴퓨터 버그의 원인이 될 수 있습니다. 초보 프로그래머를 혼동하여 다른 컨텍스트로 강제하는 경향이 있습니다. 표현식은 일반 산술 또는 포인터 산술 일 수 있으며 때로는 하나를 다른 것으로 착각하기 쉽습니다. 이에 대응하여 많은 최신 고급 컴퓨터 언어 (예 : Java)는 주소를 사용하여 메모리에 직접 액세스하는 것을 허용하지 않습니다. 또한 안전한 C dialect Cyclone은 포인터와 관련된 많은 문제를 해결합니다. 자세한 내용은 C 프로그래밍 언어를 참조하십시오.
void
포인터 또는 void*
는 ANSI C에서 지원되며 일반 포인터 유형으로서의 C ++. void
에 대한 포인터는 모든 객체 (함수 아님)의 주소를 저장할 수 있으며 C에서는 할당시 다른 객체 포인터 유형으로 암시 적으로 변환되지만 명시 적으로 캐스트되어야합니다. 만약 dereferenced.K & RC는 “유형에 구애받지 않는 포인터”용도로 char*
를 사용했습니다 (ANSI C 이전).
C ++는 할당에서도 void*
를 다른 포인터 유형으로 묵시적으로 변환하는 것을 허용하지 않습니다. 대부분의 컴파일러는 경고 만 출력하지만 부주의하고 의도하지 않은 캐스트를 피하기위한 설계 결정이었습니다. , 다른 캐스트가 발생할 때 오류가 아닙니다.
C ++에는 void*
void& (void에 대한 참조)가 없습니다. / div> (void에 대한 포인터), 참조가 가리키는 변수에 대한 별칭처럼 동작하기 때문이며 유형이 void
인 변수는있을 수 없습니다.
포인터 선언 구문 개요 편집
이 포인터 선언 c 대부분의 포인터 선언 변형에 대해. 물론 트리플 포인터를 가질 수도 있지만 트리플 포인터의 기본 원칙은 이미 더블 포인터에 존재합니다.
()는 *보다 우선 순위가 높습니다.
C # Edit
C # 프로그래밍 언어에서 포인터는 특정 조건에서만 지원됩니다. 포인터를 포함한 모든 코드 블록은 unsafe
키워드로 표시되어야합니다. 이러한 블록은 일반적으로 실행을 허용하기 위해 더 높은 보안 권한을 필요로합니다. 그러나 관리되는 메모리에 대한 포인터 (관리되는 개체에 대한 모든 포인터)는 fixed
키워드를 사용하여 선언해야합니다. 이렇게하면 가비지 수집기가 가리키는 개체를 메모리 관리의 일부로 이동하는 것을 방지 할 수 있습니다. 포인터가 범위 내에 있으므로 포인터 주소를 유효하게 유지합니다.
예외는 IntPtr
구조를 사용하는 것입니다. id = “505bd537d5”> 이며 안전하지 않은 코드가 필요하지 않습니다. 이 유형은 System.Runtime.InteropServices
의 메소드를 사용할 때 종종 반환됩니다. 예를 들면 다음과 같습니다.
.NET 프레임 워크에는 및 System.Runtime.InteropServices
네임 스페이스 (예 : Marshal
클래스) (예 : System.String
) 여러 관리되지 않는 유형 및 포인터 (예 : LPWSTR
또는 void*
)간에 비 관리 코드와의 통신. 대부분의 이러한 메서드는 메모리의 임의 위치에 영향을 줄 수 있으므로 관리되지 않는 코드와 동일한 보안 권한 요구 사항을 갖습니다.
COBOLEdit
COBOL 프로그래밍 언어는 변수에 대한 포인터를 지원합니다. 프로그램의 LINKAGE SECTION
내에서 선언 된 기본 또는 그룹 (레코드) 데이터 개체는 본질적으로 포인터 기반이며, 프로그램 내에서 할당되는 유일한 메모리는 데이터 항목의 주소를위한 공간입니다 ( 일반적으로 단일 메모리 단어). 프로그램 소스 코드에서 이러한 데이터 항목은 다른 WORKING-STORAGE
변수와 마찬가지로 사용되지만 해당 콘텐츠는 LINKAGE
포인터를 통해 간접적으로 암시 적으로 액세스됩니다. .
각 데이터 객체의 메모리 공간은 일반적으로 외부 CALL
문을 사용하거나 또는 EXEC SQL
문.
COBOL의 확장 된 버전은 USAGE
로 선언 된 포인터 변수도 제공합니다. IS
POINTER
절. 이러한 포인터 변수의 값은 SET
및 SET
ADDRESS
문을 사용하여 설정 및 수정됩니다.
일부 확장 버전의 COBOL은 실행 코드의 주소를 저장할 수있는 PROCEDURE-POINTER
변수도 제공합니다.
PL / IEdit
PL / I 언어는 모든 데이터 유형 (구조에 대한 포인터 포함)에 대한 포인터, 재귀, 멀티 태스킹, 문자열 처리 및 광범위한 내장 함수를 완벽하게 지원합니다.PL / I는 당시의 프로그래밍 언어에 비해 상당히 도약했습니다. PL / I 포인터는 유형이 지정되지 않으므로 포인터 역 참조 또는 할당에 캐스팅이 필요하지 않습니다. 포인터에 대한 선언 구문은 “xxx”라는 포인터를 선언하는 DECLARE xxx POINTER;
입니다. 포인터는 BASED
변수와 함께 사용됩니다. 기반 변수는 기본 로케이터 (DECLARE xxx BASED(ppp);
를 사용하거나 사용하지 않고 (DECLARE xxx BASED;
)) 선언 할 수 있습니다. 여기서 xxx는 기반 변수입니다. 요소 변수, 구조 또는 배열이며 ppp는 기본 포인터입니다). 이러한 변수는 명시 적 포인터 참조 (xxx=1;
)가없는 주소이거나 기본 로케이터 (ppp) 또는 다른 포인터 (qqq->xxx=1;
).
포인터 산술은 PL / I 표준의 일부가 아니지만 많은 컴파일러에서 ptr = ptr±expression
형식의 표현식을 허용합니다. . IBM PL / I에는 또한 산술을 수행하는 내장 함수 PTRADD
가 있습니다. 포인터 산술은 항상 바이트 단위로 수행됩니다.
IBM Enterprise PL / I 컴파일러에는 HANDLE
라는 새로운 형식의 포인터.
DEdit
D 프로그래밍 언어는 C를 완전히 지원하는 C 및 C ++의 파생어입니다. 포인터 및 C 형변환.
EiffelEdit
Eiffel 객체 지향 언어는 포인터 산술없이 값 및 참조 의미를 사용합니다. 그럼에도 불구하고 포인터 클래스가 제공됩니다. 포인터 산술, 형변환, 명시 적 메모리 관리, int 비 -Eiffel 소프트웨어 및 기타 기능을 사용합니다.
FortranEdit
Fortran-90은 강력한 형식의 포인터 기능을 도입했습니다. Fortran 포인터는 단순한 메모리 주소 이상을 포함합니다. 또한 배열 차원, 스트라이드 (예 : 임의 배열 섹션 지원) 및 기타 메타 데이터의 하한 및 상한을 캡슐화합니다. 연결 연산자 인 =>
는 POINTER
를 TARGET
속성. Fortran-90 ALLOCATE
문을 사용하여 포인터를 메모리 블록에 연결할 수도 있습니다. 예를 들어 다음 코드를 사용하여 연결 목록 구조를 정의하고 만들 수 있습니다.
Fortran-2003은 프로 시저 포인터에 대한 지원을 추가합니다. 또한 C 상호 운용성 기능의 일부로 Fortran-2003은 C 스타일 포인터를 Fortran 포인터로 변환하는 내장 함수를 지원합니다.
GoEdit
Go에는 포인터가 있습니다. 선언 구문은 C의 구문과 동일하지만 다른 방식으로 작성되어 유형으로 끝납니다. C와 달리 Go에는 가비지 컬렉션이 있으며 포인터 산술을 허용하지 않습니다. C ++에서와 같은 참조 유형은 존재하지 않습니다. 맵 및 채널과 같은 일부 내장 유형은 박스형이며 (즉, 내부적으로는 변경 가능한 구조에 대한 포인터) make
함수를 사용하여 초기화됩니다. 포인터와 비 포인터 간의 통합 구문에 대한 접근 방식에서 화살표 (->
) 연산자가 삭제되었습니다. 포인터의 점 연산자는 역 참조 된 개체의 필드 또는 메서드를 나타냅니다. . 그러나 이것은 1 단계의 간접적 수준에서만 작동합니다.
JavaEdit
C, C ++ 또는 Pascal과 달리 Java에서는 포인터를 명시 적으로 표현하지 않습니다. 대신 객체 및 배열과 같은 더 복잡한 데이터 구조는 참조를 사용하여 구현됩니다. 이 언어는 명시 적 포인터 조작 연산자를 제공하지 않습니다. 코드가 널 참조 (널 포인터)를 역 참조하려고 시도하는 것은 여전히 가능하지만 이로 인해 런타임 예외가 발생합니다. 참조되지 않은 메모리 개체가 차지하는 공간은 런타임에 가비지 수집에 의해 자동으로 복구됩니다.
Modula-2Edit
포인터는 VAR
매개 변수. Modula-2는 Pascal보다 훨씬 더 강력한 유형이며 유형 시스템을 이스케이프하는 방법이 적습니다. Modula-2의 일부 변형 (예 : Modula-3)에는 가비지 컬렉션이 포함됩니다.
OberonEdit
Modulla-2와 마찬가지로 포인터를 사용할 수 있습니다. 유형 시스템을 회피하는 방법은 여전히 적으므로 Oberon과 그 변형은 Modula-2 또는 그 변형보다 포인터와 관련하여 여전히 더 안전합니다. Modula-3와 마찬가지로 가비지 컬렉션은 언어 사양의 일부입니다.
PascalEdit
포인터가있는 많은 언어와 달리 표준 ISO Pascal은 포인터가 동적으로 생성 된 변수를 참조하도록 허용합니다. 익명이며 표준 정적 또는 지역 변수를 참조 할 수 없습니다. 포인터 산술이 없습니다. 포인터는 또한 연관된 유형을 가져야하며 한 유형에 대한 포인터는 다른 유형에 대한 포인터와 호환되지 않습니다 (예 : char에 대한 포인터는 정수에 대한 포인터와 호환되지 않음).이는 다른 포인터 구현, 특히 PL / I 또는 C에 사용되는 것과 같은 고유 한 유형 보안 문제를 제거하는 데 도움이됩니다. 또한 댕글 링 포인터로 인한 일부 위험을 제거하지만 dispose
표준 프로 시저 (C에있는 free
라이브러리 함수와 동일한 효과를 가짐)는 댕글 링 포인터의 위험이 완전히 제거되지 않았 음을 의미합니다.
그러나 일부 상용 및 오픈 소스 Pascal (또는 파생) 컴파일러 구현 (예 : Free Pascal, Turbo Pascal 또는 Embarcadero Delphi의 Object Pascal)에서는 포인터가 표준 정적 또는 로컬 변수를 참조 할 수 있으며 한 포인터 유형에서 다른 유형으로 캐스트. 또한 포인터 산술은 제한이 없습니다. 포인터에서 더하거나 빼면 어느 방향 으로든 해당 바이트 수만큼 이동하지만 Inc
또는 Dec
표준 프로시 저는 포인터가 가리키는 데이터 유형의 크기만큼 포인터를 이동합니다. 다른 포인터 유형과 호환되는 Pointer
이름 아래에 유형이 지정되지 않은 포인터도 제공됩니다.