仅修改void函数能否修改char变量值?出现段错误是什么原因
问题解答
核心基础逻辑
首先原代码的修改无效是因为值传递规则:函数形参是实参的独立拷贝,修改形参不会对外部实参产生任何影响,所以你原来写的void foo(char x) {x='b';}只是改了函数内部的临时变量x,完全碰不到main里的ch。
段错误的具体原因
你改成指针版本还报错,是两种问题共同导致的:
- 首先原代码里
ch是const char类型,被编译器存储在只读内存段,任何修改这个内存的操作都会触发未定义行为,大概率直接报段错误。 - 其次如果你只改了foo的参数定义为
char *x,但main里的调用还是写的foo(ch),相当于把字符'a'的ASCII码值(97)当成内存地址传入,访问这个非法地址也会直接触发段错误。
实现输出'b'的修改方案
前提说明
如果完全不修改main函数的任何代码、仅修改foo函数,是不可能实现需求的:
- 原main里的
ch是const修饰的,本身就禁止修改 - 原main里调用foo是值传递,foo拿不到
ch的内存地址,没有修改原变量的途径
最小修改方案(仅额外调整main里ch的修饰符和foo调用方式,其余不动)
首先把main里的ch改为非const:char ch = 'a';,再修改foo函数和对应的调用方式:
// 仅修改foo函数如下 void foo(char *x) { *x = 'b'; } // main里调用foo的语句同步修改为传地址 foo(&ch);
修改后逻辑:指针x存储了外部ch的内存地址,通过*x可以直接操作这个地址上存储的内容,就能成功把ch的值修改为'b'。
非const char变量的跨函数修改规则
对于非const的char变量,要在其他函数内修改它的值,必须通过指针传地址的方式操作,值传递永远只能修改形参的临时拷贝,不会影响原变量。
内容的提问来源于stack exchange,提问作者rockheaded
相关产品推荐
相关产品推荐

