ポインター(コンピュータープログラミング)
AdaEdit
Adaは強く型付けされた言語であり、すべてのポインターが型付けされ、安全な型変換のみが許可されます。すべてのポインタはデフォルトでnull
に初期化され、null
ポインタを介してデータにアクセスしようとすると例外が発生します。 Adaのポインタはアクセスタイプと呼ばれます。 Ada 83はアクセスタイプの演算を許可しませんでしたが(多くのコンパイラベンダーが非標準機能として提供していましたが)、Ada95はパッケージ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 ++編集
CおよびC ++では、ポインターはアドレスを格納する変数であり、 nullにすることができます。各ポインターにはそれが指す型がありますが、ポインター型間で自由にキャストできます(ただし、関数ポインターとオブジェクトポインター間ではできません)。「voidポインター」と呼ばれる特別なポインター型を使用すると、任意の( -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ずつ増加します。これには、連続する次の要素を指すようにポインタを増加させる効果があります。整数の配列-これは多くの場合、意図した結果です。 void型にはサイズがないため、void
ポインターではポインター演算を実行できません。したがって、gccや他のコンパイラーは
を非標準の拡張機能として扱い、char *
であるかのように扱います。
ポインタ演算により、プログラマはさまざまなタイプを処理する単一の方法:バイト単位の実際のオフセットの代わりに、必要な要素の数を加算および減算します。 (char *
ポインターを使用したポインター演算では、バイトオフセットが使用されます。これは、sizeof(char)
が定義上1であるためです。)特に、C定義では、構文a
は、配列a
のn
番目の要素です。 *(a + n)
に移動します。これは、a + n
が指す要素のコンテンツです。これは、n
がa
と同等であり、たとえばa
と書くことができることを意味します。または3
も同様に、配列の4番目の要素a
にアクセスします。
強力ですが、ポインタ演算はコンピュータのバグの原因となる可能性があります。初心者のプログラマーを混乱させ、異なるコンテキストに強制する傾向があります。式は通常の算術式またはポインター算術式であり、一方を他方と間違えやすい場合があります。これに対応して、多くの最新の高級コンピュータ言語(Javaなど)は、アドレスを使用したメモリへの直接アクセスを許可していません。また、安全なC方言Cycloneは、ポインターに関する多くの問題に対処します。詳細については、Cプログラミング言語を参照してください。
void
ポインタまたはvoid*
は、ANSICおよびジェネリックポインタ型としてのC ++。 void
へのポインタは、任意のオブジェクト(関数ではない)のアドレスを格納でき、Cでは、割り当て時に他のオブジェクトポインタタイプに暗黙的に変換されますが、明示的にキャストする必要がありますdereferenced.K & RCは、「タイプに依存しないポインタ」の目的でchar*
を使用しました(ANSI Cより前)。
C ++では、割り当てであっても、void*
を他のポインタ型に暗黙的に変換することはできません。これは、不注意なキャストや意図しないキャストを回避するための設計上の決定ですが、ほとんどのコンパイラは警告のみを出力します。 、エラーではなく、他のキャストに遭遇した場合。
C ++では、void*
void&(voidへの参照)はありません。 / div>(voidへのポインタ)。参照は、参照する変数のエイリアスのように動作し、タイプがvoid
の変数は存在しないためです。
ポインタ宣言構文overviewEdit
これらのポインタ宣言cポインタ宣言のほとんどのバリアントに対して。もちろん、トリプルポインターを持つことは可能ですが、トリプルポインターの背後にある主な原則は、すでにダブルポインターに存在します。
()は、*よりも優先されます。
C#Edit
C#プログラミング言語では、ポインターは特定の条件下でのみサポートされます。ポインターを含むコードのブロックは、unsafe
キーワードでマークする必要があります。このようなブロックを実行するには、通常、より高いセキュリティ権限が必要です。構文は基本的にC ++と同じであり、指定されたアドレスはマネージメモリまたはアンマネージメモリのいずれかです。ただし、マネージメモリへのポインタ(マネージオブジェクトへのポインタ)は、fixed
キーワードを使用して宣言する必要があります。これにより、ガベージコレクタがメモリ管理の一部としてポイントされたオブジェクトを移動するのを防ぎます。ポインタはスコープ内にあるため、ポインタアドレスは有効に保たれます。
これに対する例外は、IntPtr
構造を使用することです。これは
であり、安全でないコードは必要ありません。このタイプは、System.Runtime.InteropServices
のメソッドを使用するときに返されることがよくあります。例:
.NET Frameworkには、およびSystem.Runtime.InteropServices
名前空間(Marshal
クラスなど)。.NETタイプ(たとえば、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ポインターは型指定されていないため、ポインターの逆参照または割り当てにキャストは必要ありません。ポインタの宣言構文はDECLARE xxx POINTER;
で、「xxx」という名前のポインタを宣言します。ポインタはBASED
変数で使用されます。ベース変数は、デフォルトのロケーター(DECLARE xxx BASED(ppp);
またはなし(DECLARE xxx BASED;
)で宣言できます。ここで、xxxはベース変数です。要素変数、構造体、または配列。pppがデフォルトのポインターです)。このような変数は、明示的なポインター参照なしでアドレス指定できます(xxx=1;
、またはデフォルトのロケーター(ppp)または他のポインターへの明示的な参照でアドレス指定できます(qqq->xxx=1;
)。
ポインタ演算はPL / I標準の一部ではありませんが、多くのコンパイラではptr = ptr±expression
の形式の式を使用できます。 。IBMPL/ 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ではポインターの明示的な表現はありません。代わりに、オブジェクトや配列などのより複雑なデータ構造が参照を使用して実装されます。この言語は、明示的なポインター操作演算子を提供していません。コードがnull参照(nullポインター)を逆参照しようとする可能性はありますが、その結果、実行時例外がスローされます。参照されていないメモリオブジェクトが占めるスペースは、実行時にガベージコレクションによって自動的に回復されます。
Modula-2Edit
ポインタは、VAR
パラメータ。 Modula-2はPascalよりもさらに強く型付けされており、型システムから逃れる方法が少なくなっています。 Modula-2のバリアントの一部(Modula-3など)にはガベージコレクションが含まれています。
OberonEdit
Modula-2と同様に、ポインターを使用できます。型システムを回避する方法はまだ少ないので、Oberonとそのバリアントは、Modula-2またはそのバリアントよりもポインターに関して安全です。 Modula-3と同様に、ガベージコレクションは言語仕様の一部です。
PascalEdit
ポインターを備えた多くの言語とは異なり、標準のISO Pascalでは、ポインターが動的に作成された変数のみを参照できます。匿名であり、標準の静的変数またはローカル変数を参照することはできません。ポインタ演算はありません。ポインタにもタイプが関連付けられている必要があり、あるタイプへのポインタは別のタイプへのポインタと互換性がありません(たとえば、charへのポインタは整数へのポインタと互換性がありません)。これは、他のポインター実装、特にPL / IまたはCに使用されるものに固有の型セキュリティの問題を排除するのに役立ちます。また、ポインターのぶら下がりによって引き起こされるいくつかのリスクを取り除きますが、dispose
標準手順(Cにあるfree
ライブラリ関数と同じ効果があります)は、ポインタがぶら下がるリスクが完全に排除されていないことを意味します。
ただし、Free Pascal、Turbo Pascal、EmbarcaderoDelphiのObjectPascalなど、一部の商用およびオープンソースのPascal(または派生)コンパイラ実装では、ポインタは標準の静的変数またはローカル変数を参照できます。あるポインタ型から別の型へのキャスト。さらに、ポインタ演算には制限がありません。ポインタを加算または減算すると、そのバイト数だけいずれかの方向に移動しますが、Inc
またはDec
標準プロシージャを使用すると、ポインタは、指すように宣言されているデータ型のサイズだけ移動します。型なしポインターもPointer
という名前で提供され、他のポインタータイプと互換性があります。