I'd like to refactor some old C code of mine, and I was curious if I can replace all ptr++
with ptr += 1
where ptr
is some pointer, without changing any behavior. Here's an example of what I mean, from K&R Section 5.3:
/* strlen: return length of string s*/
int strlen(char *s)
{
int n;
for (n = 0; *s != '\0'; s++)
n++;
return n;
}
When I replace the s++
with s += 1
, I get the same results, but I'm wondering if this will be the case for all types. I also did a test for int
s:
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++;
}
If I replace the line int_array++;
with int_array += 1;
, I get the same result.
After thinking about this some more, I realize there could be a problem if the value is used in an expression. Would it be safer I just moved the increment onto another line like so:
int a = 5;
int b = a++;
would become:
int a = 5;
int b = a;
a += 1;
Conclusion
What I thought could be a problem, incrementing pointers of different types, is not a problem. See @bdonlan's response for the reason why.
This doesn't mean that you can replace all x++
with x += 1
and expect the same behavior. You can, however, replace ++x
with (x += 1)
safely, since they are equivalent.
Note that all pointers are 8 bytes.
Pointer Arithmetic Unlike regular numbers, adding 1 to a pointer will increment its value (a memory address) by the size of its underlying data type. To simplify the logic behind this, think of pointer arithmetic the same way you think about array indexing.
ptr is a pointer and it points to some valid memory location in your case. &ptr is the address of your pointer and it can be assigned to a double pointer. int **ptr1 = &ptr; Else the address of your first element is given just by ptr .
a += 1
is equivalent to ++a
(C99 §6.5.3.1/2). In a line like int b = a++;
this means it is not equivalent to a++
; a++
would return the old value of a
, while a += 1
returns the new value.
Note that if you don't use the result of a++
(ie, you have a statement containing just a++;
), then they are effectively identical.
Also, note that _all pointer arithmetic is done in increments of the pointed-to type's size (§6.5.6/8). This means that:
ptr = ptr + x;
is equivalent to:
ptr = (ptr_type *)( (char *)ptr + x * sizeof(*ptr) );
This is the same whether you use +
, ++
, +=
, or []
(p[x]
is exactly equivalent to *(p + x)
; you can even do things like 4["Hello"]
because of this).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With