在阅读stackoverflow中的一些问题和答案时,我遇到了这个question
我试图理解它,但答案很难理解,特别是像
这样的术语静态存储时间
在翻译阶段无法评估表达
等...
此外,我认为常量总是常数(这是我从学校学到的)
有人可以让它有点容易理解吗?
答案 0 :(得分:2)
这里有两个几乎完全不相关的概念:
4+5
是一个常量表达式。const A=4;
使A
成为常量表达式有时在某些上下文中,因为它是const
并从常量表达式{{1}初始化}}。 (这仅适用于C ++,而不适用于C)4
B=A;
本身可能是一个常量表达式,但A
是一个变量,本身可能不是常量表达式。B
变量是函数(或结构)承诺不会改变的变量,但其他东西可能会改变同一个变量。答案 1 :(得分:2)
在C中(与C ++不同),只有当表达式中的每个值都是数字常量或枚举值的名称时,算术表达式才是“常量表达式”。也就是说,虽然您可能已将变量声明为static const int
,但您仍然无法在常量算术表达式中使用该(常量)变量。
请注意,“常量表达式”是由定义C语言的正式标准定义的短语。还有其他表达式在直觉上是不变的,但它们不包含在正式定义中。
具有“静态存储持续时间”的变量只是在整个程序执行过程中存在的变量。大多数此类变量是全局变量(即不是任何函数的一部分,甚至不是main
的一部分),但在C和C ++中,您可以在函数范围内具有static
变量。这样的变量只初始化一次,无论调用函数多少次,它都只存在一个实例。
全局变量和具有静态存储持续时间的其他变量只能根据上述定义初始化为常量表达式。 是它们是const
变量的情况。问题只是变量具有静态存储持续时间,这意味着它们必须在程序执行之前初始化。 (在程序执行过程中存在具有静态存储持续时间的变量,因此如果它是初始化 - 即给定初始值,而不是在程序执行期间分配值 - 初始化必须在程序执行之前进行。)
在C ++中,声明为static const
的变量被视为常量值,因此它可以出现在常量表达式中。但是,在C中,情况并非如此,因此C编译器不需要跟踪static const
变量的初始值。
答案 2 :(得分:1)
您对const
和constant
感到困惑。
const
装饰器装饰一个变量,它必须有一个内存位置。(但register
不一定是真的。)它主要向人类和编译器显示这个变量的值不应该是要改变。
constant
是一个表达式,编译器知道。
所以,如果你这样做:
const float PI = 3.14;
在文件范围内,它将分配内存并拥有static storage duration
,它与进程的生命周期基本相同。
但如果你这样做:
#define PI2 (3.14)
这是一个不同的故事,因为没有记忆会包含这些信息。
所以,如果你写:
float foo1 = 2 * PI;
float foo2 = 2 * PI2;
您可以确保在编译后foo2
将被6.28
直接分配给foo1
,而{{1}}是否如此是实现定义的,因为它实际上取决于称为常量的优化技能取代
答案 3 :(得分:1)
在C中,const
- 限定变量与常量不同。整数文字50
和100
是常量表达式;它们的值在编译时是已知的(也就是说,它们可以在转换阶段进行评估,这意味着当编译器将源代码转换为机器代码时)。但是,变量 a
,c
和d
的值不会设置为运行时间 1 ;这意味着它们不能在需要编译时常量的上下文中使用 2 (它们在翻译阶段不能进行评估)。所有const
限定符都告诉编译器拒绝任何在初始化后尝试修改这些变量的代码。
链接问题中的问题是endX
和endY
在任何函数之外的文件范围内声明。因此,变量具有静态存储持续时间,这意味着当程序首次加载到内存中时,它们的存储被搁置,在main
执行之前,并且一直持续到程序终止 3 。由于它们是在main
执行之前加载的,因此无法使用在 main
执行之后 static const
之前不知道其值的表达式初始化它们。
<小时/> 1。我知道至少有一个版本的gcc会构建可执行文件,这样任何
main
- 限定变量在加载程序时都会设置初始值;然而,它们仍然被视为在static const
开始之前它们尚未被初始化。
static
- 限定变量 被认为是该语言的编译时常量。