为何while循环中指针优先级的表现存在差异?
关于
*s++执行逻辑差异的疑问与解答 问题描述
用户提出:*s++为右至左结合求值,但main函数内的while循环中*s++按*(s++)执行,而str_cpy函数的while循环中*s++却看似按(*s)++执行,询问该差异的原因。
示例代码
int main(void) { char* s = "hello world"; char* p; str_cpy(p, s); printf("%s\n", p); // prints --> hello world while(*s++) { // *s++ is working as *(s++) printf("%c", *s); // prints --> ello world skips the 'h' character } return 0; } void str_cpy(char* p, char* s) { while(*p++ = *s++); //*s++ is working as (*s)++ }
解答
首先明确:*s++的优先级和结合性是固定的,永远等价于*(s++),不存在两种执行逻辑。你觉得str_cpy里的表现像(*s)++,是对代码逻辑的误解,具体拆解如下:
main函数中的循环逻辑:
while(*s++)的执行步骤是:先解引用当前s指向的字符(第一次是'h'),判断该字符是否为非0(非'\0'),判断完成后s指针自增一位。进入循环体后,printf("%c", *s)访问的是已经自增后的s指向的字符('e'),所以最终输出跳过了'h',这完全符合*(s++)的行为。str_cpy函数中的循环逻辑:
while(*p++ = *s++)的执行顺序是:- 先解引用
s当前指向的字符(比如第一次是'h'); - 将该字符的值赋值给
p当前指向的内存位置; - 赋值完成后,
s和p指针各自自增一位; - 判断赋值的结果(也就是被复制的字符)是否为'\0',如果是则终止循环。
你觉得它像(*s)++,是因为最终复制出了完整的原字符串,但实际上(*s)++会修改原字符串的字符值(比如把'h'改成'i'),但这里原字符串"hello world"完全没有被修改,只是指针s在逐个移动读取字符。本质上这里的*s++还是*(s++),只是用法不同导致表现看起来有差异。
- 先解引用
另外需要注意:示例代码中main函数里的char* p;是未初始化的野指针,直接传给str_cpy进行赋值会导致未定义行为,实际使用时需要先给p分配足够的内存(比如声明为char p[20];或者用malloc动态分配)。
内容的提问来源于stack exchange,提问作者Aditya Patel
相关产品推荐
相关产品推荐

