2

ポインターのインクリメントと逆参照がどのように連携するかを理解しようとしています。これを試してみました。

#include <stdio.h>
int main(int argc, char *argv[])
{
    char *words[] = {"word1","word2"};
    printf("%p\n",words);
    printf("%s\n",*words++);
    printf("%p\n",words);
    return 0;
}

私は、このコードが次のいずれかを実行することを期待していました。

  1. 最初に逆参照してからポインターを増やします (word1 を出力します)
  2. 最初に逆参照してから値を増やします (ord1 を出力)
  3. 逆参照ポインタ + 1 (word2 の出力)

しかし、コンパイラはこれをコンパイルすることさえせず、このエラーを出します:lvalue required as increment operandここで何か間違ったことをしていますか?

4

4 に答える 4

2

2 番目の printf のポインター逆参照を中かっこで囲む必要がありprintf("%s\n",(*words)++);ます。

于 2012-04-14T02:16:08.320 に答える
2

配列をインクリメントすることはできませんが、ポインターをインクリメントすることはできます。宣言した配列をポインターに変換すると、それが機能します。

#include <stdio.h>
int main(int argc, char *argv[])
{
    const char *ww[] = {"word1","word2"};
    const char **words = ww;
    printf("%p\n",words);
    printf("%s\n",*words++);
    printf("%p\n",words);
    return 0;
}
于 2012-04-14T02:21:13.233 に答える
1

words配列の名前なので++、意味がありません。ただし、配列要素へのポインターを取得できます。

for (char ** p = words; p != words + 2; ++p)
{
    printf("Address: %p, value: '%s'\n", (void*)(p), *p);
}

もちろん、代わりに2、より一般的な を使用できますsizeof(words)/sizeof(*words)

于 2012-04-14T02:18:51.810 に答える
0

問題は次の行にあります。

printf("%s\n",*words++);

として読み取られ*(words++)ます。つまり、メモリのブロックをインクリメントします。それは意味がありません。

int a = 1;
(&a)++; // move a so that it points to the next address

これは C では違法です。

この問題は、C における配列とポインターの違いによって引き起こされます。(基本的に) 配列はメモリ ブロック (コンパイル時に割り当てられる) であり、ポインターはメモリ ブロックへのポインターです (必ずしもコンパイル時に割り当てられるとは限りません)。 . これは、C を使用する場合の一般的なトリップアップであり、それに関する SO に関する他の質問があります (例: C: char ポインターと配列の違い)。

(修正は他の回答で説明されていますが、基本的には文字列の配列ではなく文字列へのポインタを使用したいと考えています。)

于 2012-04-14T02:33:28.467 に答える