面试问题:不使用引用作为函数自变量或从函数返回值而更改局部变量值
void func()
{
/*do some code to change the value of x*/
}
int main()
{
int x = 100;
printf("%d\n", x); // it will print 100
func(); // not return any value and reference of x also not sent
printf("%d\n", x); // it need to print 200
}
Run Code Online (Sandbox Code Playgroud)
x 价值需要改变
答案是你做不到。
C编程语言无法做到这一点,并且尝试这样做总是会导致未定义的行为。这意味着不能保证结果会是什么。
现在,您可能很想利用未定义的行为来破坏C的运行时系统并更改值。但是,这是否以及如何工作完全取决于特定的执行环境。例如,当使用最新版本的GCC和clang编译代码并启用优化功能时,该变量将x不再存在于输出代码中:没有对应于其名称的存储位置,因此您甚至无法直接修改原始内存地址。
实际上,以上代码大致产生以下汇编输出:
main:
subq $8, %rsp
movl $100, %esi
movl $.LC0, %edi
xorl %eax, %eax
call printf
xorl %eax, %eax
call func
movl $100, %esi
movl $.LC0, %edi
xorl %eax, %eax
call printf
xorl %eax, %eax
addq $8, %rsp
ret
Run Code Online (Sandbox Code Playgroud)
如您所见,该值100是printf调用前直接存储在ESI寄存器中的文字。即使您func试图修改该寄存器,该修改也会被编译后的printf调用覆盖:
…
movl $200, %esi /* This is the inlined `func` call! */
movl $100, %esi
movl $.LC0, %edi
xorl %eax, %eax
call printf
…
Run Code Online (Sandbox Code Playgroud)
无论您将其切成小方块,答案是:x编译输出中没有变量,因此即使接受未定义的行为也无法修改它。您可以通过覆盖函数调用来修改输出printf,但这不是问题。
通过C语言的设计以及局部变量的定义,您不能在不以某种方式使它可用的情况下从外部访问它。
使局部变量可被外部访问的一些方法:
extern如果在文件级声明了变量,则将其导出(在所有函数之外)。哈克:只需更改代码void func(),即可创建一个define。
类似于@chqrlie
void func()
{
/*do some code to change the value of x*/
#define func() { x = 200; }
}
int main()
{
int x = 100;
printf("%d\n", x); // it will print 100
func(); // not return any value and reference of x also not sent
printf("%d\n", x); // it need to print 200
}
Run Code Online (Sandbox Code Playgroud)
输出量
100
200
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
249 次 |
| 最近记录: |