2009-12-12 67 views
6

私は一般的にポインタのコンセプトを得ていると思うのですが、私にとって一つのことは、それがグローバルに指しているものは何でも一般化しているようです変数(例えば、ポインタを使用してvoidの関数から値を返す機能)は、自然にそのすべての付随する危険性を伴います。Cのポインタとグローバル変数の違いは何ですか?

ポインタが配列内の特定の変数またはインデックスを参照するという事実以外に、です。ポインタとグローバル変数の違いは何ですか?

+1

K&R以外の作品を指す言葉「The C Book」を初めて見たと思います。 –

+0

は完全に異なっています。 –

+0

はい、コメントをする前にリンクを見てから気づきました。 –

答えて

17

彼らは全く異なる獣です。説明を良くするために、私は両方を定義しましょう。

ポインター:

変数は、データのいくつかの作品を保持しています。ポインタは、別のメモリを参照するデータの一種です。それを何らかのオブジェクトを指し示す "Over ---->"という看板と考えてください。たとえば、Cの文字列は文字へのポインタに過ぎず、慣習的には、それに続く文字が\0文字まで存在することがわかります。

プログラムで、あなたは各機能の変数を持っています。ために....

グローバル変数を除いて、プログラムの部分との間で共通の情報を共有するための他のメカニズムがないため、Cは、広範囲にポインタを使用しています。これらは関数へのパラメータでも、内部で定義されたパラメータでもかまいません。同様に、グローバル変数と呼ばれるものもあります。これらの変数は、ファイル内のすべての関数がアクセスできる情報を格納します。これは、グローバルな状態や設定のようなものを渡すのに便利です。たとえば、いくつかのメッセージを出力する前にコードがチェックするdebugと呼ばれるものを使用したり、ビデオゲームのスコアのようなグローバル状態オブジェクトを格納することができます。

あなたが混乱していると思うこと:両方を使用してコードの部分間で情報を共有できます。関数の引数はで値に渡されるため、関数はそれを呼び出す変数を変更できません。この問題を「修正」するには2つの方法があります。最初の(そして正しい)方法は、変数へのポインタを関数に渡すことです。このようにして、関数は親の変数をどこで修正するかを知っています。 もう1つの方法は、グローバル変数を使用することです。そうすれば、ポインターを回す代わりに、グローバル変数を直接編集するだけです。

あなたは同じことを達成するために両方を使うことができますが、どのように動作するかは全く別です。実際には、グローバル変数はポインタになります。

+2

グローバル変数を使用するよりもポインタが正しいかどうか(またはどのような状況で)ポインタが正しいかを渡すのはなぜですか? –

+5

情報がグローバルである必要がない場合は、グローバル名前空間を汚染しているだけです。グローバルな状態への変更はどこからでも発生する可能性があるため、コードを理解することははるかに難しくなる可能性があります。 マルチスレッドのプログラムでは、状態を編集する関数は、大切な注意やロックなしにグローバル変数または静的変数を使用する場合、再入可能または再帰的ではありません。 – McPherrinM

0

完全に異なる概念。グローバル変数とローカル変数の両方へのポインタを持つことができます。両者を関連付けるものは何もない。

また、ある関数から、その関数内でスコープされた変数へのポインタを確実に返すことができます。変数は関数のスタック上に存在していて、今はそれがなくなってしまったので、それは悪い考えです。

8

グローバル変数は、どのスコープでもアクセス可能な変数です。ポインタは、何かが存在するアドレスを含む変数です。

これらは互いに直接的に関連していません。

ポインタ変数は、グローバルスコープまたはローカルスコープのどちらでもかまいません。また、グローバル、ローカル、またはスコープがない変数を指すこともできます(ヒープから抜け出したり、DIOラインをアドレス指定しているかのように)。

4

大きな違いがあります。ポインタの「その他」の使用(文字列と配列の処理、ツリーやリンクリストなどの動的データ構造の構築を含む)では、ポインタを使用してローカル変数へのアクセスを他の関数に与えることは、共有よりはるかに柔軟で制御されますこれら2つの関数間のグローバル変数。

まず、呼び出された関数に異なる時刻に異なる変数へのアクセスを提供することができます。同じグローバル変数に結果を保存する場合は、scanf()を使用するのがどれほど難しいか考えてみてください。

第2に、ポインタを別の関数に渡すと、その関数がオブジェクトを変更できるという事実がはっきり分かります。同じ目的のためにグローバル変数を使用すると、どの関数がグローバルを変更するのか、そうでないのかを忘れることは簡単です。

第3に、グローバル変数はプログラムの有効期間中メモリを消費します。ローカル変数は、その包含関数が終了すると解放され、free dのときに、動的に割り振られたデータが解放されます。したがって、グローバル変数は時にはかなりのメモリの浪費となることがあります。

ポインタを使用すると、もはや存在しない変数を参照する危険がありますので、注意が必要です。しかし、これは複雑なグローバルまたは長命のデータ構造が存在し、それ自体がしばしば設計上の弱点である場合、最も頻繁に問題となります。

グローバリゼーションは、優れたモジュール式プログラムの設計になっており、ポインタはしばしば同じことを達成するためのより良い方法を提供します。

3

"ポインタ"は、値を取得する方法を示す変数です。これは、気になる値のアドレスです。あなたは値を得るためにそれを逆参照します(*で)。

"グローバル"は変数のスコープを定義します。プログラム内のどこでも名前を指定して値を取得できます。

ローカルポインタまたはグローバル非ポインタを持つことができます。概念は完全に直交しています。

0

というポインタは、変数の型を参照します。それは別のものを参照するために使用される変数です。用語グローバルは、変数スコープ、すなわちプログラムの任意の部分からの可視性を指す。したがって、さまざまな種類の変数属性を参照するため、質問はやや意味がありません。ポインタ変数は実際にグローバルスコープを持つことができ、両方の属性を同時に持つことができます。

ポインタは実際にスコープに直接存在しないオブジェクトを参照することがありますが(これは私があなたが参照していると思います)、スコープが制限されているためです。グローバルポインタです!)。

また、グローバル変数は常にに静的ストレージクラスがあります。ポインタは静的変数、動的変数、または自動変数を参照することができますが、変数であるため、ポインタ自体は静的または自動であるか、動的に割り当てられたポインタ配列の場合でも動的です。

実際にははるかに大きなユーティリティがあり、さまざまな方法で使用できる場合は、ポインタの非常に特殊な使用を検討していると思います。たとえば、ほとんどの場合、ポインタを使用してリンクリストデータ構造内のリンクを実装します。グローバル変数はそれを行うのに役立つものではありません。

クリフォード

関連する問題