**面试问题:**在不使用引用作为函数参数或不从函数返回值的情况下更改局部变量值
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
}
x
值需要更改
6条答案
按热度按时间q0qdq0h21#
答案是你不能。
C编程语言没有提供这样做的方法,而且 * 尝试 * 这样做总是会导致 * 未定义的行为 *。这意味着无法保证结果会是什么。
现在,你可能会试图利用未定义的行为来破坏C的运行时系统并改变其值。然而,是否这样做以及如何这样做完全取决于特定的执行环境。例如,当用最新版本的GCC和clang编译代码并启用优化时,变量
x
在输出代码中就不再存在了:它的名称没有对应的内存位置,因此您甚至不能直接修改原始内存地址。实际上,上面的代码大致生成了以下程序集输出:
如图所示,
100
是一个直接存储在ESI寄存器中的常量,在printf
调用之前,即使func
试图修改该寄存器,修改也会被编译后的printf
调用覆盖:不管你怎么掷骰子,答案都是:在编译后的输出中没有
x
变量,所以你不能修改它,甚至接受未定义的行为。你可以通过重写printf
函数调用来修改 output,但这不是问题所在。aiazj4mn2#
根据C语言的设计,以及局部变量的定义,如果不以某种方式使其可用,就无法从外部访问它。
使外部世界可以访问局部变量的一些方法:
extern
导出。klh5stk13#
哈克
仅更改
void func()
中的代码,创建define
。类似于“chqrlie”。
产出
4bbkushb4#
答案是你不能,但是...
我完全同意@virolino和@Konrad Rudolph的观点,我不喜欢我对这个问题的“解决方案”被认为是最佳实践,但既然这是某种挑战,人们可以提出这种方法。
define会将
int
设置为空。因此x
将是全局静态x
而不是局部静态x
。由于int main() {
行现在仅为main(){
,因此编译时会出现警告。它仅在返回类型为int的函数为special handling时才编译。umuewwlo5#
这种方法是笨拙和脆弱的,但面试官要求它。所以这里有一个例子,为什么C和C++是如此有趣的语言:
wydwbb8l6#
无聊的回答:我将使用一个简单的全局指针变量:
我不确定“发送引用”是什么意思,如果设置一个全局指针也算发送引用,那么这个答案显然违反了所述问题的奇怪规定,是无效的。
(On关于“奇怪的规定”这个主题,我有时候希望SO有另外一个标签,像
driving-screws-with-a-hammer
这样的东西,因为这是这些“脑筋急转弯”总是让我想到的。非常明显的问题,非常明显的答案,但是不,明白了,你不能使用那个答案,你被困在一个荒岛上,你的C编译器的for
语句在沉船中被破坏了,所以你应该像麦盖弗一样,用椰子壳和鼻屎来代替。偶尔,这些问题可以展示出良好的横向思维能力,而且很有趣,但大多数时候,它们只是愚蠢的。)