1

私はいつもCで*&p = p =&* pだと思っていました。私はこのコードを試しました:

 #include <stdio.h>
 #include <stdlib.h>

 char a[] = "programming";
 char *ap = &a[4];  

int main(void)
{

 printf("%x %x %x\n", ap, &*(ap), *&(ap));   /* line 13 */
 printf("%x %x %x\n\n", ap+1, &*(ap+1), *&(ap+1));   /* line 14 */
}

最初のprintf行(13行目)は私にアドレスを与えます:

40b0a8 40b0a8 40b0a8

予想通りです。しかし、2番目のprintf行を追加すると、Borlandは次のように不平を言います。

"first.c":E2027行14の関数mainのメモリ位置のアドレスを取得する必要があります

私は得ることを期待していました:

40b0a940b0a940b0a9。

14行目の*&(ap + 1)という表現が原因のようです。14行目の3つのポインター式はすべて同等だと思いました。なぜ私は間違って考えているのですか?

2番目の関連する質問:行

char *ap = a;

配列aの最初の要素を指します。使用しました

char *ap = &a[4];  

配列aの5番目の要素を指す。

表現は

char *ap = a;

式と同じ

char *ap = &a[0];

最後の表現は前の表現よりも冗長なだけですか?

どうもありがとう...

4

4 に答える 4

6

左辺値のアドレス、つまりオブジェクトを参照する式のみを取得できます。ap + 1アドレス計算です。値はありますが、一時オブジェクトであるため、左辺値ではなく、そのアドレスを取得することはできません。

2番目の質問への回答として、式のほとんどのコンテキストでは、配列は最初の要素へのポインターに減衰するため、そうchar *ap = a;ですchar *ap = &a[0];。これは同等です。

于 2010-04-11T21:45:18.500 に答える
1

C参照演算子を使用する場合、任意の式ではなく、有効な左辺値を指す必要があります。したがって、&(ap+1)ap+1は単なる式であり、場所ではないため、は無効です。言えないap+1 = foo();

はい、aはここの&a[0]と同じです。*(a + b)はa [b]と100%同等であることに注意してください(この同等性の珍しい例については、奇妙な言語機能のトップアンサーを参照してください)。配列のメンバーへのポインターを取得するときは、&array[i]またはarray+iを使用できます。例:

struct foo array[5];
struct foo *item_3 = &array[3];
struct foo *also_item_3 = array + 3;

この場合、使用するかどうかarray+i&array[i]スタイルの問題です。 &array[i]配列アイテムが取得されていることがより明確であるため、間違いなくより良い選択です。さらに、&vec[i]はC++のベクトルで機能しますが、vec+iは機能しません。

于 2010-04-11T21:52:49.530 に答える
0

これらのステートメントの1つが具体的に原因であると思われる場合は、その行を3つの別々の行に分割し、コンパイラーがどこに文句を言うかを確認します。私も同じ疑いを持っていますが、それを確認するために、私はちょうどあなたにそうするように言ったのと同じようにします。

于 2010-04-11T21:45:29.843 に答える
0

チャールズはあなたの主な質問について正しいと思います、そしてあなたは2番目の質問について正しいと思います:char *ap = a;と同等char *ap = &a[0];です。

于 2010-04-11T21:50:08.647 に答える