6

我想重构我的一些旧 C 代码,我很好奇是否可以ptr++ptr += 1where ptris some 指针替换 all 而不改变任何行为。这是我的意思的一个例子,来自 K&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++将返回 的a,同时a += 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

++并且--是根据内置类型的算术定义的。行为将是相同的,除了后缀返回旧值。

于 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 回答