-
- 3.1. const的引用
- 3.2. 指针和const
- 3.2.1. 顶层const和底层const
- 3.3. 常量表达式
- 3.3.1. 指针和constexpr
c++基础
1. 变量声明和定义的关系
分离式编译:允许将程序分割为若干个文件,每个文件可被独立编译
c++为支持分离式编译,于是将声明和定义区分开
- 声明:使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明
- 定义:负责创建与名字关联的实体
如果想声明一个变量而非定义它,必须在变量名前添加关键字extern,而不要显示地初始化变量
1 | extern int i; //声明i而非定义i |
注意:
- 如果要在多个文件中使用同一个变量,就必须将声明和定义分离。此时,变量的定义只能出现在一个文件中,而其他用到该变量的文件必须对其进行声明
- 任何包含显式初始化的声明即成定义
- 在函数体内部初始化一个由extern关键字会产生错误,但是可以在函数体外给extern变量赋初值
1 | int main() { |
1 |
|
2. 引用
此处指的是“左值引用”
2.1. 引用即别名
引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字。
引用不是对象,代表不能定义引用的引用。而且,引用只能绑定在对象上,不能与字面值或某个表达式的计算结果绑定在一起。
下面的例子会报错,非常量引用的初始值必须为左值
1 | int main() { |
2.2. 和指针的区别
指针本身是一个对象,而引用不是,于是可以定义指向一个指针的引用
1 | //right |
3. const限定符
特点:
- const所定义的值不能被改变
- 默认状态下,const对象仅在文件中有效,如果想要共享,需要添加extern标识符
3.1. const的引用
也叫作常量引用
1 | const int ci = 1024; |
与一般的引用对比,其特点如下:
- 不能修改他所绑定的对象
- 允许将一个常量引用绑定非常量的对象,字面值,甚至是一个表达式
为什么能够将常量引用绑定一个非常量的对象呢?
答:编译器生成了一个临时量。
3.2. 指针和const
指向常量的指针和常量指针的区别:
- 前者不能用于改变所指对象的值,要想存放常量对象的地址,只能使用指向常量的指针,但是没有规定所指对象必须是一个常量。
- 常量指针必须初始化,且一旦初始化完成,则它的值不能再改变了,可以通过其操控指向的对象
1 | int main() { |
1 | int main() { |
总结:
- 常量指针,指针本身是常量,不能改变指针的值
- 指向常量的指针,指向的对象是常量,不能改变对象的值
3.2.1. 顶层const和底层const
顶层const指指针本身是个常量,底层const指所指对象是一个常量。
注意的点:
- 执行对象拷贝时,拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换。
- 用于声明引用的const都是底层const
1 | int i = 0; |
p3既是一个顶层const也是一个底层const,拷贝p3时可以不在乎它是一个顶层const
1 | p2 = p3;//正确,具有相同的底层const |
3.3. 常量表达式
常量表达式:是指值不会改变且在编译过程中就能得到计算结果的表达式
1 | const int a = 20;//是一个常量表达式 |
可以使用constexpr类型以便由编译器来验证变量值是否是一个常量表达式
1 | constexpr int mf = 20; //20是常量表达式 |
常量表达式的值为字面值类型,算术类型、引用和指针属于字面值类型
3.3.1. 指针和constexpr
如果在constexpr声明中如果定义了一个指针,限定constexpr仅对指针有效,与指针所指的对象无关
1 | const int *p = nullptr; //p是一个指向整型常量的指针 |
4. 类型别名
定义类型别名的两种方法:
- typedef
- using(新标准)
1 | typedef double wages; |
要注意指针、常量和类型别名的关系:
1 | typedef char *pstring; |
其中const pstring 为指向char的常量指针,而非指向常量字符的指针!并不是下面这种方式
1 | const char *cstr = 0; |
5. auto类型说明符
可以使用auto类型说明符,让编译器替我们去分析表达式所属的类型
1 | auto a = 1 + 2; |
auto也能用来声明多个变量,前提是变量的初始基本数据类型必须一样
1 | auto i = 0, *p = &i; //ok,i是整数,p是整型指针 |
auto一般会忽略掉顶层const,顶层const会保留,可以在auto前加一个const修饰符来推断出一个顶层const