c++面向对象程序设计 博客1
下面是这一段时间学过的知识以及我的个人感悟。
首先是constexpr类型。声明constexpr的数据对象一定是一个常量,而且必须用常量表达式初始化。若constexpr的对象是一个函数,则它的类型应为constexpr函数。const的对象是常量,如果对象是常量表达式,则是constexpr类型。 auto类型说明符。用它来声明变量的类型,由编译器自动去分析并推断出其类型。定义auto一定要有初始值。 decltype类型说明符。作用是选择并返回操作数的类型。编译器会自动分析表达式的类型,并不会真正计算表达式的值,例如const int a=0; decltype(a) x=1;//x的类型是const int。
typedef关键字的应用。typedef int A;//A就相当于int,"A s=1;"就是"int s=1;" typedef int *p;//定义了一个名为p的指针 typedef int A[];//定义了一个名为A的数组
范围for(range-for)语句。它可以对容器或序列里的所有元素逐个进行某种操作。语法形式为for(declaration:expression) statement;//declaration定义一个变量,最常用的方法是使用auto类型说明符;expression必须是一个序列。 例 int a[]={1,2,3}; for(auto e;a) e=e*2;//作用是将数组a的元素逐个乘以2。
指针。指针语法为 类型 *变量; int x=1; int *p=&x; &是取地址运算符,*是指针解引用运算符。p是x的指针,存放x的地址,指针不能指向不同类型的对象,不能被赋值,也不能被初始化为不同类型的地址值。指针可以进行自加自减运算。void*指针可以持有任何类型的地址值,只能表明相关的值是个地址,但该地址保存的对象类型不知道,不允许void指针到其他类型指针的直接赋值。
new和delete。c++语言通过new和delete两个运算符来进行动态存储空间的管理。new在动态内存中为对象分配空间,创建对象,并返回对象的地址。new 类型或new 类型(初始值). int *p1=new int; *p1=100; int *p2=new int(100);//在堆上分配一个int对象,初始化并返回地址,这个对象只能通过指针间接操作。 new 类型[数组大小] int *p=new int[100]; 堆上的空间使用后必须释放,否则会造成内存泄露,用delete运算符释放。 int *p=new int; *ip=521; delete ip; 释放后不能再使用ip指向的内存。
引用。左值引用,类型 &引用变量=初始值;引用必须被初始化,且初始值须是一个有内存地址的对象,不能在绑定到其他的对象。 右值引用, 类型 &&右值引用变量=右值表达式; 右值引用也必须被初始化,且右值引用引用的对象将要被销毁。
const限定指针和引用。不能将const地址赋值给非const指针,允许将一个非const地址赋值给const指针,const跟着谁就限定谁。 const引用可以绑定到非const对象,也可以用任意表达式初始化const引用,只要表达式的结果能转换为引用的类型。 当一个对象的值可能在编译器的控制或检测之外被改变时,应该将对象声明为volatile,例如一个被系统时钟更新的对象,volatile的语法和const相同。
结构体。结构体能把一组不同类型的数据组合在一起,构成一个复合类型,其中每个数据都是结构体的成员。 struct 结构体类型名{ 成员声明; }; 例如 struct scoresheet{ string name; int xuehao; int score; }; scoresheet s; s.name="某某某"; s.xuehao=111; ..... 使用结构体可以解决很多问题,例如要统计班级成绩单,就可以使用结构体。
联合。使用一个变量来处理不同的数据类型时可以用联合,用关键字union定义,语法和struct相似,union的每次只能使用一个成员。
枚举。枚举类型定义了一组命名的整型常量,可以提高代码的可读性,用关键字enum定义。 enum ShapeType{circle=10,square=20,a}; 为指定值的成员会赋给它相邻的下一个整数值,a=21。 不能使用枚举成员进行迭代,不能自增自减。
数组。数组在上学期已经学过。size_t是一种无符号类型,用来表示内存中任意对象的大小。 还可以用指针来访问数组元素。
begin()函数返回指向数组第一个元素的指针,end()函数返回指向数组最后一个元素的下一个位置的指针。
标准库类型string。表示可变长度的字符序列,使用时应包括头文件<string>。size()可以返回string对象的长度,empty()判断是否为空,string的加法运算至少有一个运算对象是string。
标准库类型vector。vector是长度可变的向量,使用时加头文件<vector>。用push_back(x)可以向vector的末尾插入元素,pop_back()可以删除vector的末尾。使用vector可以解决一些不确定数量的问题,v.size()返回元素个数。与数组相比,vector和string都很灵活。
迭代器。vector<int>::iterator it;//it能读写vector<int>的内容,vector<int>v; auto it1=v.begin();。迭代器类似于指针类型,在容器或string类型上使用,指向对象是容器的元素或string中的字符。*iter返回迭代器所指元素的引用,iter->mem可以获取该元素的成员,使用起来非常方便。
文件数据处理。使用文件流要有头文件<fstream>,使用字符串流要有头文件<sstream>, 运用文件流可以实现对文件的读写操作,ifstream类用来输入(读文件),ofstream用来输出(写文件);ifstream in("文件名.txt");是定义文件和打开文件;in从文件中读取数据,完成读取后要关闭文件,用in.close();ofstream out("文件名.txt");可以写文件,完成后也需用out.close()关闭文件。使用字符串流可以更方便的存储数据。
函数。 语法形式为 返回类型 函数名(参数列表){函数体},函数是由用户定义的操作,函数的结果是返回值,类型称为函数返回类型,如果函数不返回任何结果,应将返回类型声明为void。函数名后的参数是形参,函数体里的参数是实参,函数在遇到return语句后结束。参数传递有传值和传引用两种,按值传递即实参值初始化形参,形参的改变不能影响实参的值,所以若要修改实参的值可以将形参声明为指针或引用。可以将函数声明为返回指针或引用,此时返回对象本身,返回引用时,修改返回值会改变实际返回的对象,可以用const声明返回值避免这种情况。重载函数的名字相同,功能相似,但参数个数或类型不同,实参会调用最佳函数。非指针和引用上的conat限定词不能区分重载函数,const限定指针或引用时可以区分。 生存期是指程序执行过程中对象存在的时间,与作用域和存储类别密切相关。全局对象定义的变量和函数在整个程序中存在,局部对象的作用域从其声明点开始,到函数结束为止,例如for,while语句。可以将局部对象声明为static,是静态储存,在第一次定义时进行初始化,生存期会延续到程序结束。 register关键字声明在函数中频繁使用的自动变量,例如循环控制变量。 文件作用域 static可以加在函数定义前,使这个函数只能在本文件里的其他函数调用,称为静态函数。extern声明全局对象。 namespace作用域,namespace关键字用来命名定义空间,用户声明的每个namespace都是一个作用域, using 声明可以将namespace中的名字引入特定作用域。 using std::cout; using namespace std; 可以出现在全局作用域、namespace或局部作用域中 引入的名字从using声明开始到其所在作用域结束都可见。 c++程序对象的存储类别有静态存储,自动存储和动态存储。静态分配是指在全局静态存储区为变量分配内存空间,自动分配指在程序的运行栈存储区中为变量临时分配内存空间,动态分配是指利用被称为堆(heap)的内存块为变量分配内存空间 (new,delete)。
类和对象 抽象数据类型ADT,常见定义方式是采用结构体加全局函数。结构体描述数据,全局函数描述对这些数据的操作。数据成员与成员函数,结构体内的函数称为成员函数,数据称为数据成员,这样的结构体被称为类。
感悟 c++这门课明显要比上学期难很多,里面有很多新的概念,且比较难理解,所以应该多花时间去理解这些知识点,并且应该注重课后的复习和预习,稳固学过的知识。