本文基于c++primer对自己学过的c++中的疑难点进行记录,方便回顾与记忆。
复合类型
-
(左值)引用
左值引用-不能绑到要求转换的表达式、字面常量、返回右值的表达式。
右值引用-用于内置类,&&进行绑定。右值绑定只能绑定在即将销毁的对象上,以便将引用的资源移动到另一个对象中。
不能将右值引用绑定在左值上。
引用--起别名
int ival = 1024;
int &refVal = ival;//refval指向ival
//引用必须进行初始化,不可能只声明
irfVal是一个引用,它的值为1024,&refVal的值为000000B10419F5C4 ,实际上是ival的地址。
此时refVal就是对ival的别名,实际上refVal就是ival。
refVal = 2;
int ii =refVal;
//等价于用ival对ii进行赋值
对引用的操作,实际上是对被引用的值的操作。获取引用的值,实际上获取的是被引用的值的值
不能定义引用的引用。
引用类型要与绑定对象类型匹配,两个特例:
- const
- 类型转换与继承
-
指针
指针与引用异同点:
同:
都可以实现对对象的间接访问异:
- 指针本身是一个对象,可以进行赋值和拷贝
- 指针无需定义时赋值
- 引用本身不是对象,引用定义后就无法绑定到其他对象,之后使用该引用都是最初绑定的那个对象
- 指针赋值只是存放了该对象的地址,给指针赋值就是存放一个新的地址,从而指向一个新的对象
指针存放一个对象的地址,解引用符(*)实现对指针所指向的对象的访问
int* ipl, * ip2;//ip1和ip2是指向int类型对象的指针
double dp, * dp2;//dp2是指向double类型对象的指针
示例:
int ival = 42;
int* p = &ival;//初始值是ival的地址
int* p2 = p;//初始值是指向ival的指针
cout << ival << " " << p << " "<<p2<<" "<<*p<<" "<<*p2;
输出结果:42 000000A72598F714 000000A72598F714 42 42
分析:ival是int类型的数字量,值为42;
&ival是对ival的引用别名,属于引用类型,值是ival的存放地址;
p是指向ival的指针,存放的是该对象的地址;
p2是指向p的指针,p指针指向ival对象,因此p2存放的是ival的地址;
*p,*p2都是对ival的访问,因此是ival的值。
int ival = 42;
int* p = &ival;//初始值是ival的地址
*p = 1;
cout << ival;
对指针的赋值实际上是对其指向对象的赋值,输出1.
注:
int &i =r;//此时i是一个引用,&起到声明作用
int *p;//此时p是一个指针,*起到声明作用
p = &r;//此时&是取地址符,p是r的地址
*p = r;//此时*是解引用符,p是r的地址,*p是r的值
空指针-null pointer
不指向任何对象。
int* p = nullptr;
void*
存放任意类型对象的地址,对其存放的数据类型未知,因此无法直接对该指针指向的对象进行操作
头文件保护符:
用于头文件中,一般变量名全部大写,预处理器会在编译前执行使用这些功能有效防止重复包含的发生
#define将一个变量设置为预处理变量
#ifdef当且仅当变量已定义为真,顺序执行到#endif,否则忽略
#ifndef当且仅当变量未定义为真,顺序执行到#endif,否则忽略
string
命名空间:
#include <string>
using std::string
string对象在执行读取操作时会自动忽略开头的空白(空格符、换行符、制表符等)并且从第一个字符开始读取到下一处空白。
cin>>s;
cout<<s;
如果输入hello world,则输出hello;
读取未知数量的string对象:
int main() {
string word;
while (cin >> word)
cout << word << endl;
return 0;
}
getline()从输入符读入内容,直到遇到换行符为止
int main() {
string line;
while (getline(cin, line))
cout << line << endl;
return 0;
}
其他属性:
empty | 返回一个判断是否为空字符串的bool值 |
size | 返回无符号整型数,string的字符数量 |
关系运算符 | 从前往后比对,第一个不同的字符比较结果 |
+ | 连接操作,不能两个字面值(如hello和worlf)直接相加,至少有一个string对象 |
字面值和string是不同类型
对字符串每个字符的操作方法:
int main() {
string str("some string");
for (auto c : str)
cout << c << endl;
for (auto& c : str)//每个字符转大写,使用&改变其本身
c = toupper(c);
cout << str << endl;
}
结果展示:
对单个字符的处理:
- 使用下标s【x】,下标x范围【0,s.size】
- 使用迭代器
vector
命名空间:
#include <vector>
using std::vector
初始化:
//定义具有10个整型元素的向量(尖括号为元素类型名,它可以是任何合法的数据类型),不具有初值,其值不确定
vector<int>a(10);
//定义具有10个整型元素的向量,且给出的每个元素初值为1
vector<int>a(10,1);
//用向量b给向量a赋值,a的值完全等价于b的值
vector<int>a(b);
//将向量b中从0-2(共三个)的元素赋值给a,a的类型为int型
vector<int>a(b.begin(),b.begin+3);
//从数组中获得初值
int b[7]={1,2,3,4,5,6,7};
vector<int> a(b,b+7);
v.empty() | 判断是否为空 |
v.size() | 返回元素个数 |
v.push_back(t) | 尾部添加一个t元素 |
v[n] | 返回第n个位置的元素 |
v1 = v2 | 用v2替换v1内容 |
v1 = {a,b,c} | 用列表内容初始化v1 |
v1==v2 | 当且仅当所有元素相同且数量相同 |
v1!=v2 | |
</> | 关系运算符。字典顺序比较 |
对单个元素处理类似string',v【】只能访问已经存在的元素,不能用于添加元素
数组:
与vector相似,存放相同数据类型的元素,但数组的长度固定
不允许拷贝和赋值
int a1[3] = { 0,1,2 };
int a2[] = { 1,2 };
int a3[5] = { 1,2 };//a3={1,2,0,0,0}
string a4[] = { "w","eee" };
int* a5[10];//含有10个int类型指针的数组