YaoCheng8667 的个人博客 YaoCheng8667 的个人博客

记录精彩的程序人生

目录
《C++ Primer》第二章:变量与数据类型
/    

《C++ Primer》第二章:变量与数据类型

1. 变量声明和定义的关系

  • 声明(declaration):使得变量(或函数)的名字为程序所知,规定对象的类型和名字。
  • 定义(definition):负责创建与名字相关联的实体,除了规定对象的类型和名字,还申请存储空间,有可能为变量赋一个初始值。

1.1 使用示例

extern int i;                             //声明i而未定义
int j;                                    //声明并定义i
extern void print();                      //声明一个函数
void print();                             //定义一个函数

1.2 声明的用途

C++ 分离式编译,多文件中可以使用同一变量或函数。主要用途有 3 点:

  1. 扩展外部变量的作用域(在同一个文件范围内)。
  2. 将外部变量的作用域扩展到其他文件。
  3. 将外部函数(函数名前面没有加 static 关键字)的作用域扩展到其他文件。

1.3 Tips

  1. 变量可以被声明很多次,只可被定义一次。
  2. 在函数体内部试图初始化一个 extern 标记的变量将引发错误。

2. 指针和引用

2.1 指针和引用的不同

引用本身并不是一个对象,一旦定义了引用,就不能绑定其他对象。指针并没有这种限制。

2.2 符号的多重含义(&和*)

  • &紧跟类型名出现,是声明的一部分代表声明一个引用。
  • * 紧跟类型名出现,代表声明一个指针。
  • &出现在表达式中,代表取地址。
  • * 出现在表达式中,表示解引用符,去当前指针指向地址的值。
int i = 42;
int &r = i;                               //r是一个引用(紧跟类型名)
int *p;                                   //p是一个指针(紧跟类型名)
p = &r;                                   //&为取地址符
*p = 43;                                  //*为解引用符
int &r2 = *p;                             //&为引用声明 *为解引用符

2.3 void* 指针

void*指针是一种特殊的指针,它可以用于存放任意对象的地址,但对于这个地址内存放的是什么类型的对象并不了解,因此不能直接操作指向的对象。

利用 void 指针可以做的事非常有限:和别的 void*指针比较,作为函数的输入或输出,赋给另一个 void*指针。

3. const 限定符

const 对象一旦创建后其值不再改变,因此,const 对象创建后必须初始化。

const int i = get_size();                   //正确,运行时初始化
const int j = 42;                           //正确,编译时初始化
const int k;                                //错误,没有初始化

3.1 const 的引用

常量对象只能创建常量引用,非常量对象可以创建常量引用,但不可通过此引用进行修改。
也就是,常量只能看做常量,非常量可以看做常量。

const int ci = 1024;
const int &r1 = ci;                          //正确,引用和对象都是常量
int &r2 = ci;                                //错误,非常量引用指向常量对象

3.2 指针和 const

  • 常量指针

常量指针必须初始化,指向的地址不变。

  • 指向常量的指针

类似引用,若要存放常量的地址,必须声明为指向常量的指针。

int errNumb = 0;
int *const curErr = &errNumb;                  //常量指针,一直指向errNumb
const double pi = 3.14159;
const double *const pip = π                 //指向常量的常量指针,一直指向pi
  • 顶层 const(top-level const)和底层 const(low-level const)

顶层 const 表示指针本身是个常量,底层 const 表示指针指向对象是个常量。

3.3 constexpr 和常量表达式

常量表达式:值不会改变且在编译期就能得到计算结果的表达式。

constexpr 变量:C++11 新标准规定允许将变量声明为 constexpr 类型以便由编译器验证变量是否是一个常量表达式。

constexpr int mf = 20;                          //20是常量表达式
constexpr int limit = mf + 1;                   // mf+1是常量表达式
constexpr int sz = size();                      // 只有当size()是常量表达式时,才是一条正确的声明语句

4. 处理类型

4.1 类型别名

有两种方法可以定义类型别名:

1.使用 typedef

typedef double wages;                            //wages是double的同义词
typedef wages base *p;                           //base是double的同义词,p是double*的同义词
wages w = 1.22;

2.新标准规定了一种新的方法,使用别名声明来定义类型别名

using I = int;                                    // I是int的同义词

示例代码:Code/TestTypedef

4.2 auto 类型说明符和 decltype

  • auto 类型说明符

C++ 11 标准引入 auto 类型说明符,让编译器替我们去分析表达式所属类型。
auto 类型的变量必须有初始值。

auto item = val1 + val2;
auto item2 = getItem();
  • decltype

与 auto 功能类似,decltype 函数返回的是操作数的数据类型(并不计算操作数的值)。

decltype(f()) sum;                             //sum的类型为f返回值类型

如果 decltype 使用的表达式不是一个变量,则 decltype 返回表达式结果对应的类型。

int *p = &r;
decltype(*p) c;                                 //c是一个int型引用,必须初始化

标题:《C++ Primer》第二章:变量与数据类型
作者:YaoCheng8667
地址:https://ycisme.xyz/articles/2019/12/05/1575526641819.html