为什么要使用静态"常量"而不是实际值?

时间:2016-12-30 17:42:54

标签: c++ c

我正在查看最小二乘法的代码,我遇到了以下几行:

static double one = 1.0;
static double p1 = 0.1;
static double p5 = 0.5;
...

我想知道为什么有人会为static定义1.0。例如,我可以理解为pi添加某些内容,但是对于1.00.1等琐碎的数学值等等?我认为它会降低代码的可读性,但它可能还有其他一些我缺失的好处。

那么,这些定义是否有原因?或者,如果它没有与现代代码一起使用,那么旧的编译器是否有任何理由?我知道我正在查看的代码已经从FORTRAN转换为C / C ++。 FORTRAN中是否有任何理由?

5 个答案:

答案 0 :(得分:6)

  

我知道我正在查看的代码已转换为C / C ++   FORTRAN。 FORTRAN中是否有任何理由?

FORTRAN对所有子例程参数使用pass-by-reference。但是,与其他具有pass-by-reference的语言不同,它仍然允许您将“rvalues”作为参数传递。在幕后,FORTRAN编译器转换代码如下:

CALL SUBFOO(X + Y, 4)

代码如

TEMP1 = X + Y
TEMP2 = 4
CALL SUBFOO(TEMP1, TEMP2)

这正是你的C ++代码正在做的事情:创建变量以便将指针(或引用)传递给子程序FORTRAN-style。

当然,这不是惯用的C或C ++。通常情况下,您会按价值传递double

(从我对this question的回答中复制的代码示例。)

答案 1 :(得分:5)

使用

static double one = 1.0;
static double p1 = 0.1;
static double p5 = 0.5;

对我来说没什么意义。如果用更有意义的东西命名变量,那将是有意义的。我看到了类似的价值:

static double defaultCoefficient = 1.0;
static double defaultRateOfIncrease = 0.1;
static double defaultRatio = 0.5;

在第二组中,在代码中使用变量比使用相应的常量更有意义。

让它们保持不变会更有意义。

static double const defaultCoefficient = 1.0;
static double const defaultRateOfIncrease = 0.1;
static double const defaultRatio = 0.5;
  

我知道我正在查看的代码已从FORTRAN翻译为C / C ++。

如果翻译是由程序完成的,那么为什么变量的命名方式是可以理解的。

如果翻译是由人完成的,他们可能会遵循一些关于如何快速移动事物的准则,而不一定通过理解代码来创建有意义的变量名。

答案 2 :(得分:5)

我见过这种情况的一个案例是使用哈佛架构的一些(较旧的,嵌入式)平台。

假设我有一个(外部库)函数,它将一个指针作为参数:

void Foo(double *Bar);

如果我想将常量传递给此函数,我显然不能直接写它。我必须在开幕式中这样做,所以我可以采用one的地址为例。

Foo(&one);

在某些哈佛平台上,const值放在程序ROM或闪存而不是RAM中,因此无法使用ROM地址而不是所需的RAM地址。

然后将它变为全局(静态)变量,以便在启动代码中初始化一次(从ROM复制到RAM的值一次),而不是每次需要它时使其成为自动变量。

我承认的利基用例。

答案 3 :(得分:3)

不,这个常数很愚蠢。如果没有其他原因,它实际上不是一个常数

答案 4 :(得分:1)

实际上有充分的理由这样做,它涉及软件开发过程本身。

假设您有一个翻译单元,它使用某个数字参数调用某个函数,当然您可以使它成为常量:

static const double epsilon = 1.e-3;

漂亮,干净的代码。但是现在你意识到你设置的epsilon并不是那么好,你需要一个更好的epsilon。你没有确定的方法来确定它应该是什么,所以你去做一些试验和错误:

static const double epsilon = 1.e-4;

您重建了程序。它仍然不是好事。如果再次更改它,则必须等待构建完成,并且在一些非平凡的项目上可能需要一段时间。怎么办?

好吧,调试器允许你改变变量的值,只要它们驻留在内存中(而不像真正的常量那样被删除)。所以我们做了以下事情:

static double epsilon = 1.e-4;

现在我们在该文件中的某处设置断点。我们可以修改epsilon而不必每次都重建我们的程序。我们最终节省了宝贵的开发时间。我们在没有时间找到合适的价值。

我们不保留 - const吗?不。这是一个常量,因此在检查我们的代码之前我们将其标记为const。保留非常量是代码气味。没有其他目的。