2017-02-02 8 views
0

の部材としてチャーポインタIはK & R(ページ:133)から、実施例structureを取り、structurearraypointerに少数pointer演算を試みました。ポインタ演算:構造体

#include <stdio.h> 
// struct example from K&R 
struct key { 
    char *word; 
    int count; 
}keytab[] = { 
    "auto",0, 
    "break",0, 
    "const",0, 
    /*.....*/ 
    "case",0 
}; 
int main() { 
    struct key *ptr1 = keytab; 
    printf("%d\n",sizeof(struct key)); 

    //check1 
    printf("%s\n",ptr1++->word); //1 
    printf("%s\n",ptr1->word); //2 

    //check2 
    printf("%s\n",++ptr1->word); //3 
    printf("%s\n",++ptr1->word); //4 

    //check3 
    printf("%s\n",ptr1++->word); //5 
    printf("%s\n",ptr1->word); //6 ?? 
} 

出力:

8 
auto 
break 
reak 
eak 
eak 
const 

私は、演算子の優先順位の助けを借りて3rd4thprintfの出力を理解することができます。

しかし、5th6thprintfの場合、ptr1はどのようにインクリメントされていますか?プログラムの出力は1st & 2ndprintfと同様の動作を示します。 ptr1が1つの構造体サイズ(ここでは8バイト)のステップでインクリメントした場合、それはどのようにしてkeytab[2]の開始に位置合わせされます。

私は間違ったことを理解しているかもしれませんが、この最後のクエリが無効かもしれないので、説明してください!

ありがとうございました!

答えて

1

ptr1が1つの構造体サイズ(ここでは8バイト)のステップで増分する場合、どのようにそれがキータブ[2]の開始位置に揃うか。

しかしptr1はキータブの要素を指して常にです。要素を途中で指すことは許されません。それは決して起こりません。

あなたがreakを参照してください理由、そしてeakは、キータブエントリptr1がその場で変更されたことで指されていることです。

つまり、++ptr1->wordは変更されません。ptr1すべてです。チェックすることができます。前後の値を印刷するだけです。その式は、wordの値をのキータブに変更します。3行目以降は、を指し示すようにkeytab[1].wordが変更されました(インクリメントされました)。

最後にptr1を増やすと(#5が印刷された直後)、それでも&keytab[1]から&keytab[2]に増加しています。 keytab[1]の内部を変更しても、それはまったく影響しません。

私は演算子の優先順位の助けを借りて、3番目と4番目のprintfの出力を理解することができあなたが正しくこれのほとんどを実現しますが、ptr1->wordを変更するptr1の値には影響しないことを見落としているようだ

自体。

+0

@thanksこの回答は私の疑問を解決します。 – Debashish

+0

'しかし、ptr1-> wordの変更はptr1自体の値に影響しないことを見落としました。はい、私は 'ptr1'が前進していると思いました。 – Debashish

1

したがって、3と4のプリントはptr1-> wordをインクリメントします。それらが実行された後、ptr1-> wordは "eak"を指します。

印刷5は、変更されていない値を最初に印刷し、次にptr1をインクリメントします。次に、リストの次の単語「const」をポイントします。

これはすべて、あなたが述べたように演算子の優先順位だけでなく、接頭辞と後置++演算子の影響についても説明しています。それらの副作用は同じですが、最初のものは新しい値を返し、2番目のものは古い値を返します。

+0

これはリスト内の次の単語を指しています。 "' ptr1がどこを指しているかにかかわらず、 'ptr1 ++'は常に次の配列要素の開始位置に進みます(ここでは 'keytab [2] ')。私は正しいですか? – Debashish

+1

いいえ、上記のように++ ptr1-> wordはptr1の値を変更しませんでした。 ptr1 ++は常にptr1 = ptr1 + 1となるため、ptr1の前の値は重要です。 –

+0

はい、間違いました – Debashish

1

この式:

++ptr1->word 

ptr1ポインタをインクリメントしません。 ->オペレータは接頭辞++よりも厳密にバインドするため、operator precedenceのため、++(ptr1->word)とグループ化されています。つまり、現在指示されている構造体のオブジェクトのメンバーをインクリメントすることです。つまり、wordメンバをインクリメントします。

+0

'ptr1'が' 5''printf'の後の 'keytab [2]'メンバ文字列 '' const "'の途中を指し示すことを期待していました。しかし、ここではそうではありません。したがって、 'ptr1'がどこに向いていても、' ptr1 ++ 'は常に次の配列要素(ここでは' keytab [2] ')の開始位置に進みます。 – Debashish

+1

@Debashish:そうです。 'ptr1'の型は' struct key'へのポインタなので、常に 'keytab'配列の次の要素に進みます。 –

関連する問題