1

こんにちは私はこれについての説明を以下で得るのに混乱しました、誰かが私にそれを説明できますか?前もって感謝します。

#include<stdio.h>
int main(){
    char *arr,c;
    arr = &c;

    arr++;
    *arr = 'a';

    arr++;
    *arr = 'b';

    arr++;
    *arr = 'c';

    arr--;
    arr--;

    printf("\narr 1 = %c",arr);
    printf("\narr 2 = %c",arr[1]);
    printf("\narr 3 = %c",arr[2]);
    getch();
    return 1;
    }

出力は次のとおりです
。arr1=
a arr 2 = b
arr 3 = c

しかし、行を変更した場合:

printf("\narr 1 = %c",arr);

printf("\narr 1 = %c",arr[0]);

現在の出力は次のとおりです
。arr1=  
arr 2 = b
arr 3 = c

なぜ「a」が印刷されないのですか。

*プログラムを悪いコーディングとして疑問視しているすべての人のために..このようなポインタを使用するのは良いコーディング方法ではないことを私は知っていますが、私の質問は、arr[0]がarr[1]&arr[のように何も出力しない理由です。 2]割り当てられたものを印刷していますか?

4

3 に答える 3

9

プログラムの最初のバージョンでは、次のようなことが起こる可能性があります。

  • コンパイラはc、スタック上のあるアドレス、たとえば 1003 (1 バイト) に置きます。
  • コンパイラはarr、スタック上のあるアドレス、たとえば 1004 ~ 1007 (4 バイト) に置きます。
  • このステートメントは、1003arr = &c;のアドレスを に入れます。carr
  • このステートメントarr++;は に 1 を追加するarrため、1003 ではなく 1004 になります。
  • ステートメントは、ポイントする場所に*arr = 'a';書き込みます。これは現在、C 標準では定義されていない動作です。が に設定されている場合、オブジェクト内のその場所には 1 バイトしかありませんでした。C 標準では、オブジェクトの外部でそのアドレスをインクリメントした後に他の場所に書き込むとどうなるかは保証されていません。'a'arrarr&c
  • この例では、1004 が を指しているため、 のバイトの 1 つにarr書き込みます。これは、 にあったアドレスを恐ろしく変更します。'a'arrarr
  • 次にarr++;、アドレスを再度インクリメントし、どこかに*arr = 'b';書き込みます。悪い値が含まれている'b'ため、どこにあるのかわかりません。arr
  • 次にarr++;、アドレスを再度インクリメントし、どこかに*arr = 'c';書き込みます。'c'どこにあるのかわかりません。
  • 次にarr--;、アドレスを書き込んarr--;だ後の値に戻します。'a'
  • 次に、最初のprintf呼び出しで値が渡さarrれ、「%c」指定子で出力されます。「%c」は文字を出力するためのarrものですが、渡すのはポインターです。ただし、以前にポインターに書き込ん'a'だため、ポインターの値は'a'そのバイトの1つにあります。
  • たまたま、「%c」指定子がポインターとともに使用されると、この の実装はprintfポインター値のバイトの 1 つを出力します。この場合は、 を書き込んだのと同じバイトです'a'。したがって、「a」が印刷されます。他の C 実装でこれが起こることに依存することはできません。arrこれは、コンパイラがメモリ内の直後にたまたまメモリ内に配置したため、この場合にのみ発生したためc、ステートメント*arr = 'a';は. これは、すべての C 実装で発生するわけではありません。あなたは「ラッキー」です。</li> 'a'arr
  • 'a'intoarrの書き込み後、arrどこかはわかりませんが、どこかを指しています。この場所を としましょうx
  • ステートメントarr++;とは、場所に*arr = 'b';書いた。'b'x+1
  • ステートメントarr++;とは、場所に*arr = 'c';書いた。'c'x+2
  • 次に、 を指す2 つのarr--;ステートメントが返されました。文字 at 、is 、 is も同様です。これらを printf に渡して「%c」で出力すると、「b」と「c」が出力されます。arrxarr[1]x+1'b'arr[2]'c'

プログラムの 2 番目のバージョンでは、 が次のarr[0]ように渡されprintfます。

  • の値は、そのバイトの 1 つにarr書き込むことによって形成された値です。'a'これは何らかの「ランダムな」アドレスであり、私たちが管理していない場所を指しています。どうやらそこには 0 文字、またはその他の印刷されない文字があるため、が にarr[0]渡されるとprintf、何も印刷されません。
  • 「b」と「c」を渡しarr[1]て出力します。これは、コードがこれらの場所にandを書き込んだためです。arr[2]'b''c'
于 2012-12-18T17:59:08.370 に答える
6

arr配列を逆参照arr[0]するため、はと同等ではありません。正しい同等物はです。arr[0] &arr[0]

ちなみに、あなたがしていることは未定義の振る舞いを引き起こします。なぜなら、インクリメントした後arr、それは無効なメモリ位置を指しているからです-元々は単一の文字を指しているので、その後に何かがあると仮定することはできません。

于 2012-12-18T16:40:39.300 に答える
6

これは単に未定義の動作です。単一の を指しているarr++; *arr = 'a';ため、不正です。何でも起れる。arrchar

于 2012-12-18T16:41:23.367 に答える