9

Cを学び始めたばかりですので、よろしくお願いします。ポインタに関してこれまで読んだことから:

int * test1; //this is a pointer which is basically an address to the process 
             //memory and usually has the size of 2 bytes (not necessarily, I know)
float test2; //this is an actual value and usually has the size of 4 bytes,
             //being of float type
test2 = 3.0; //this assigns 3 to `test2`

さて、私が完全に理解していないこと:

*test1 = 3; //does this assign 3 at the address 
            //specified by `pointerValue`?
test1 = 3;  //this says that the pointer is basically pointing 
            //at the 3rd byte in process memory, 
            //which is somehow useless, since anything could be there
&test1; //this I really don't get, 
        //is it the pointer to the pointer? 
        //Meaning, the address at which the pointer address is kept?
        //Is it of any use?

同様に:

*test2; //does this has any sense?
&test2; //is this the address at which the 'test2' value is found? 
        //If so, it's a pointer, which means that you can have pointers pointing 
        //both to the heap address space and stack address space. 
        //I ask because I've always been confused by people who speak about 
        //pointers only in the heap context.
4

3 に答える 3

3

素晴らしい質問です。

最初のブロックは正しいです。ポインターは、データのアドレスを保持する変数です。そのポインターの型は、そのポインターによって保持されているアドレスの内容を解釈する方法をコードに指示します。

コンストラクト:

*test1 = 3

ポインターの逆参照と呼ばれます。つまり、ポインタが指すアドレスにアクセスし、通常の変数のように読み書きできます。ノート:

int *test;
/*
 *    test is a pointer to an int - (int *)
 *   *test behaves like an int - (int)
 *
 * So you can thing of (*test) as a pesudo-variable which has the type 'int' 
 */

上記は、私が使用するニーモニック デバイスです。

ポインターに数値を割り当てることはめったにありません...おそらく、「よく知られている」メモリアドレスを持つ特定の環境向けに開発している場合ですが、あなたのレベルでは、あまり心配する必要はありませんそれ。

使用する

*test2

最終的にエラーになります。ポインターではないものを参照しようとするため、ポインターがどこを指しているかを誰が知っているかなど、ある種のシステム エラーが発生する可能性があります。

&test1&test2は、実際には と へのポインタtest1ですtest2

ポインターへのポインターは非常に便利で、ポインターへのポインターを検索すると、私よりもはるかに優れたリソースがいくつか見つかります。

于 2012-12-12T22:44:26.320 に答える
1

まず、混乱を加えましょう。「ポインター」という単語は、ポインター型の変数(またはオブジェクト)、またはポインター型の式のいずれかを指す場合があります。ほとんどの場合、人々が「ポインター」について話すとき、それらはポインター変数を意味します。

ポインタは、モノ(標準用語では「オブジェクト」 )を指すことができます(しなければなりません)。それは正しい種類のものを指すことしかできません。intへのポインタは、floatオブジェクトを指すことは想定されていません。ポインタはNULLにすることもできます。その場合、指摘することはありません。

ポインタ型も型であり、ポインタオブジェクトもオブジェクトです。したがって、ポインタへのポインタを作成することは許可されています。ポインタからポインタは、ポインタオブジェクトのアドレスを格納するだけです。

ポインタができないもの:

  • 値を指すことはできません:p = &4;不可能です。4はリテラル値であり、オブジェクトに格納されていないため、アドレスがありません。
  • 式についても同じp = &(1+4);ことが言えます。式「1+4」には場所がないため、不可能です。
  • 同じことが戻り値p = &sin(pi);にも当てはまります。戻り値はオブジェクトではないため、アドレスはありません。
  • 「レジスタ」としてマークされた変数(現在はほとんど区別されています)は、アドレスを持つことができません。
  • ビットフィールドのアドレスを取得することはできません。これは、基本的に、ビットフィールドが文字よりも小さい(または粒度が細かい)可能性があるためです。したがって、異なるビットマスクが同じアドレスを持つ可能性があります。

上記のスケルトンにはいくつかの「例外」があります(voidポインター、キャスト、配列オブジェクトを超えて1つの要素を指す)が、明確にするために、これらは改良/修正、IMHOと見なす必要があります。

于 2012-12-12T23:52:05.140 に答える
1

最初の部分が正しいようです。

*余談ですが、その記号をどこに置くかについては、さまざまな慣習があります。他の人が好むように、私は変数名に囲まれたint *test1ものを好みint* test1ます。真ん中に浮かんでいることがどれほど一般的かはわかりません。

別の付随的な考え:test2 = 3.0浮動小数点 3 を に代入しtest2ます。で同じ目的を達成できますtest2=3。この場合、3 は暗黙的に整数から浮動小数点数に変換されます。選択した規則は、明確さという点ではおそらく安全ですが、厳密に必要というわけではありません。

偶発的でないもの

*test1=3で指定されたアドレスに 3 を代入しますtest

test1=3意味はありますが、私は無意味だと考えています。記憶場所 3 に何があるか、触れても安全なのか、触ることが許されているのかさえわかりません。

そのため、次のようなものを使用すると便利です

int var=3;
int *pointy=&var;
*pointy=4;
//Now var==4.

このコマンド&varは のメモリ位置を返し、後で でアクセスできるようにvar格納します。pointy*pointy

しかし、次のようなこともできます。

int var[]={1,2,3};
int *pointy=&var;
int *offset=2;
*(pointy+offset)=4;
//Now var[2]==4.

そして、これは合法的に次のようなものを見るかもしれませんtest1=3: ポインタは数値と同じように加算および減算できるため、このようにオフセットを格納できます。

&test1はポインターへのポインターですが、それは私にとってはややこしいように思えます。実際には、値test1が格納されているメモリ内のアドレスです。そしてtest1たまたまその値として別の変数のアドレスを格納しています。このようにポインタを考え始めると (メモリ内のアドレス、そこに格納される値)、扱いやすくなります... または少なくとも私はそう思います。

*test2それ自体に「意味」があるかどうかはわかりません。*原則として、コマンドが の値をtest2メモリ内のある場所に取り、そこで見つけた値を返すと想像できるという点で使用できます。しかしtest2、float として定義するため、メモリ内のどこに到達するかを予測するのは難しく、設定test2=3しても 3 番目の場所には移動しません (理由については、IEEE754 仕様を調べてください)。しかし、コンパイラがそのようなことを許可するとしたら、私は驚くでしょう。

別の簡単な例を見てみましょう。

int var=3;
int pointy1=&var;
int pointy2=&pointy1;
*pointy1=4;  //Now var==4
**pointy2=5; //Now var==5

このように、好きなだけ連続してポインターをチェーンできることがわかります。これは、動的メモリから作成した多くの構造体のアドレスで満たされたポインターの配列があり、それらの構造体に動的に割り当てられたもの自体へのポインターが含まれている場合に発生する可能性があります。ポインターへのポインターを使用するときが来たら、おそらくそれを知っているでしょう。今のところ、それらについてあまり心配しないでください。

于 2012-12-12T23:09:42.437 に答える