6

私の古い C コードをリファクタリングしたいのですが、動作を変更せずに、すべてptr++をポインターのptr += 1ある場所に置き換えることができるかどうかに興味がありました。ptrK&R セクション 5.3 から、私が意味することの例を次に示します。

/* strlen: return length of string s*/
int strlen(char *s)
{
    int n;
    for (n = 0; *s != '\0'; s++)
        n++;
    return n;
}

を に置き換えるs++s += 1同じ結果が得られますが、これがすべてのタイプに当てはまるかどうかは疑問です。sのテストも行いましたint

int size = 10;
int *int_array = (int*)calloc(size, sizeof(int));
for (int i = 0; i < size; i++)
    int_array[i] = i;

for (int i = 0; i < size; i++) {
    printf("*int_array = %d\n", i, *int_array);
    int_array++;
}

int_array++;行をに置き換えるとint_array += 1;、同じ結果が得られます。

これについてもう少し考えてみると、値を式で使用すると問題が発生する可能性があることに気付きました。次のようにインクリメントを別の行に移動した方が安全でしょうか。

int a = 5;
int b = a++;

次のようになります。

int a = 5;
int b = a;
a += 1;

結論

問題になる可能性があると思っていたのは、さまざまなタイプのポインターをインクリメントすることですが、問題ではありません。理由については、@bdonlan の応答を参照してください。

x++これは、すべてを置き換えx += 1て同じ動作を期待できるという意味ではありません。ただし、これらは同等であるため++x、安全に置き換えることができます。(x += 1)

4

3 に答える 3

11

a += 1++a(C99 §6.5.3.1/2)と同等です。このような行では、 ;と同等int b = a++;ではないことを意味します。は の古い値を返し、 は新しい値を返します。a++a++aa += 1

の結果を使用しない場合a++(つまり、 のみを含むステートメントがある場合a++;)、それらは事実上同一であることに注意してください。

また、_all ポインター演算は、ポイント先の型のサイズの増分で行われることに注意してください (§6.5.6/8)。この意味は:

ptr = ptr + x;

次と同等です。

ptr = (ptr_type *)( (char *)ptr + x * sizeof(*ptr) );

これは、++++=、または[](p[x]は とまったく同じ*(p + x)です。このため、次のようなこともできます) を使用しても同じ4["Hello"]です。

于 2011-12-07T19:13:23.420 に答える
1

++--組み込み型の算術に関して定義されます。postfix が古い値を返すことを除いて、動作は同じです。

于 2011-12-07T19:13:57.937 に答える
1

いい質問です。答えはイエスです。それは可能です。どのように行っても、ポインタをインクリメントするとポインタが追加sizeof(the type that the pointer points to)されます。他の回答が示すように、インクリメントがいつ発生するかに依存しないように注意する必要があります。つまり、 a++ と ++a は異なる効果を持ちますが、 a は最終的に同じ値になります。

問題は、なぜa++すべてのコードを からに変更したいのa+=1ですか? ポインターで後置インクリメント演算子を使用することは、C プログラマーなら誰でも簡単に理解できるはずですが、なぜその変更を行うのかを理解するのは困難です。

于 2011-12-07T19:15:44.660 に答える