C++
引用和指针
引用:
int i= 12;
int &ri=i;
1.引用必须被初始化
2.引用和对象是绑定的关系,相当与对象的另一个名字,对二值赋值都会相互更改
int i=12;
int &ri=i;
ri=5;
//此时i=5
3.&符号有时也被用作取地址。
int i=2;
int *p;
p=&i;
*p=5;
//此时*p就是i的指针,给*P赋值5,i也为5
4,引用并非一个对象,一旦引用已经绑定了一个对象,不能在绑定到其他对象上去。
(2)指针
1.指针不需要在定义时赋值
2.指针本身就是一个对象,允许对指针赋值和在生命周期中指向不同的对象
int i=12;
int *p=&i;
*p=2;
//i的值也会随着改变
3.两种访问对象方式
int i=12;
int *p=&i
int *p;
p=&i;
4.空指针:不指向任何对象
int *p=nullptr;
int *p=0;
5.void *型指针:可以指向任何对象
double i=3.14;
double *p1=&i;
viod *p=&i;
p=p1;
string
(1)几种初始化的方式
string s="xxxx";
string s("xxx");
string s=(10,'a');//10个a
string s=string(10,'a');
string a="xxx";
string s=a;
(2)string的操作:
os<<s //s写到os中,输出os
is>>s //is中读取字符串赋给s
getline(is,s) //从is中读取一行赋给s,返回is,遇到换行符就会停止
s.empty() //s为空返回true,反之false
s.size() //返回s的字符个数
s[n] //返回s中第n个字符的引用,从0计数
s1+s2 //返回s1 s2连接厚的字符串
s1=s2
s1==s2
<,<=,>,>= //利用字符在字典中的顺序进行比较
判断字符串的结尾可以用 ‘\0’ 作为判断因素
vector
(1)定义和初始化vector对象
vector<T> v1 //v1是一个空容器,它潜在元素的类型是T类型的
vector<T> v2(v1) //v2中包含v1的所有元素
vector<T> v2=v1
vector<T> v3(n,val) /v3中包含n个重复的元素,每个元素值为val
vector<T> v4(n) //v4中包含亮n个重复的初始化的对象
vector<T> v5{a,b,c...} //v5中所有的元素和其具体的值
vector<T> v5={a,b,c...} //等价上面
注意:初始化时,vector<int> v1 =10 是错误的,可以写成vector<int> v1(1,10)
(2)向vector中添加元素
使用的时候并没有那么先知先觉,往往需要改变或者数量很大,此时就用到vector的成员函数
push_back()
//向容器中放1-100
vector<int> v1;
for(int i=0:i<=100;i++)
v1.push_back(i);
//从标准输入中读取单词
string word;
vector<string> v2;
while(cin>>word)
v2.push_back(word);
注意:循环体内包含有向vector对象添加元素的语句,不能呢个使用for循环,因为for语句体内不应改变其便利需力的大小
(3)其他vector操作
v.empty() //为空反true
v.size() //返回元素个数
v.push_back(t) //向v的末尾加t元素
v[n] //返回v中第n个元素的引用
数组
(1)定义和初始化内置数组
数组是一种符合类型,数组的声明如a[d],a是名称,d是维度即元素个数,维度必须是一个常量表达式
unsigned cnt=10; //非常量
constexpr unsigned i=10; //常量表达式
int arry[10]; //含有10个整数的数组
int *p[i]; //含有10个整型指针数组
string aa[cnt]; //错误,cnt非常量
(2)显示初始化数组元素可以对数组的元素进行初始化,此时允许忽略数组的维度
const unsigned i=3;
int a1[i]={0,1,2}; //含有3个元素的数组
int a2[]={0,1,2}; //维度是3的数组
int a3[5]={0,1,2}; //a3的元素为 0 1 2 0 0
string a4[3]={"aa","bb"}; //a4的元素为"aa" "bb" ""
int a5[2]={0,1,2}; //错误,初始值过多
(3)字符的特殊性
字符数组有一种额外的初始化形式,可以用字符串的面值来初始化,但此时要在结尾预留一个空字符的空间
char a1[]={'c','a','='}; //列表初始化
char a2[]={'c','a','=','\0'}; //列表初始化含有空字符
char a3[]="c++"; //自动添加字符串结束空字符
const char a4[6]="123456"; //错误,没有空字符空间
(4)复杂的数组声明
int *ptrs[10]; //ptrs含有10个整型指针数组
int &refs[10]=/*?*/; //错误不存在引用的数组
int (*parray)[10]=&arr; //parray指向一个含有10个整数的数组
int (&arrRef)[10]=arr; //arrRef引用含有10个整数的数组
(5)数组指针运算
给一个指针加上(减去)某个数值,结果仍是指针新指针指向的元素与原来的指针相比前进了(后退了)该数值个位置
需要注意的是,不能移出数组的总长度。
constexpr size_t i=5;
int arr[i]={1,2,3,4,5};
int *ip=arr; //等价与int *p=&arr[0];
int *ip2=ip+4; //ip2指向arr的尾元素arr[4]
(6)解引用和指针运算的交互
int a1[]={0,2,4,6,8};
int last=*(a1+4); //把last初始化成8,也就是a1[4]的值
表达式×(a1+4)计算a1前进4个元素后的新地址
(6)下标和指针
对数组执行下标运算其实是对指向数组元素的指针执行下标运算:
int a1[]={0,2,4,6,8};
int i=a1[2];
int *p=a1; //P指向a1的首元素
i=*(p+2); //i为a1[2]
int *p=&a1[2]; //p指向索引为2的元素也就是a1[2];
int j=p[1]; //等价与*(p+1),也就是a1[3];
int k=p[-2]; //2-2=0,指向a1[0];
多维数组
严格来说,C++中咩有多维数组,通常所说的多维数组其实就是数组的数组
int a1[3][4]; //可以理解为大小为3的数组,每个元素含有4个整数的数组
(1)初始化
允许使用花括号括起来的一组值初始化数组:
int a1[3][4]={
{0,1,2,7},
{9,5,2,4},
{0,1,4,3}
}; //初始化所有的元素
//初始化每一行首元素,其他值为0
int a2[3][4]={{1},{2},{3},{4}};
//初始化第一行,其他值为0
int a3[3][4]={1,2,3,4};
(2)多维数组和指针
int a1[3][4];
int (*p)[4]=a1; //p指向有4个整数的数组
p=&a1[2]; //p指向第三行元素数组