每个人都知道C / C ++函数参数是按值传递的。那么为什么有些人坚持认为正确的风格是在修改之前制作函数参数的本地副本?例如,他们会写:
void baz(unsigned int *ptr)
{
unsigned int *lPtr = ptr;
for(int i = 0; i < 10; i++)
{
foo(*lPtr++);
}
}
而不是:
void baz(unsigned int *ptr)
{
for(int i = 0; i < 10; i++)
{
foo(*ptr++);
}
}
似乎第二种方式更易于阅读,因为它的变量较小。
答案 0 :(得分:3)
唯一的理由是对于更大的函数,有人可能会在函数底部添加新功能而没有意识到参数被修改或在之前变得无效。
想象:
int bighorriblefunction(const char * astr)
{
// hundreds of lines of horribleness
while ( * astr ) { /* something */ ++ astr ; }
// more pages of code
/** author two adds later */
if ( ! strcmp(astr, "magicvalue") ) { /** do this really important thing **/ return 1 ; }
return 0 ;
}
它会让作者两次意识到新代码永远不会运行。
答案 1 :(得分:2)
他们这样做是因为调试时原始值很有用。
答案 2 :(得分:1)
我认为这是因为代码的作者在baz()
的第一个版本中编写了变量的声明,然后他重构了代码,它将for循环中的代码移动到函数{{ 1}},作者错误地没有删除变量。变量是纯粹的浪费。希望这有帮助!
答案 3 :(得分:1)
这是一个穷人的界面与实现分离的版本。
假设你在一年前写过这段代码:
class Foo
{
public:
void bar( const char *where )
{
// The dreaded copy
const char *destination = where;
// The actual implementation that in the real world may take 500
// lines of code with 20 references to the variable destination
}
};
现在,一年之后,你想让参数 where 可选,默认为该类的成员变量。唉,你不记得那500行代码到底是做什么的!幸运的是,您在使用前通过复制参数来保存:
class Foo
{
public:
void bar( const char *where = NULL)
{
// Hooray! I only have to change 1 line here!
const char *destination = where? where : m_MyHomeDir.c_str();
// The actual implementation that in the real world may take 500
// lines of code with 20 references to the variable destination
}
private:
std::string m_MyHomeDir;
};
答案 4 :(得分:0)
如果你是用C ++编写的,只需使用:
std::for_each(ptr, ptr+10, foo);
我知道,这并没有直接回答这个问题,但确实指出它通常应该是无关紧要的事实。如果它是相关的,你可能需要重写代码。
答案 5 :(得分:0)
我不清楚这些“有些人”是谁(我从来没有听说过这种要求),但我能想到的唯一正当理由是它有助于调试:如果调试器停止了函数在中间,你可以看到它最初调用的参数值。但是在大多数情况下,只需向上移动一个调用框架并查看传递给函数的表达式的值,就可以实现相同的功能。