5

私は非常に単純なことを試みていますが、単純であるはずですが、どういうわけか私をいじっています...

ポインターとして扱われるときの配列に対する ++ の効果と、配列として扱われるときのポインターを理解しようとしています。

そう、

int main()
{
    int a[4] = { 1, 4, 7, 9 };
    *a = 3;
    *(a+1) = 4;
    *++a = 4; //compiler error
}

1:では、*(a+1)=4a[1]=4 を設定します。//Happy しかし、 の場合*++a = 4;、++ が * の前にあるため、ポインター a が 1 増加すると予想されます。次に * が開始され、4 に等しくなります。しかし、このコードは機能しません...なぜですか?

別の問題:

int main()
{

    int* p = (int *)malloc(8);
    *p = 5;
    printf("%d", p[0]);

    *++p = 9; //now this works!
    printf("%d", p[1]); //garbage
    printf("%d", p[0]); //prints 9

}

2:これで *++p = 9; 正常に動作しますが、実際には配列のように動作していません。2つの違いは何ですか?これは、p をインクリメントして 9 に等しくするだけです。p[0] を出力すると、9 が出力され、p[0] 経由でアクセスすることはできなくなりましたが、*(p-1) は 5 を示しています。まだあります。[0] でポインタをインデックスすると、正確にはどこを指すのでしょうか? 変化したこと?

すべての専門家に感謝します!

4

2 に答える 2

9

配列名は変更可能な左辺値ではないため、操作 ++ は適用されないため++a、変更しようとするaとコンパイル時エラーになります (aは配列名です)。

*(a + 1)*a++は同じではありません。追加するだけでそれ自体を変更しないためa + 1、有効な命令です。一方(これは と同等です) したがって、エラーを変更しようとします。1a++aa = a + 1

「配列名」はポインタではないことに注意してください。ポインターは変数ですが、配列名は変数ではありません。もちろん、配列名をポインターに割り当てると、ほとんどの式で配列名が最初の要素のアドレスに分解されます。例えば

int *p = a;

p配列の最初の要素 ( ) を指していることに注意してくださいa[0]

配列名が最初の要素へのポインターに減衰しないいくつかの例外を読みますか?

a[i]は と同等です*(a + i)。ここでa、ポインターまたは配列名のいずれかを指定できます。したがって、2番目の例p[i]では有効な式です。

また、2 番目のコード例ではポインタ (変数) である*++pため、は有効です。p

于 2013-10-13T06:28:11.957 に答える
1
int a[4] = { 1, 4, 7, 9 };
int *pa=a;

配列名とポインタの間には、覚えておかなければならない違いが 1 つあります。ポインターは変数なのでpa=a、 とpa++は有効です。しかし、配列名は変数ではありません。のような構造a=paおよびa++違法である


int* p = (int *)malloc(8);

malloc() の結果をキャストしない

ポインターでインデックスを使用する

p[1]=9; // p[1]==*(p+1)
于 2013-10-13T06:29:44.840 に答える