[英]What happens to a parameter if it is passed twice? Once by value and once by reference? Will it be modified or not?
[英]What happens to a parameter passed by value that is modified locally?
我很清楚,在C / C ++函数之外,修改按值传递的函数参数无效,但是编译器允许这样做-但是会发生什么? 是否由参数构成本地副本,并且可以在函数中进行修改 ?
#include <stdio.h>
void doSomething( int x )
{
x = 42;
printf( "The answer to Life, the Universe and Everything is (always): %i!\n", x );
}
int main( int argc, char **argv )
{
int a = 0;
doSomething( a );
return -a;
}
现在,这总是无错误地退出,但是在事物方案(内存空间)中函数中以x
表示的值保留在哪里?
我想(合并的声明和定义)应该开始:
void doSomething( const int x )
我会被任何不正派的编译器打败。
对于函数doSomething()
, x
在函数本地。 它具有与在函数体开头定义的任何其他变量类似的作用域。
一般而言, x
仅存在于doSomething()
函数的范围内。 一旦doSomething()
被调用(并且传递了参数doSomething()
就定义了x
并在控件返回后销毁了x
。 只要执行了函数调用(即变量仍在作用域内),参数就与任何其他变量相同,仅由函数调用中提供的参数进行初始化。
引用C11
,第§6.2.1章, 标识符范围
[...]如果声明标识符的声明符或类型说明符出现在功能定义的块内或参数声明列表中,则标识符具有块作用域,该作用域终止于相关块的末尾。 [...]
如您所知, x
是传递给函数调用的实际参数的本地副本 ,对函数内部对x
所做的任何更改都不会反映到调用方(实际参数)中,但是编译器没有理由抱怨因为该函数内部x
上的操作有效。
函数的value参数实际上是该函数的局部变量,但它是在函数调用中初始化的。 所以这些:
void f( int n ) {
n++;
}
和:
void g() {
int n = 0;
n++;
}
如果对f()的调用设为f(0),则它们实际上是相同的。 在这两种情况下,变量都将在函数退出时被丢弃。
形式参数x
是在从实际的参数存储器中的单独的对象a
,所以任何更改x
不会反映在a
。
正如其他人解释的那样, x
在doSomething
函数中是局部的,任何修改仅影响参数的局部副本。
但是请注意,C ++允许通过引用传递: doSomething()
定义中的很小变化将对该程序产生重大影响:
void doSomething( int& x ) {
x = 42;
printf( "The answer to Life, the Universe and Everything is (always): %i!\n", x );
}
使用上面的函数定义, main
变量a
实际上确实将其值更改为42
。 由于main()
的代码相同,因此此C ++功能可能导致代码混乱,尤其是对于C程序员而言。
值x是局部的,并保留在堆栈中。 每个函数都有其自己的堆栈部分,当程序进入函数时会保留该部分。 值x将位于堆栈的这一部分。 并且仅在定义它的功能范围内有效。 如果更改x,它将仅针对定义了x的函数进行更改。 如果函数结束(从函数返回),则为函数保留的堆栈将被破坏,因此值x也将被破坏。 因此x将不再可用,因为它不再存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.