开启学习与复习C++语法
从今天开始进行对C++语言的学习复习,主要是针对自己觉得重要和薄弱的地方进行学习,一个刚入门的小白菜非常希望各位大佬提些学习C++的好方法,若文中有错,请提醒提醒,在此,先谢过啦。
1、指针与引用
(1)区别
- 指针: 存放指向变量地址的变量;自身是一个对象,可以进行赋值和拷贝等(原变量不会变化);同时在声明时可以不进行初始化;指针存在多级指针;指针拥有存储空间,并且内存大小是固定的,其大小跟操作系统、CPU、编译器有关;传递参数时,指针传递的是指针的地址;
- 引用: 现有变量的别名;不会分配内存空间;对引用的赋值等更改是直接对原变量的更改;引用没有多级引用;使用sizeof运算符返回原变量的大小;引用在声明时必须初始化,否则报错,完成初始化后,引用不能再指向其他对象;传递参数时,引用传递的是原变量的地址。
(2)指针操作与void*指针
- 指针操作: 可以使用!=、==等操作符判断两指针是否相等;可将指针作为判断条件,若为nullptr,返回false,否则返回true;
- void* 指针: 可以指向任何类型的指针,后期可以利用static_cast强制转换为原类型指针。
2、const常量
(1)常量
- 在声明时完成初始化,一旦初始化将无法更改其值;const对象的作用域与普通变量的作用域相同;const对象在默认情况下仅在当前文件下有效,若要在同一个程序的多个文件有效,需要添加关键字:extern (当且仅当const变量为当前文件的全局变量时才可以,且只能初始化某一文件内的const相同变量)。
(2)指向常量的引用
- 初始化常量引用时允许用任意类型的表达式作为初始值,比如非常量、常量、表达式等;
- 常量必须由常量引用指向,并且不能修改常量值;
- 非常量引用不能指向常量引用或常量;
- 不能通过常量引用修改其指向的非常量值,但可通过其他途径修改。
(3)指向常量的指针
- 初始化时可以指向任意类型的表达式作为初始值,比如非常量、常量、表达式等;
- 常量必须由指向常量的指针指向,且不能通过该指针改变常量值;
- 指向常量的指针可以更改指向对象;
//验证指向常量的指针是否可以指向其他对象
const int t = 2;
const int* t_ptr = &t;
cout << *t_ptr <<t_ptr<< endl;
const int t2 = 3;
t_ptr = &t2;
cout << *t_ptr << t_ptr<<endl;//结论是可以改变指向对象
- 普通指针无法指向常量,且指向常量的指针无法复制给普通指针;
- 若指向常量的指针指向非常量,不可通过该指针更改非常量的值,但可以通过其他方式修改。
//验证第五条
int i=0;
const int *p=&i;//指向非常量
*p=5;//此处错误
i=5;//此处正确
(4)常量指针
- 常量指针是指针本身在初始化后不能进行更改,即其存储的变量地址不能修改,不能改变指向对象。
- 所指向的对象可以做相应的修改,且可以通过指针常量对对象进行更改。
int x = 1;
int y = 2;
int* const p = &x;
*p = 5;//此处实质是在改变x的值
p = &y;//此处报错,不能修改常量指针
(5)顶层const与底层const
- 顶层const: 就是对象本身不能更改;
int x=0;
int *const p=&x;//顶层const,p本身不能更改
const int y=5; //顶层const,y本身不能更改
- 底层const: 所指对象不能更改。
const int x=10;
const int *p=&x;//底层const,即x(即*p)不能更改
const int &q=x; //底层const,x不能更改
3、迭代器与sizeof()
(1)迭代器
- 迭代器支持自增、自减、解引用、加减、比较等运算,迭代器类似于指针;
- 常见的迭代器有begin()、end(),其中end()指向最后一个元素的后一位,左闭右开区间;
- 迭代器分为iterator和const_iterator两类,前者支持读写元素,后者只可读元素。
(2)sizeof()
- 对于引用来说,使用此运算符返回原变量的内存大小;
- 对于指针来说,返回指针本身大小,一般为4个字节;
- 对于指针解引用来说,返回指针指向的对象大小;
- 对于vector和string来说,返回某一固定大小,不会随着元素增多而变大;
- 对于数组来说,返回数组所有元素的内存大小总和。
4、类型转换
(1)static_cast
- 除了底层const,其他具有明确定义的类型转换都可实现;
- 相对于旧式强制转换,此类强制转换更加清晰安全,可读性得到提高;
- 但是通过实践:static_cast不能将某类型指针转换成另一类型指针,旧式强制转换可以实现。
//类型转换
float i = 8.0;
float* p = &i;
int j = 10;
int j2 = 15;
int* const cp = &j;
cout << *cp << endl;
double ptr1 = (double)*p; //旧式强制类型转换
int* ptr2 = (int*)p; //将float类型指针转换成int类型指针
static_cast<int>(i); //转换变量类型
static_cast<int>(*p); //转换变量类型
//static_cast<int*>(p); //将float类型指针转换成int类型指针,用static_cast转换会失败
int* p1 = static_cast<int*>(cp); //去除顶层const
p1 = &j2; //去除顶层const,指针可指向其他变量
cout << *p1 << endl;
void* cp1 = &j;
double* p2 = static_cast<double*>(cp1); //将无类型指针转换为原类型(或其他类型)指针
(2)dynamic_cast
- 此强制转换是将指向父类的指针安全地强制转换成子类的指针或引用;
- 对于指针型转换,若转换失败,返回0;
- 对于引用型转换,若转换失败,则抛出一个bad_cast异常。
(3)const_cast
- 仅转换底层const,添加或去掉底层const。
const int nu = 10;
const int *num = ν
int nu1 = 15;
int* num2 = &nu1;
const_cast<int*>(num); //去掉底层const
const_cast<const int*>(num2); //添加底层const
num = & nu1; //此处可以改num的值
//num2 = ν //此处会报错,因为上述已将num2转换为const
(4)reinterpret_cast
- 通常为运算对象的位模式提供较底层次上的重新解释。(这个强制转换有点不懂)
5、异常处理
(1)throw
- 程序通过throw来引发异常,
- 语法为:throw 表达式,其中表达式的类型是抛出异常的类型。
(2)try
- 基本语法:
try {
正常逻辑程序段
}catch{
出错后的处理程序段
}catch{
出错后的处理程序段
}//......
- 先执行正常逻辑程序段,当遇到异常时,选中某个catch子句处理异常后,继续执行其他语句。
以上便是今天的总结啦,可能存在错误与不足,若有发现,请大家指出,谢谢啦!!