2016-06-21 17 views
0

私は現在ダン・グーキンの書籍「ダミーのためのCのプログラミング」でCプログラミングを学んでいます。C言語のポインタを再初期化する

私が現在読んでいるトピックの1つは、配列が実際にポインタであるという事実です。

#include <stdio.h> 

int main() 
{ 
    int numbers[10]; 
    int x; 
    int *pn; 

    pn = numbers;  /* initialize pointer */ 

/* Fill array */ 
    for(x=0;x<10;x++) 
    { 
     *pn=x+1; 
     pn++; 
    } 

    pn = numbers; 

/* Display array */ 
    for(x=0;x<10;x++) 
    { 
     printf("numbers[%d] = %d, address %p\n", 
       x+1,*pn,pn); 
     pn++; 
    } 

    return(0); 
} 

私の質問は本当に線17で私は17行目のように、再びポインタをreintializeない場合は、ポインタpnのPEEK値が表示されていることを実現している:ダンは、次のコードであることを証明しようとしました2番目のforループシーケンスは意味をなさないゴミの束です。したがって、コードが意図したとおりに動作するように、再度ポインタを再インライン化する必要があることを知りたいですか?

+10

"*配列は実際にはポインタです*"いいえ、そうではありません。 – alk

+4

その本を取り除く... – LPs

+0

*あなたのプログラムがあなたが期待する結果を与えるために、 "なぜ再統合する必要があるのですか?" *。 – StoryTeller

答えて

3

アレイは、ポインタではなく、Cは、そのポインタは配列の最初の項目をポイントするという効果と、アレイの変数の型のポインタに配列を割り当てることができ。それはpn = numbersの機能です。

pnは、配列ではなくintへのポインタです。これは単一の整数を指します。インクリメントすると、次のメモリ位置に移動します。それが作るシフトは、ポインタの型のサイズなので、この場合はintです。

これは何を証明していますか?配列はポインタではありませんが、配列は配列アイテムの型のサイズのN倍の連続したメモリブロックです。

2番目のループを実行すると、ポインタはもはや配列に属していないメモリに到達します。そのため、その場所に存在する情報だけが「ゴミ」になります。

ポインタを増分して配列を繰り返し処理する場合は、そのポインタを最初の項目に再初期化する必要があります。 forループは、10まで数えて1つしか行いません。配列についてはわかりませんし、ポインタについてはわからないので、ループは自動的にポインタをリセットしません。

+1

ああ、私は参照してください。ちょっとしたことを明確にするために、コードは実際には配列がポインターであることを証明するのではなく、配列の型のN倍の大きさの連続的なメモリブロックであることを証明しようとしています。この章では、配列がポインタのように動作する方法について一般的に説明しています。ご不便をおかけして申し訳ありません:( – TruthOrDare

+0

標準ではごみがありません。未定義の動作です。その他 – Olaf

0

フィル配列の間に、ポインタpnがインクリメントされ、データが配列に配置されます。配列の内容を出力するために使用される同じポインタ変数。この再初期化が行われるため。

2

pnが最初のループでインクリメントされるため、最初のループが終了した後にpnnumbersアレイを超えるアドレスを指します。したがって、コンテンツの印刷に同じポインタを使用するので、2番目のループの前に配列の先頭にpnを初期化する必要があります。

1

pnに含まれるアドレスを次のコードスニペットで変更したため、

for(x=0;x<10;x++) 
    { 
     *pn=x+1; 
     pn++; 
    } 
1

pnポインタは、numbersアレイを指すために使用されています。

最初のfor -loopは、pnを使用して値を設定し、データ要素ごとにpnを実行します。ループの終了後、pnは、numbers(割り当てられていない11番目の要素)の末尾を指します。二for -loopが機能するために

、すなわちそれ以外のあなたは、あなたがshouldnメモリにアクセスするだろう、numbersアレイの前面に移動する必要がpn配列を介して、踏んで再びnumbersをループにpnを使用するには、 (非割り当てメモリ)を見ている。

1

最初の配列はではなく、ポインターです。それらは関数呼び出しで使用されたときにポインタへのの崩壊であり、(ほとんど)同じように使用できます。 sizeof(pa)は、ポインタのサイズであるのに対し、

いくつかの微妙な違い

int a[5];  /* array */ 
int *pa = a; /* pointer */ 

pa[0] = 5; 
printf("%d\n", a[0]); /* ok it is the same here */ 
printf("address of array %p - address of pointer %p, value of pointer\n", 
    &a, &pa, pa); /* &a is the same as pa not &pa */ 
printf("size of array %d - size of pointer %d\n", sizeof(a), sizeof(pa)); 

sizeof(a)はここ5 * sizeof(int)です。あなたの質問のために今

:最初のループの後

pnポイントp[10]ともはやp[0]にします。それが理由リセットする必要があります。

+0

ポインタと配列の相違点を教えてくれてありがとうございます( – TruthOrDare

1

ポイントホームを駆動するには、のアレイはポインタではありません。あなたはint numbers[10]としてnumbersを宣言するとき、あなたはメモリ内に次を得る:

  +---+ 
numbers: | | numbers[0] 
     +---+ 
     | | numbers[1] 
     +---+ 
      ... 
     +---+ 
     | | numbers[9] 
     +---+ 

numbersの最初の要素への別々のポインタ用に確保して何のストレージはありません。何が起こるかは、式numbersがどこに現れても、sizeofオペランドまたは&オペレータのオペランドでない場合、それは "intへのポインタ"型の式に変換( "崩壊")され、は、配列の最初の要素のアドレスです。 numbersの最初の要素を指すように設定し、その後、アレイを介し「ウォーキング」されて何がpnでやっている

  +---+ 
numbers: | | <------+ 
     +---+  | 
     | |  | 
     +---+  | 
      ...   | 
     +---+  | 
     | |  | 
     +---+  | 
      ...   | 
         | 
     +---+  | 
    pn: | | -------+ 
     +---+ 

次の整数を指すようにpnを進め01​​表現この場合、配列の次の要素であるオブジェクト:

  +---+ 
numbers: | | 
     +---+ 
     | | <------+ 
     +---+  | 
      ...   | 
     +---+  | 
     | |  | 
     +---+  | 
      ...   | 
         | 
     +---+  | 
    pn: | | -------+ 
     +---+ 

最初のループの終わりにまでポインタを進めるpn++それぞれ、あなたが

  +---+ 
numbers: | | 
     +---+ 
     | | 
     +---+ 
      ... 
     +---+ 
     | | 
     +---+ 
      ... <------+ 
         | 
     +---+  | 
    pn: | | -------+ 
     +---+ 

この時点で、pnを直ちにアレイの端を次のオブジェクトを指している:以下有します。このため、次のループの前にpnをリセットする必要があります。そうでない場合は、numbersの直後のメモリを通過しています。これには、トラップ表現(つまり、指定された型の正当な値に対応しないビットパターン)を含むかなりのものが含まれます。

アレイの最後を超えてメモリにアクセスしようとすると、の未定義の動作が呼び出されます。これは、コードが完全にクラッシュしてゴミを表示して正常に動作することを意味します。

+0

)コードがどのように機能するかを理解する。 – TruthOrDare

関連する問題