C语言中修改作为函数参数的字符串值无效,原因是什么?
为什么修改指针参数后外部变量没变化?
这是C语言里超级常见的指针误区,我给你拆解明白:
核心原因:C的参数都是值传递
不管你传的是普通变量还是指针,C语言都会复制一份参数的值给函数里的局部参数。你调用foo(s)的时候,其实是把s里存的"old string"的地址,复制了一份给函数里的return_string变量。这时候return_string和外面的s是两个完全独立的变量,只是初始值一样而已。
你在函数里写return_string = tmp;,只是把tmp指向的"new string"的地址,赋值给了这个局部的return_string。函数执行完,这个局部变量就被销毁了,外面的s根本没被碰过,所以输出还是原来的old string。
两种正确的解决方法
方法1:用指向指针的指针(二级指针)
如果要修改外面的指针变量本身,就得把指针的地址传进去,用二级指针来操作:
int foo(char **return_string) { char *tmp = "new string"; *return_string = tmp; // 直接修改外部指针变量的内容 return 0; } // 调用时传递指针的地址 char *s = "old string"; foo(&s); printf("%s\n", s); // 现在输出new string
这里&s是取s变量的地址,函数里的*return_string就是直接操作外面的s,把它指向的地址改成tmp的地址,这样外部的s就指向新字符串了。
方法2:让函数返回新指针
更简单的方式是让函数直接返回新的字符串地址,然后在调用处重新赋值:
char* foo() { char *tmp = "new string"; return tmp; } // 调用时接收返回值 char *s = "old string"; s = foo(); printf("%s\n", s); // 输出new string
这种方式逻辑更直观,函数给你新的地址,你把它赋值给原来的s就行。
补充说明
如果你的需求是修改字符串的内容(不是换个指针指向新字符串),比如s是存在栈上的数组:char s[] = "old string";,那直接传一级指针就能修改内容,比如strcpy(return_string, "new string");。但你的场景是要让指针指向新的字符串,所以必须用上面两种方法。
内容的提问来源于stack exchange,提问作者Robb1
相关产品推荐
相关产品推荐

