C++_Primer知识点整理(一)

来源:C++ Primer中文版(第5版)

开始

关于“类”类型:

类定义了行为,不论是自定义类还是标准库定义的类,在定义之初就决定了在此对象上能够使用的所有操作,可以在“标准操作”基础上对某些行为进行重载

点运算符( . ): 只能运用于“类”类型的对象

点运算符( . )与箭头运算符(->)的联系和区别:

  1. 点运算符能够获取对象的成员,箭头运算符能够获取对象的成员

  2. 点运算直接获取对象的成员,箭头运算符通过指针间接访问对象的成员

  3. 访问对象为指针类型时,需使用箭头运算符;或用点运算此形式:

    1
    2
    3
    4
    5
    6
    auto *pre;
    (*pre).value; //先解引用,再访问其中的对象
    //等价于
    pre -> value;


第二章:变量和基本类型

内置基本数据类型:

根据硬件设计不同、编译器区别、地区或行业统一标准不一致等原因,同一数据类型在不同机器上所占的存储空间有所差异

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//常见算术类型
bool //布尔类型
char //字符型
wchar_t //宽字符
short //短整型
int //整型
long //长整型
long long //长整型
float //单精度浮点数
double //双精度浮点数
long double //扩展精度浮点数
//每种类型具体所占空间大小由不同编译规则及硬件环境决定
//long long是C++11中新定义的,C++规定其最小为64位
//float、double、long double的精度从低到高排列

整型分为:带符号(signed)和不带符号(unsigned)。short、int 、long 、long long都是带符号的,只要在前面加上unsigned就是无符号类型的定义

类型选择的默认准则:

  1. 明确知道数据不可能为时,选用无符号类型
  2. 常见的整型计算使用 int 定义,长度超过 int 时,选用 long long 类型进行定义
  3. 涉及浮点数运算选择 double 定义
  • 算术表达式中既有 无符号数 又有 int值 时,int值 会转换成 无符号数

  • 负数 转换成 无符号数 (类似将一个带符号的值赋给无符号对象)时,此负数存储的位模式不会改变,但是会被解释成一个大正数

    1
    2
    3
    4
    5
    6
    7
    8
    //32位计算机
    unsigned arr = -42
    //正数 42 的二进制表示是:00000000 00000000 00000000 00101010
    //在二进制补码表示法中,负数是对正数取反并加 1。取反后: 11111111 11111111 11111111 11010101
    //在上述基础上加1得到-42的32位补码:11111111 11111111 11111111 11010110
    /* 将 -42 转换为无符号数时,类似于将负数赋值给无符号对象
    此时arr的值为-42的32位补码在无符号对象中的解释:4294967254
    等价 -42 mod 2^32 ,也就是:2^32-42 = 4294967254 */

字面值常量(具体的数)

字面值常量的形式和值决定了其数据类型:

  • -42是一个有符号的整型
  • 3.1415926是一个无符号(有符号)的浮点数

整型字面值可以用相应的前缀表示其 进制: 0开头为八进制,0x或0X开头表示十六进制

字符字面值和字符串字面值:

字面值类型:可以在编译时求值的类型。常见的基本类型:整型、浮点型、指针类型、空类型void等,均属于字面值类型。string类型、IO库等就不属于字面值类型

  • 字符字面值:用 单引号 括起来的一个字符,只能是单个字符,底层通常表现为对应的ASCII码或Unicode码所对应的值

  • 字符串字面值:用 双引号 括起来的 零个或一个或多个字符 ,不可修改,以空字符 ‘ \0 ‘ 标志结束的常量字符数组,底层表现为一个不可变大小的数组

变量:

变量:一个有具体类型、名字、可供程序操作的 存储空间。定义格式:类型 变量名列表 分号

对象:一块能存储数据,具有某种类型的存储空间

对象的初始化和赋值是有区别的:

  • 初始化:创建变量时赋给其一个初始值
  • 赋值:把对象当前的值擦除,用另一个值来代替

是否初始化对象,由'类'决定;如果不进行初始化,那默认的初始化值是什么,也由'类'决定

Tip:内置类型的对象,建议进行初始化,避免发生不可靠的事件

复合类型:

复合类型:基于其他类型定义的类型

引用(绑定)

1
2
3
int val = 10;
int &refVal = val;
//refVal即为一个引用,可以通过refVal访问val

引用不是一个对象,只是给已经存在的对象起了一个别名,并将这个别名和原对象绑定在一起

  • 引用只能绑定在对象

  • 必须要进行初始化

  • 引用的类型必须要和所绑定的对象类型一致

指针

1
2
3
int x = 10;
int *pre = &x; //指针存放的是地址,必须要用取地址符&获取某元素的地址
int *pre01 = pre;

