【问题标题】:Which is the better practice: global constant or #define? [duplicate]哪个是更好的做法:全局常量还是#define? [复制]
【发布时间】:2011-07-22 03:24:42
【问题描述】:

可能重复:
C++ - enum vs. const vs. #define

在我使用#define 之前,我曾经在我的主函数中创建常量并将它们传递到需要它们的地方。我发现我经常通过它们,这有点奇怪,尤其是数组大小。

最近我一直在使用 #define,因为我不必将 main 中的常量传递给每个单独的函数。

但现在我想起来了,我也可以使用全局常量,但由于某种原因,我对它们有点犹豫。

哪种做法更好:全局常量还是#define?

另外一个相关的问题:如我所描述的那样从我的 main 传递常量是一种不好的做法吗?

【问题讨论】:

标签: c++ c-preprocessor constants


【解决方案1】:

他们做的事情并不完全相同。 #define 允许您在编译时影响代码,而全局常量仅在运行时生效。

看到#define 只会给您带来额外的麻烦,因为没有检查您如何使用它,您应该尽可能使用全局常量,并且在必须时使用#define。这样会更安全,更易读。

至于从main 传递常量,这并不是不合理的,因为它使被调用函数更灵活地接受来自调用者的参数,而不是盲目地将其拉出某个全局。当然,在程序的整个生命周期内,实际上并不会期望该论点发生变化,而您并没有从中获得太多收益。

【讨论】:

  • 例如,将全局常量用于二维数组大小是否可以接受?我猜这是唯一的方法。
  • 不正确:宏让您在预处理时影响代码,而全局常量可能在编译时影响代码,并且可能只在运行时起作用。
  • @Alexander:您在技术上是正确的。我是故意简化的,例如编译时间 = 当我点击编译按钮时。
【解决方案2】:

使用常量而不是#define 是非常受欢迎的。 #define 会在它出现的每个地方愚蠢地替换令牌,并可能导致各种意想不到的后果。

传递值而不是使用全局变量是一种很好的做法。它使代码更灵活、更模块化、更可测试。尝试用谷歌搜索“从上面的参数化”。

【讨论】:

  • 取决于您使用全局变量的目的 - 例如,我个人认为有人拥有全局常量 PI 没有问题。
  • 此外,常量可以在命名空间或类中声明,并且可以设为受保护或私有。这一点,再加上常量是类型化的(宏替换不是),使得代码更安全。
  • 效率方面,例如一个字符串常量只会在内存中驻留一次。 #define 中的字符串将多次替换到您的代码中,并可能替换到您的可执行文件中。
  • @Stuart:当然是这样,所有的规则都是指导方针。
  • 二维数组需要原型中的列大小怎么办?
【解决方案3】:

永远不要使用#defines 或const 变量来表示数组大小;最好让它们明确。

代替:

#define TYPICAL_ARRAY_SIZE 4711

int fill_with_zeroes(char *array)
{
  memset(array, 0, TYPICAL_ARRAY_SIZE);
}

int main(void)
{
  char *za;

  if((za = malloc(TYPICAL_ARRAY_SIZE)) != NULL)
  {
    fill_with_zeroes(za);
  }
}

它使用一个(共享的,想象它在一个公共标题或其他东西中)#define 来传达数组大小,最好将它作为一个真正的参数传递给函数:

void fill_with_zeroes(char *array, size_t num_elements)
{
  memset(array, 0, num_elements);  /* sizeof (char) == 1. */
}

然后只需更改调用站点:

int main(void)
{
  const size_t array_size = 4711;
  char *za;

  if((za = malloc(array_size)) != NULL)
  {
    fill_with_zeroes(za, array_size);
  }
}

这使得大小在分配它的地方是本地的,被调用的函数不需要神奇地“知道”一些关于它的参数的东西,这些参数不是通过它的参数通过它的参数传达的。

如果数组是非动态分配的,我们可以做得更好,甚至在本地删除重复的符号大小:

int main(void)
{
  char array[42];
  fill_with_zeroes(array, sizeof array / sizeof *array);
}

这里,众所周知的sizeof x / sizeof *x 表达式用于(在编译时)计算数组中元素的数量。

【讨论】:

    【解决方案4】:

    常数更好。两者的唯一区别是常量是类型安全的。

    【讨论】:

    • 并且常量不会践踏所有的命名空间规则。
    【解决方案5】:

    您不应该像 const 参数那样使用用#define 定义的值。定义主要用于防止编译器在编译时根据您的需要(平台相关的选择、编译时的优化等)编译部分代码。

    因此,如果您出于这些原因不使用定义,请避免使用并使用常数值。

    【讨论】:

      猜你喜欢
      • 2015-11-03
      • 1970-01-01
      • 2013-12-19
      • 2017-12-30
      • 2018-08-11
      • 1970-01-01
      • 2011-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多