4

ジョブにポインターが必要になるケースや具体的な例はありますか? つまり、ポインターを使用せずにポインターを必要とする何かを実行できますか? ポインターを関数パラメーターとして送信できますが、それは返されたデータで行うことができます。ポインターを使用して関数内の複数の変数を変更できますが、それにも回避策があります。

実際にポインターが必要ですか?

ばかげた質問だと思いますが、状況によっては正しいように思えますが、ポインターを使用してできないことがあるかどうかを知りたいだけです。

4

5 に答える 5

5

高水準言語のパラダイムの設計ではポインターを避けることができます (Java を例に挙げます) が、言語が提供すると主張する機能の実際の実用的な実装では、ポインターが再び現れる傾向があります。

ある種の動的に再構成する FPGA アーキテクチャ、ステート マシンのコロニー、または同様のアイデアをコンピューターとして使用していない限り、実際のコンピューティング マシンはあまりオブジェクト指向ではありません。ストレージ デバイスで操作を実行するのではなく、データを取得して計算し、書き戻すだけです。メモリ内のデータを検索するには、アドレスの概念を使用します (連想メモリと呼ばれるものがありますが、ほとんどの場合、それらは好ましくありません)。データ (または関数本体、または両方を含む構造体) がメモリ内のあるアドレスにあると判断したら、そのアドレスをどのように処理するかを理解する必要があります。さらに別のメモリ位置にアドレスを書き込むことができ、最もよく知られているポインターの概念があります。スタックにアドレスを格納することはできますが、それは ' 「スタックポインタ」と呼ばれるレジスタに相対的なストレージです。または、アドレスをレジスタまたは命令ワードに格納することもできます。

しかし、命令語の実際のフォーマットを見ると、重要なプロセッサの「レジスタ」は、実際にはレジスタ ファイルと呼ばれる特別なオンチップ メモリ内の番号付けされた場所です。それらに番号を付けるというRISCの伝統により、これは特に明白になりますが、レジスタに名前が付けられているアセンブリ言語スキームでも当てはまります-MOVまたはその他の命令には、命令のタイプと形式を決定するいくつかのビットと、レジスタをエンコードするいくつかのビットがあります各オペランドの数。したがって、レジスタ間接アドレッシングは、技術的には、別のアドレス、つまりポインタを保持する 1 つのメモリ位置です。同様に、

結論: 高レベルのプログラマーからポインターを隠すことができますが、実装が以下に基づいている限り、

(アドレス可能なデータ メモリ/レジスタ ファイル) <-> CPU -<-> (アドレス可能なプログラム メモリ)

計算のアイデア、実装レベルでそれらを避けることはできません。

于 2012-05-07T16:16:48.863 に答える
1

高水準言語でポインターは必要ですか? 厳密には、チューリングマシンの意味では、いいえ。ただし、実際には、チューリング マシンでコーディングすることはありません。高水準言語でコーディングするため、開発者はコードを書く際の精神的な負荷を軽減するために特定の構成要素を必要とします。ポインターを使用すると、特定の抽象化 (リンクされたリストなど) をより簡単に表現できます。したがって、「必要」という言葉の最も厳密な解釈では答えはノーかもしれませんが、実際には答えはイエスです。

StackOverflow FAQ をお読みください。

于 2012-05-07T16:12:52.867 に答える
1

ポインターを配列の (効率的な)イテレーターとして使用できることは非常に便利だと思います。

たとえば (C99):

ptrdiff_t stride = 8;
double* data = ...;
size_t size = ...;
const double* end = data + size * stride;

for (double* restrict p = data; p < end; p += stride)
    *p = ...;

ポインター演算が意図を表現するのに非常に役立つことがわかります。サブ配列を表すためにポインター + ストライドを渡すことができることも便利です。

一部の言語では、ポインターを使用してデータを操作することは許可されていません (ただし、参照は許可されています)。Cでは、たとえば次のように記述します。

void foo(const double* data, ptrdiff_t stride, size_t size, double* out);

C# では、次のように記述します。

void Foo(double[] data, int stride, double[] output);

しかし今outputでは、他の何かの部分配列ではなく、完全な配列、または 1 つの要素出力の場合の単純なスタック変数であることが強制されます (C# は、本当に必要な場合はポインターを提供しますが、提供しないふりをしましょう)。

于 2012-05-07T16:16:59.670 に答える
0

ポインタの機能は、参照のスーパーセットです。参照を使用して実行できることはすべて、ポインターを使用して実行できます。ポインターは参照よりも強力なツールであるため、Cはポインターを使用します。それは低レベルの強力な言語です。

ジョブのポインタが必要になるケースや具体的な例はありますか

はい、例えばポインタ演算の場合。

//copy string to a buffer
char buffer[1024];
strcpy(buffer, "hello ");  
strcpy(buffer + 6, "world!");

ポインタを必要とする何かがそれらを使用せずに行われる可能性があります。

確かに、大きなオブジェクトをメソッドに渡したいと思います。コピーする代わりに、ポインタを渡すこともできますが、参照を渡す方がよい場合があります。

void foo(Object const& o); // <- this one is prefered
void foo(Object *o);

オブジェクトを関数に渡す方法の一連のルールを次に示します。

関数パラメーターとしてポインターを送信することはできますが、返されたデータを使用して送信できますか?

それはできます。ポインタを返す際の問題は、「ポインタが指すストレージの場所はどこですか?」です。ローカル変数を返すのは危険な考えです(C ++ 11は、移動セマンティクスでこの問題を解決しました)

ポインターを使用して関数内の複数の変数を変更できますが、その回避策もあります

申し訳ありませんが、これはわかりません。

実際にポインタが必要ですか?

はい、そうです。

于 2012-05-07T16:23:20.020 に答える