初始化与赋值

当对象在创建时获得了一个特定的值, 我们就说这个对象被初始化了. 在使用=号时, 如果创建了新的对象, 则为初始化而非赋值.

初始化不是赋值, 初始化的含义是创建变量时赋予其一个初始值, 而赋值的含义是吧对象的当前值擦除, 而以一个新值代替.

在使用列表初始化(C++11支持)时, 如果存在丢失信息的风险, 则编译器会报错.

默认初始化: 如果变量定义时没有指定初值, 则被默认初始化. 默认值由变量类型和变量定义的位置决定. **定义在任何函数之外的内置类型变量被初始化为0, 定义在函数体内部的内置类型变量将不被初始化. **

定义在函数内的内置类型的对象如果没有初始化, 其值是未定义的.类对象如果没有显示初始化, 其值由类决定.

变量声明与定义

分离式编译允许将程序分割为若干个文件, 每个文件可被独立编译. 为了支持分离式编译, C++语言将声明和定义区分开来, 声明使得名字为程序所知, 如果一个文件想要使用别处定义的名字则必须包含对那个名字的声明, 而定义负责创建与名字关联的实体.

如果想声明一个变量而非定义它, 就在变量名前添加关键字extern且不要显示地初始化变量:

extern int i;          //声明i而非定义i
int i; //声明并定义i

任何包含显式初始化的声明即成为定义. extern语句如果包含了初始值就不再是声明, 而变成定义了:

extern int i = 10;      //定义

在函数体内部, 如果试图初始化一个由extern关键字标记的变量, 将引发错误. 变量能且只能被定义一次, 但是却可以多次声明.

变量能且只能被定义一次, 但是可以被声明多次.

要在多个文件中使用同一个变量, 就必须将声明和定义分离, 变量的定义必须出现在且只能出现在一个文件中, 其他用到该变量的文件必须对其进行声明, 却绝对不能重复定义.

引用和指针

引用就是一个对象的别名, 引用必须初始化, 一旦初始化完成, 引用将和它的初始值对象一直绑定在一起, 无法令引用重新绑定到另外一个新的对象上.

引用并非对象, 他只是为一个已经存在的对象所起的另外一个名字而已.

引用本身不是对象, 因此无法定义引用的引用.

两种方法为指针置空

int *p = nullptr; // C++11标准推荐, 字面值类型
int *q = NULL // 需要#include <cstdlib>, 预处理器变量
int *r = 0; // OK, 初始化字面值常量0

现代C++程序最好使用nullptr, 避免使用NULL.

const限定符

初始化和const: 如果利用一个对象去初始化另一个对象, 则它们是不是const都无关紧要:

int i = 42;
const int ci = i;
int j = ci;

const常量特征只在构造完成时才生效, 因此初始化时可以给它一个初始值.

默认状态下, const对象仅在文件内有效, 如果想要在一个文件中定义它, 而在多个文件中声明并使用它, 解决的办法是对于const变量不管是声明还是定义都添加extern关键字.

extern const int bufSize = fcn(); // file1.cc定义并初始化一个常量, 该常量能被其他文件访问
extern const int bufSize;// file1.h中, 与file1.cc中是同一个bufSize

如果想在多个文件之间共享const对象, 必须在比变量的定义之前添加extern关键字.

可以把引用绑定到const对象上, 称之为对常量的引用, 对常量的引用不能被用作修改它所绑定的对象.

const int ci = 1024;
const int &r = ci; // 引用以及对应的对象都是常量
int i = 42;
const int &r2 = i; // 允许将const int &绑定到普通int对象上, 但是不允许通过r2改变i的值

如果const关键字出现在星号左侧, 表示被指物是常量, 如果出现在星号右侧, 表示指针自身是常量.

顶层const表示指针本身是个常量, 底层const表示指针所指的对象是一个常量.

constexpr和常量表达式

常量表达式(const expression)指值不会改变并且在编译过程中就能得到计算结果的表达式

类型别名

typedef int ElementType;
using ElementType = int; // C++11标准, 与typedef等价的定义

类型别名的错误理解

const char *pstring;
const pstring cstr = 0; // cstr是指向char的常量指针, 即cstr本身是const的不可改变, 但所指对象可以改变
const char *cstr2; // cstr2是指向const char的指针, 即cstr2本身可以改变, 所指对象不可改变.

auto类型说明符:

auto让编译器通过初始值来推算变量的类型, 显然auto定义的变量必须有初始值.

使用引用类型推断结果是引用所绑定的对象的类型, 如果希望推断出引用类型必须明确指出.

int i = 0, &r = i;
auto a = r; // a的类型为int 而非int &
auto &b = r; // b的类型为int &

auto一般会忽略掉顶层const, 同时底层const则会被保留下来

const int ci = i, &cr = ci;
auto b = cr; // b是int类型 而非const int
const auto c = ci; // ci推断出是int, c是const int类型

decltype类型指示符

如果decltype使用的表达式是一个变量, 则decltype返回该变量的类型, 包括顶层const和引用在内.

const int ci = 0, &cj = ci;
decltype(ci) x = 0; // x类型为const int
decltype(cj) y = x; // y类型为const int &, 因此必须初始化
// 以下是decltype几个特殊用法
decltype(f()) sum = x; // x类型为f()返回值类型, f()并没有被调用
int i = 42, *p = &i, &r = i;
decltype(r + 0) b; // 加法结果是int, 因此b是未初始化的int
decltype(*p) c; // 若表达式内容是解引用操作, 则得到引用类型, 因此c是int &, 必须初始化
decltype((i)) d; // 双层括号的结果永远是引用类型, 而单层括号只有当表达式是引用类型其结果才是引用类型

