The New C++ -- 变量(4. const限定符和constexpr说明符 )
2012-02-10 12:19
337 查看
注意:constexpr为C++11标准,某些编译器可能还不支持该语法。
我们已经知道了字面值常量的值是不可更改的,所以称之为常量。变量是内存中的一块存储空间,我们可以读写里面的内容。但有时候我们也需要一种机制能够阻止随意的修改一个变量的值,这时候我们就要用到const限定符(const-qualifier)。在定义或者声明一个变量的时候,const限定符可以放在我们前面讲过的类型说明符前面或者后面表示该变量的值不可被更改。要注意的是,如果变量定义或者声明的时候有const限定符,那么一定要进行初始化。因为const变量不可以后来被赋值。对基本数据类型来说,这也是初始化和赋值的一个细微差别:可以初始化一个const变量,但不可以赋值。例如,
小知识:const限定符可以放在普通的类型说明符前面,例如const unsigned long,const long long等,也可以放在普通的类型说明符后面,例如unsigned const,long double const,等等。无论你喜欢放在前面还是放在后面,最好在同一个程序中保持位置一致。很多人提倡放将const限定符放在类型说明符后面,但C++的创造者Bjarne Strostrup博士自己更喜欢放在前面。
const限定符在语法上也是类型说明符的一种,但是他不可单独使用,必须和其他的类型说明符搭配使用而表明不可改变(constant)的性质。因为const限定符也是类型说明符,所以const变量和非const变量在C++中并不是同一种类型,虽然他们之间还是有着千丝万缕的联系,我们以后会详细讲述。你现在要记住的便是int和const int并不是同一种类型。
我们已经知道,const变量不能被修改。C++还提供了一种更为``严格''的constexpr说明符(constexpr-specifier),在变量被声明或者定义的时候,如果类型说明符前面或者后面用了constexpr说明符,则表明该变量是一个const变量同时该变量必须被初始化。你也许说,这个const不是一样么?constexpr更加严格,用来初始化该变量的表达式必须是一个``常数表达式''。也就是说constexpr变量是一个由常数表达式初始化的const变量。关于常数表达式,我们以后还会详细谈起,对于基本数据类型来说,常数表达式是由字面值常量,constexpr限制的变量,和由常数表达式初始化过的const变量组成的表达式。换句话说,常数表达式的值在编译期间就可以确定。例如,
constexpr的变量的值必须是编译器在编译的时候就可以确定的。上例中因为nonconst_var的值在语法上来讲,运行期间可能被更改,所以编译期间无法确定,不属于常数表达式。因为const_var2是由非常数表达式来初始化的,所以const_var2也不是常数表达式。但const_var2本身的声明,定义及初始化是合法的。constexpr比const更严格,用来初始化constexpr_var2和constexpr_var3的也都不是常数表达式,所以他们的定义都是错误的。
小知识:constexpr和const一样,都可以放在类型说明符的前面或者后面。但和const不一样,绝大多数人的习惯都会将constexpr放在类型说明符前面。所以除非你知道你在做什么,请将constexpr放在类型说明符前面。还有一点和const不一样的是,constexpr并不是类型说明符,但是constexpr定义的变量都是const类型的变量。
小知识:volatile限定符和const限定符是并列的关系。volatile可以放在类型说明符前面或者后面,也可以和const或者constexpr一起用。const和constexpr表明该变量不可在程序中被修改,而volatile表明该变量的值随时可能被硬件,操作系统或者另外的线程改变,编译器不可以对这个变量随意的优化。volatile一般只有在嵌入式系统或者多线程环境下才会被用到。const和volatile一起用并不矛盾。const表示程序本身不可以修改这个变量,volatile表示这个变量可以随时被其他的东西修改(除程序本身之外还有其他的可能修改变量的东西例如硬件异常等)。const限定符和volatile限定符一般被和称为cv限定符(cv-qualifier)。
我们已经知道了字面值常量的值是不可更改的,所以称之为常量。变量是内存中的一块存储空间,我们可以读写里面的内容。但有时候我们也需要一种机制能够阻止随意的修改一个变量的值,这时候我们就要用到const限定符(const-qualifier)。在定义或者声明一个变量的时候,const限定符可以放在我们前面讲过的类型说明符前面或者后面表示该变量的值不可被更改。要注意的是,如果变量定义或者声明的时候有const限定符,那么一定要进行初始化。因为const变量不可以后来被赋值。对基本数据类型来说,这也是初始化和赋值的一个细微差别:可以初始化一个const变量,但不可以赋值。例如,
int nonconst_var = 3; nonconst_var = 4; const int const_var1 = 5; int const const_var2 = 6; const_var1 = 7; //错误:不可赋值 const_var2 = 8; //错误:不可赋值 const int const_var3; //错误:必须初始化
小知识:const限定符可以放在普通的类型说明符前面,例如const unsigned long,const long long等,也可以放在普通的类型说明符后面,例如unsigned const,long double const,等等。无论你喜欢放在前面还是放在后面,最好在同一个程序中保持位置一致。很多人提倡放将const限定符放在类型说明符后面,但C++的创造者Bjarne Strostrup博士自己更喜欢放在前面。
const限定符在语法上也是类型说明符的一种,但是他不可单独使用,必须和其他的类型说明符搭配使用而表明不可改变(constant)的性质。因为const限定符也是类型说明符,所以const变量和非const变量在C++中并不是同一种类型,虽然他们之间还是有着千丝万缕的联系,我们以后会详细讲述。你现在要记住的便是int和const int并不是同一种类型。
我们已经知道,const变量不能被修改。C++还提供了一种更为``严格''的constexpr说明符(constexpr-specifier),在变量被声明或者定义的时候,如果类型说明符前面或者后面用了constexpr说明符,则表明该变量是一个const变量同时该变量必须被初始化。你也许说,这个const不是一样么?constexpr更加严格,用来初始化该变量的表达式必须是一个``常数表达式''。也就是说constexpr变量是一个由常数表达式初始化的const变量。关于常数表达式,我们以后还会详细谈起,对于基本数据类型来说,常数表达式是由字面值常量,constexpr限制的变量,和由常数表达式初始化过的const变量组成的表达式。换句话说,常数表达式的值在编译期间就可以确定。例如,
int nonconst_var = 100; const int const_var1 = 2; const int const_var2 = nonconst_var; constexpr int constexpr_var1 = 3 + const_var1 * 4; //成立 constexpr int constexpr_var2 = 3 + nonconst_var * 4; //错误 constexpr int constexpr_var3 = 3 + const_var2 * 4; //错误
constexpr的变量的值必须是编译器在编译的时候就可以确定的。上例中因为nonconst_var的值在语法上来讲,运行期间可能被更改,所以编译期间无法确定,不属于常数表达式。因为const_var2是由非常数表达式来初始化的,所以const_var2也不是常数表达式。但const_var2本身的声明,定义及初始化是合法的。constexpr比const更严格,用来初始化constexpr_var2和constexpr_var3的也都不是常数表达式,所以他们的定义都是错误的。
小知识:constexpr和const一样,都可以放在类型说明符的前面或者后面。但和const不一样,绝大多数人的习惯都会将constexpr放在类型说明符前面。所以除非你知道你在做什么,请将constexpr放在类型说明符前面。还有一点和const不一样的是,constexpr并不是类型说明符,但是constexpr定义的变量都是const类型的变量。
小知识:volatile限定符和const限定符是并列的关系。volatile可以放在类型说明符前面或者后面,也可以和const或者constexpr一起用。const和constexpr表明该变量不可在程序中被修改,而volatile表明该变量的值随时可能被硬件,操作系统或者另外的线程改变,编译器不可以对这个变量随意的优化。volatile一般只有在嵌入式系统或者多线程环境下才会被用到。const和volatile一起用并不矛盾。const表示程序本身不可以修改这个变量,volatile表示这个变量可以随时被其他的东西修改(除程序本身之外还有其他的可能修改变量的东西例如硬件异常等)。const限定符和volatile限定符一般被和称为cv限定符(cv-qualifier)。
相关文章推荐
- The New C++ -- 变量 (5. sizeof表达式,typeid表达式和地址操作符)
- The New C++ -- 变量 (6. 变量名的声明点和作用域)
- The New C++ -- 变量 (7. 左值,右值)
- The New C++ -- 变量(0)
- The New C++ -- 变量(1. 变量的声明和定义)
- The New C++ -- 变量 (2. 变量的赋值和输入)
- The New C++ -- 变量 (3. 变量的初始化)
- The New C++ -- 基本数据类型和字面值常量 (2. 整型和整数字面值常量)
- c++: Does the new operator for dynamic allocation check for memory safety?
- The New C++ -- 基本数据类型和字面值常量 (3. sizeof表达式和typeid表达式)
- The New C++ -- 基本数据类型和字面值常量 (6. 布尔型和布尔字面值常量)
- C++程序运行时内存布局之----------局部变量,全局变量,静态变量,函数代码,new出来的变量
- C++成员变量的new操作应该放在构造函数中吗?
- 在C++中不要大量用new申请小变量
- C++new出来的和直接声明的对象变量有什么不同呢?
- The New C++ -- 目录
- The New C++ -- 基本数据类型和字面值常量 (7. 浮点型和浮点字面值常量)
- C++程序运行时内存布局之----------局部变量,全局变量,静态变量,函数代码,new出来的变量
- C++11 - the new ISO C++ standard and GCC
- The New C++ -- 基本数据类型和字面值常量 (8. 字符串字面值常量)