指针是一个存放地址的对象,可以通过指针对象间接访问其指向的目标(对象)

  • 只进行了定义而未进行初始化的指针是一个危险的存在,不知道此对象指向何处
  • 空指针指向了一个为 nullptr 的值,而不是没有指向任何对象
  • 要访问指针指向的对象,需使用解引用符( * )

const限定符

1
2
3
const int a = 10;
const int &r1 = a; //常量引用,不能通过r1修改a的值

const修饰的对象,其值不能被改变,必须要进行初始化

const修饰的对象可进行大部分操作,只是不能进行改变对象值的行为

指针和const

const修饰的常量,只能用指向常量类型的指针进行指向

1
2
3
4
const int x = 10;
int *pre01 = x; //错误
const int *pre = x; //正确
//const所修饰的常量x,只能用const修饰的指针进行指向

cosnt修饰的常量指针,可以指向一个常量对象,也可以指向一个非常量对象。只是不能通过指针修改其指向对象的值

类型的处理

类型别名

  • 使用 typedef 关键字定义
1
2
3
typedef int wages;
typedef wages base;
//int、wages、base是同义词
  • 使用别名声明关键字 using
1
using wages = int;

关键字 autodecltype

auto:当未知对象的类型时,使用 auto 可以使编译器自己分析表达式类型,其声明的对象必须要赋初值,表达式(初值)得到的类型通过 auto 定义其修饰的对象,并以此结果初始化 auto 修饰的对象

decltype:auto 修饰的对象必须要初始化,其行为受到一定限制。decltype可以只自定义其类型,而不进行初始化

1
2
3
4
5
6
auto a = 10; //a被定义为一个int类型变量
double b = 3.14;
auto c = b; // c和b同属于double类型

decltype(a) b; //根据a的类型定义b
decltype(f()) sum; //sum的类型是函数f的返回类型

第三章:字符串、向量和数组

可变长的字符序列 string

  • 初始化string对象的不同方式
1
2
3
4
5
6
string s1;    //定义一个string对象,进行默认初始化,是一个空串
string s2(s1); //s2是s1的副本
string s2 = s1;
string s3("value"); //直接初始化
string s3 = "value"; //拷贝初始化
string s4(n , 'c'); //用n个连续的c初始化s4
  • 基本操作
1
2
s.empty()    //字符串s为空时返回true,否则返回false
s.size() //返回s中字符的个数,末尾的结束符不计算在内

关于string的比较:

  1. 大小写敏感
  2. 两个string对象长度不同,较短的string对象的每个字符都与较长string对象对应位置上的字符相同,则较短string对象小
  3. 两个string对象在某些对应位置上不同,比较结果为:两个对象第一次出现差异的地方,字符大小的比较结果

字符字面值,字符串字面值和string对象

  • 字符字面值:用点引号括起来,只能是单个字符,底层通常表现为对应的ASCII码或Unicode码
  • 字符串字面值:用双引号括起来,零个或一个或多个字符,不可修改,在内存中被分配一个字符数组,以空字符**’\0’**结束
  • string对象:可以进行动态管理,是一个标准库中的类,以空字符**’\0’**结束

头文件 cctype 中的部分函数

cctype中的函数通常用于处理单个字符,例如对string对象某一位上的字符进行处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <cctype>
isalnum(c) //当c是字母或数字时为true
isalpha(c) //当c时字母时为true
iscntrl(c) //当c是控制字符时为true,换行符、回车符、空字符、分页符等均为控制字符
isdigit(c) //当c是数字时为true
isgraph(c) //当c是图形字符(可以在屏幕上显示的,空格、控制字符等均不是图形字符)时为true
islower(c) //当c是小写字母时为true
isprint(c) //当c是可打印字符(包括空格)是为true
ispunct(c) //当c是标点符号时为true
isspace(c) //当c是空白时为true(空格、制表符、回车、换行等)
isupper(c) //当c是大写字母时为true
isxdigit(c) //当c是十六进制数字时为true
tolower(c) //如果c是大写字母,输出对应的小写字母;否则原样输出
toupper(c) //如果c是小写字母,输出对应的大写字母;否则原样输出

标准库类型vector(向量)

vector是一个拥有相同类型对象的集合,也被称为容器

  • 定义和初始化vector常见的方法
1
2
3
4
5
6
7
8
9
#include <vector>
vector<T> v1; //定义了一个T类型的空vector,名字为v1
vector<T> v2(v1); //用v1中的元素初始化v2
vector<T> v2 = v1; //同上一句
vector<T> v3(n , val); //用n个val初始化v3
vector<T> v4(n); //v4包含n个已经初始化的默认元素(T为int时,每个元素都为0;T为string时,每个元素都为空)
vector<T> v5{a,b,c,……}; //利用列表对vector对象进行初始化
vector<T> v5 = {a,b,c,……};
//T为数据类型,可以是int、double、string、vector等