George
George

Reputation: 7317

Do functions w/pointer arguments still have local copies of those arguments?

Consider the following code taken from K&R:

/* strlen: return length of string s */

int strlen(char *s)
{
    int n;

    for (n = 0; *s != '\0', s++)
        n++;
    return n;
}

K&R states that here "s++ has no effect on the character string in the function that called strlen, but merely increments strlen's private copy of the pointer".

  1. Am I correct in interpreting "s++" as being equivalent to "&s[0]+1". This seems non-sensical to me, so I must be wrong here.
  2. If s++ really has no effect on *s, then how could the loop condition (i.e., *s != '\0') ever change in truth value? After all, *s is unaffected by s++. So it will either be true forever or false in the first place. Why is this not the case?

Upvotes: 0

Views: 52

Answers (2)

Havenard
Havenard

Reputation: 27894

A copy of the pointer, yes. Arguments are always copied. And the same way a function can modify arguments as its own local variables without affecting the original variable, the same can be done with pointers.

By incrementing s++ you are doing the same as s = &s[1] or s = s + 1, and it modifies s as the local variable it is, this change does not propagate to the original pointer in the caller.

Only by modifying the value a pointer is pointing to, as when modifying *s, it will have it modified in the caller aswell. Thats why when attempting to modify a pointer itself, you have to use a pointer to a pointer, for instance: char** var

Upvotes: 1

sepp2k
sepp2k

Reputation: 370357

Am I correct in interpreting "s++" as being equivalent to "&s[0]+1".

No. The expression &s[0]+1 does not have side-effects - s++ does. The way it is used here (that is without using its return value), s++ is equivalent to s = s + 1 or s = &s[0]+1 or s = &s[1] (which all do the same thing).

If s++ really has no effect on *s, then how could the loop condition (i.e., *s != '\0') ever change in truth value?

s++ does have an effect on *s in the sense that it changes what s points to and if s points to somewhere else, then of course the value of the expression *s will change. However it does not have an effect on the value that s previously pointed to.

To illustrate this consider strlen being called on a string str where char* str = "abcd";: At the beginning of the loop s points to str[0]and thus *s is equal to 'a' because str[0] is equal to 'a'. After you do s++, s now points to str[1]. Now *s is equal to 'b' because str[1] is equal to 'b', yet neither str[0] nor the contents of str changed.

Upvotes: 2

Related Questions