【发布时间】:2011-01-22 11:58:31
【问题描述】:
文章末尾:http://www.learncpp.com/cpp-tutorial/45-enumerated-types/
它提到了以下句子:
最后,与常量变量一样,枚举类型会显示在调试器中,这使得它们在这方面比#defined 值更有用。
“常量变量”是一个正确的术语吗?常量和变量不一样吗?
谢谢。
【问题讨论】:
文章末尾:http://www.learncpp.com/cpp-tutorial/45-enumerated-types/
它提到了以下句子:
最后,与常量变量一样,枚举类型会显示在调试器中,这使得它们在这方面比#defined 值更有用。
“常量变量”是一个正确的术语吗?常量和变量不一样吗?
谢谢。
【问题讨论】:
它是一个变量,因为它是一个可寻址的对象,而不是一个不可寻址的文字常量。
这可能是矛盾的,但语言标准通常使用术语变量来指代可寻址对象,并使用const 来指定只读可寻址对象。
【讨论】:
C++ 中的常量是一种特殊的变量。我知道这听起来可能与常识相矛盾,但在 C++ 中就是这样。
int var1 = 1;
int const var2 = 2;
它们的区别只是const关键字,它告诉编译器var2的值一旦创建就不能改变:
var1 = 2; // fine
var2 = 1; // compilation error!
这个简单的规则还会对const 变量强制执行进一步的约束,例如您不能创建对const 变量的非const 引用(否则您仍然可以通过该引用更改其值)。出于同样的原因,您也不能将var2 传递给具有签名f(int& i) 的函数。但是,您可以创建对它们的const 引用,使用它们的值等,就像使用任何“正常”变量一样。所以总的来说,它们就像任何其他变量一样。
【讨论】:
int const var2 = 2; 不要把const放在第一位。这意味着一个变量,它是一个 int const-lvalue,可能写成 int const&,请注意它是 const 而不是 int 的引用(或左值)(无论标准是什么)说,它混淆了语义和语法)。因此,constness 是类型信息(不幸的是),就像 reference aka lvalue 是类型信息一样。它不是一种特殊的变量类型(很遗憾)。
是的,用词有点矛盾。变量是根据定义而变化的东西,而常量是不根据定义而变化的东西。
除此之外,在 C++(和其他语言)中,人们仍然称它们为常量变量,因为我们本质上将任何具有名称的值都视为变量。
尽管说“恒定”,但请随意。
【讨论】:
常量是变量。在 C++(和大多数语言)中,将变量定义为常量只是告诉编译器不允许更改该变量。
【讨论】:
从表面上看这是一个明显的矛盾,并且可能是出于历史原因(“变量”用于指代与名称和类型相关联的内存位置)。
但是,我可以尝试证明该术语的合理性: 在编译时,它是一个变量——在优化之前,它具有变量的所有属性——占用内存,有一个位置等等——并且处理方式大致相同。 (相比之下,您提供的值如 43423L、3.141 或文字“somestring”不是变量。) 在运行时,它不能再更改,并且被视为常量。它是一种“一次写入变量”,您在源代码中设置。
【讨论】:
很多人都很困惑。在 K&R C 中,可以更改字符串文字。因此,文字是常量,意味着不可变是错误的。在 ISO C 和 C++ 中,一些 T 的 const 类型的变量也可以使用强制转换来更改。再说一遍,常量并不意味着不可变。正如@foo 上面指出的那样,由于优化,常量通常不具有变量的属性,实际上语义通常会指定它。另外不要忘记在 C 和 C++ 中有 常量表达式 有时称为编译时常量,用于数组边界,例如,一种永远不会与变量混淆的常量,同意吗?
这里有一个定义:常量是名称与值的绑定。有了这个定义,1 是一个常量,因为它是一个文字名称,并且绑定是隐式的。还有这里
enum {x};
void f();
有两个常量,即x 和f:它们是符号名称的绑定(在这种情况下,两个标识符,在C++ 中operator+ 也是一个名称,但不是一个标识符)。
现在,我将向您展示另一个令您惊讶的常数!
int y = 1;
是的,y 也是一个常数!它是名称y 与地址的绑定。
[如果在堆栈上,则从框架底部偏移]
所以实际上你的抽象语法中的几乎所有东西都是一个常数,如果你仔细考虑的话:)
【讨论】: