C++ 定义常数时包括算术运算

C++ 定义常数时包括算术运算,c++,constants,c-preprocessor,C++,Constants,C Preprocessor,所以我经常看到这样的事情: #define gf_PI f32(3.14159265358979323846264338327950288419716939937510) #define gf_PIhalf f32(3.14159265358979323846264338327950288419716939937510 * 0.5) 这意味着每次我在代码中使用gf_PIhalf时,都会计算半个PI值,对吗? 直接写半个π的值不是更好吗 这样做不是更好吗: #define gf_PI f32

所以我经常看到这样的事情:

#define gf_PI  f32(3.14159265358979323846264338327950288419716939937510)
#define gf_PIhalf  f32(3.14159265358979323846264338327950288419716939937510 * 0.5)
这意味着每次我在代码中使用gf_PIhalf时,都会计算半个PI值,对吗?
直接写半个π的值不是更好吗

这样做不是更好吗:

#define gf_PI f32(3.14159265358979323846264338327950288419716939937510)
const float gf_PIHalf = gf_PI * 0.5f;    // PIHalf is calculated once
最后,这样做不是最好的(为什么这似乎不是一种常见的做法):

这意味着每次我在代码中使用gf_PIhalf时,都会计算出半个PI值,对吗

不,不太可能


您可以合理地指望编译器在编译时(而不是运行时)执行乘法运算。

您的结论有些正确,只是
#define
版本几乎肯定会在编译时解决,而有关类型常量全局的部分是不常见的做法。它们是现代良好规范中的常见做法
#define
s对于这种用途来说几乎是行不通的。最佳做法是在未命名的命名空间中定义文件作用域全局变量:

namespace
{
    const float g_SomeGlobal = 123.456f;
}

这会阻止翻译单元之外的任何人“看到”g_SomeGlobal

你真的在乎你的程序是否再执行一次乘法吗?真的那么关键吗?这是一个很好的问题。我曾经问过一个关于内存限制和效率的类似问题,我认为我得到的标准答案类似于“老实说,在这个速度下,这并不重要。数据量如此之小,效率的比率不会受到太大影响。”我想在这种情况下,你会发现,与你每次都可以信任的重新计算相比,程序的效率并不一定会受到影响。如果你对算法有信心,我会追求纯粹的效率。看,一个好的编译器会优化成一个常数…@Smash:嗯,这不太可能成为瓶颈,但如果乘法运算实际上每次都会发生,并且会在一个经常调用的关键循环中使用,那么我看不出有什么理由不使用其他解决方案之一来确保它不会发生。@plast1K:这是一个常量。每次重新计算都不能让我再相信它了。
namespace
{
    const float g_SomeGlobal = 123.456f;
}