@[TOC](C++ 变量和基本类型)

C++ 变量和基本类型

声明与定义:

c是支持分离式编译的,因此为了支持分离式编译,C中声明与定义是分开的。

声明就是让程序知道有这个名字

定义就是创建一个与名字有关的实体

如果想声明却不定义,就在变量前面加关键字extern,而且不能显式的初始化变量:

extern int i;//声明却没定义i
int i; //声明并且定义i

任何显式初始化的声明即成为定义,如果前面加了extern关键字也是一样。并且如果在函数体内初始化由extern关键字标记的变量的话,会直接报错。

extern int i=1//定义

值得注意的是,变量只能被定义一次,但可以被声明多次
在多文件中,如果多个文件想共用一个变量,那么这个变量的定义只能出现在一个文件中,其他文件则必须声明该遍变量

//file1.cpp
int x=1;
//file2.cpp
extern int x;
//file3.cpp
extern int x;

引用:

引用就是为对象起另外的名字

C++在定义引用应用时就会把它与初值绑定在一起,而不是拷贝给它。并且,一旦初始化完成无法将引用绑定到另外一个对象上。因此,引用必须初始化。

要牢记的是,引用的类型必须与所引用对象的类型一致,并且不能与字面值或某个表达式的计算结果绑定在一起

除了以下两种情况:

  1. 初始化常量引用时允许将以任意表达式作为初始值,只要表达式的结果能转换成对应类型即可。
int i = 10;
const int &x1 = 2 * i;//正确
int &x2 = 2 * i;//错误,因为x2并非一个常量引用

指针:

void* 指针能存储任何对象的地址,但是并不能通过 void*指针操作所指对象,因为不知道这个指针指的是什么类型。

指针和constexpr

在constexpr的声明中如果定义了一个指针,constexpr仅对指针有效,与指针所指对象无关。

const int *p = nullptr;//指向整数常量的指针
constexpr int *p = nullptr;//指向整数的常量指针

const:

初始化:

默认状态下,const对象仅在文件内有效。 在编译的过程中,编译器会把所有用到该const变量的地方都替换成相应的值。所以,每个文件必须知道const的初始值(const对象也必须初始化)。但由于默认状态下,const对象仅在文件内有效,当多个文件同时出现同名的const变量时,其实就相当于分别定义了不同的变量。
如果想只定义一次怎么做呢?只需要无论是声明还是定义都标记extern关键字即可。

//fill1.cpp
extern const i=1;
//file2.cpp
extern const i;

const的引用:

把引用绑定到const对象上,即为对常量的引用。但与普通引用不同的是不能让非常量引用指向一个常量变量。

初始化常量引用时允许将以任意表达式作为初始值,只要表达式的结果能转换成对应类型即可。
虽然不能让非常量引用指向一个常量对象,但是常量引用所绑定的对象却可以是非常量对象,只是不能通过常量引用对绑定的对象进行修改。

int i=10;
int x1& = i;//正确
const int x2& = i;//正确
x1 = 0//正确
x2 = 0//错误,不能通过x2修改i

const与指针

请分清楚指向常量的指针常量指针

指向常量的指针:

const int x=1;
const int *p = &x;//p为指向常量x的指针
int *p = &x; //错误,因为p只是个普通指针

常量指针(不变的指针而不是指针指向的值):

int x=0;
int *const p = &x;//p为常量指针
const int xx=0;
const int *const pp= &xx;//pp为指向常量的常量指针

const总结

总的来说,const分为顶层const以及底层const。其中顶层const指本身是一个常量,可以表示任意的对象是常量。而底层const则与指针和引用等符合类型有关,表示所指对象是一个常量。(存在同时是顶层和底层const的情况)

int i=0;
int *const p1 = &i;//顶层const
const int p2 = i;//顶层const
const int *const p3 = &p2;//左边的const是底层const,右边的const是顶层const
const int &x = p2;//底层const

decltype

deltype((var))(注意是双层括号)时结果永远是引用。

deltype(var)的结果当var是引用时结果才是引用。

如果表达式是解引用操作,则deltype将得到引用类型。

自定义数据结果

C++11规定可以为数据成员提供类内初始值

Q.E.D.