[C++ Primer] 第2章: 变量的更多相关文章

  1. C++ Primer 第2章 变量和基本类型

    C++ Primer 第2章 变量和基本类型 C Primer 第2章 变量和基本类型 1 基本内置类型 算数类型 类型转换 字面值常量 2 变量 变量定义 3 复合类型 引用d左引用 指针d 4 c ...

  2. C++ Primer 读书笔记 第2章 变量和基本类型

    C++ Primer 第二章 变量和基本类型 2.1 基本内置类型 C++定义了一组表示整数.浮点数.单个字符和布尔值的算术类型(arithmetic type),此外还定义了Void类型. 算术类型 ...

  3. C++ Primer 笔记(2)第二章 变量与基本类型

    第二章 变量与基本类型 1.基本内置类型包括算术类型和空类型,算术类型分为两类:整型(包括字符和布尔类型)和浮点型: 2.布尔类型(bool)的取值是真(true)或者假(false): 3.字面值常 ...

  4. <<C++ Primer>> 第二章 变量和基本类型 术语表

    术语表 第 2 章 变量和基本类型 地址(address): 是一个数字,根据它可以找到内存中的一个字节    别名生命(alias declaration): 为另一种类型定义一个同义词:使用 &q ...

  5. C++ Primer 笔记 第二章

    C++ Primer 第二章 变量和基本类型 2.1基本内置类型 有算数类型和void类型:算数类型储存空间大小依及其而定. 算数类型表: 类型 含义 最小储存空间 bool 布尔型 - char 字 ...

  6. C++ Primer 第3章 字符串、向量和数组

    C++ Primer 第3章 字符串.向量和数组 C Primer 第3章 字符串向量和数组 1 命名空间的using声明 2 标准库类型string 3 标准库类型vector 4 迭代器介绍 5 ...

  7. 逆向基础 C++ Primer Plus 第二章 开始学习C++

    C++ Primer Plus 第二章 开始学习C++ 知识点梳理 本章从一个简单的C++例子出发,主要介绍了创建C++程序的步骤,以及其所包含的预处理器编译指令.函数头.编译指令.函数体.注释等组成 ...

  8. Java 第二章 变量

    第二章 变量 变量称为:是计算机语言中能储存计算机结果或能表示值抽象概念 .变量可以通过变量名访问 int money ; //变量 money=1000; //赋值 int money=1000: ...

  9. Java 第二章 变量、数据类型和运算符

    第二章      变量.数据类型和运算符 什么是变量: 变量代表一块内存区域,变量类型不一样,这一块内存的大小也不一样. #在编程语言里面,你可以通过定义变量,向内存里添加数据或者修改内存已有的数据. ...

随机推荐

  1. 利用ansible进行自动化构建etcd集群

    上一篇进行了手动安装etcd集群,此篇利用自动化工具ansible为三个节点构建etcd集群 环境: master:192.168.101.14,node1:192.168.101.15,node2: ...

  2. 20145307陈俊达《网络对抗》Exp3 免杀原理与实践

    20145307陈俊达<网络对抗>Exp3 免杀原理与实践 基础问题回答 杀软是如何检测出恶意代码的? 恶意代码中一般会有一段有较明显特征的代码也就是特征码,如果杀毒软件检测到有程序包含的 ...

  3. 20135320赵瀚青LINUX第八周学习笔记

    赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 本周学习的是linux ...

  4. 20145325张梓靖 实验一 "Java开发环境的熟悉"

    20145325张梓靖 实验一 "Java开发环境的熟悉" 程序设计过程 实验内容 实现凯撒密码,并进行测试 编写代码 使用java.util.Scanner进行输入,而它的方法里 ...

  5. Linux内核源码目录说明

    Linux内核源代码位于/usr/src/linux目录下,其结构分布如图1.3所示,每一个目录或子目录可以看作一个模块,其目录之间的连线表示“子目录或子模块”的关系.下面是对每一个目录的简单描述. ...

  6. http://www.artrobot.com/北京钢铁侠

    http://www.artrobot.com/ 钢铁侠ROS智能机器人 钢铁侠ROS智能机器人 型号 ARTrobot-ROS 产品图片:   产品概述: ARTrobot-ROS全开放机器人套件服 ...

  7. Flask: socket.error: [Errno 48] Address already in use 问题

    参考: Mac OSX 解决socket.error: [Errno 48] Address already in use问题 Mac OS X中解决socket.error: [Errno 48] ...

  8. HDU 2485 Destroying the bus stations(费用流)

    http://acm.hdu.edu.cn/showproblem.php?pid=2485 题意: 现在要从起点1到终点n,途中有多个车站,每经过一个车站为1时间,现在要在k时间内到达终点,问至少要 ...

  9. Gym - 101334C 3514 无向仙人掌

    http://codeforces.com/gym/101334/attachments 题意: 判断是否是仙人掌图并且连通,如果是的话则计算出它有多少个连通子图也是仙人掌. 思路:连通子图也就是我们 ...

  10. Recover Binary Search Tree,恢复二叉排序树

    问题描述:题意就是二叉树中有两个节点交换了,恢复结构. Two elements of a binary search tree (BST) are swapped by mistake. Recov ...