考虑以下来自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声明这里“s ++对调用strlen的函数中的字符串没有影响,但只是增加了strlen指针的私有副本”。
答案 0 :(得分:2)
我是否正确地将“s ++”解释为等同于“& s [0] +1”。
没有。表达式&s[0]+1
没有副作用 - s++
。它在这里使用的方式(即没有使用其返回值),s++
相当于s = s + 1
或s = &s[0]+1
或s = &s[1]
(它们都做同样的事情)。
如果s ++对* s没有影响,那么循环条件(即* s!='\ 0')如何才能改变真值?
s++
确实会对*s
产生影响,因为它会改变s
指向的内容,如果s
指向其他位置,那么当然是表达式*s
将会改变。但是它对s
之前指出的值没有影响。
为了说明这一点,请考虑在字符strlen
上调用str
char* str = "abcd";
:在循环开始时s
指向str[0]
,因此{ {1}}等于'a',因为*s
等于str[0]
。完成'a'
后,s++
现在指向s
。现在str[1]
等于*s
,因为'b'
等于str[1]
,但'b'
和str[0]
的内容均未发生变化。
答案 1 :(得分:1)
指针的副本,是的。始终复制参数。同样,函数可以将参数修改为自己的局部变量,而不会影响原始变量,使用指针也可以这样做。
通过递增s++
,您与s = &s[1]
或s = s + 1
进行相同操作,并将s
修改为本地变量,此更改不会传播到*s
调用者中的原始指针。
只有修改指针指向的值,就像修改char** var
时一样,它会在调用者中修改它。这就是为什么在尝试修改指针本身时,你必须使用指向指针的指针,例如:{{1}}