6周的C++,我学会了这些

(一)在第一周的学习中,我们首先学习了递归算法,对递归的要求并不算太高,主要是温习一下之前学过的知识,并且在 算法设计与分析 这门课中,会比较的轻松:

递归:

递归的关键在于找出递归定义和递归终止条件。

递归成功的秘诀在于:

我们不用担心递归方法是如何解决子问题的。
只要简单地了解它能正确地解决子问题,而且使用子问题的求解结果就能正确地解决原问题。层层递归,最终便可得到最终的答案。

记忆化搜索:

在递归的过程中,将已经计算出来的结果保存起来,当之后的计算用到的时候直接取出结果,避免重复运算,因此极大的提高了算法的效率,也就是空间换时间
我们在一般情况下,主要是使用数组。

(二)在第二周的学习中,我们学习了结构体以及指针和引用的相关知识。结构体的内容,在学到类之后,就差不多被类所代替了,因为类有比较好的封装性:

结构体引用成员的三种等价形式:

① 结构体变量.成员名
②(*结构体指针变量名).成员名 (注意括号)
③ 结构体指针变量名->成员名

指针及引用:

new运算符:
  • 分配单个对象:new 类型 或者 new 类型(初始值)

    int* ip1 = new int;
    int* ip2 = new int(100);
    
  • 分配多个连续存储的对象:new 类型[数组大小]

    int* ipa = new int[100];
    
  • 定位new,在指定位置分配空间:new (指针) 类型;

delete运算符:
  • 释放new分配的空间
delete 指针;
delete[] 指针;
const限定指针:

(1)指向const对象的指针(非const ):

const type *cp; //或者type const *cp;

cp是指向常量的指针,它所指向的内存中的内容不可以改变,即*cp的值不能改变

(2)指向非const对象的const指针:

type* const cp = initAddressValue;

cp是常量指针,初始化后值不能改变,指向固定的单元

(3)指向const对象的const指针:

const type* const cp = initAddressValue;
const int ival = 5;
const int* const pi = &ival; 
		//pi是一个指向const对象的const指针
引用:

一般在程序中,引用主要用作函数的参数
必须被初始化,初始值是一个有内存地址的对象。

使用左值引用时注意:
  • 引用并非对象,是为已存在的对象所起的另一个名字
  • 引用只能绑定到对象(有内存地址)上,不能与字面值或某个表达式的计算结果绑定在一起。
有空指针:

指针可以不指向任何对象,其值为0,表示空指针

没有空引用:

引用必须指向一个对象,而且一直指向该对象,不存在“空”引用。

(三)在第三周的学习中,我们学习了类的使用(包含一些特殊的函数),当然也学会了使用C++的特色之一 —— 初始化列表:

类的使用:

数据成员:
  • 除了静态 static 数据成员外,数据成员不能在类体中被显式地初始化
  • 类的成员可以是其他类的对象,称为类的组合。但不能以类自身的对象作为本类的成员。
成员函数:

利用构造函数创建对象:
类名 对象名[(实参表)];
类名 *指针变量 = new 类名[(实参表)];

构造函数初始化成员有两种方法:

  1. 使用构造函数的函数体进行初始化
  2. 使用构造函数的初始化列表进行初始化

析构函数:

  • 析构函数自动调用(隐式调用)
  • 析构函数没有返回值,不能有参数,也不能重载

如果没有定义任何构造函数 ,C++编译器会自动创建一个默认构造函数 。 如果已经定义了一个构造函数,编译器不会自动创建默认构造函数,只能显式调用该构造函数。

何时使用初始化列表:

  1. 常量成员
  2. 引用类型
  3. 没有默认构造函数的类类型

初始化列表的注意点:

1 因为初始化列表中无法直接初始化基类的数据成员,所以我们需要在列表中指定基类的构造函数,如果不指定,编译器则会调用基类的默认构造函数。

2 推荐使用初始化列表,它会比在函数体内初始化派生类成员更快,因为在分配内存后,在函数体内又多进行了一次赋值操作。

3 初始化列表并不能指定初始化的顺序,正确的顺序是,首先初始化基类,其次根据派生类成员声明次序依次初始化,因此,我们现在最好就养成良好的顺序习惯。

(四)在第四周的学习中,我们主要学习了this指针、复制构造函数、浅复制、深复制的相关内容:

this指针的使用:

  1. 在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this;
  2. 当参数与成员变量名相同时,如this->n = n (不能写成n = n)。

复制构造函数:

语法形式:
类名 :: 类名(const 类名 & 引用名 , …);

复制构造函数的特点:
  1. 复制构造函数名与类名相同,并且也没有返回值类型
  2. 复制构造函数可写在类中,也可以写在类外。
  3. 复制构造函数要求有一个类类型的引用参数
  4. 如果没有显式定义复制构造函数,系统自动生成一个默认形式的复制构造函数。
复制构造函数的调用 :
  1. 声明语句中用类的一个已知对象初始化该类的另一个对象时。

    Point ob1;
    Point ob2(ob1);
    

    但是:下面的因为s2已提前声明,所以不会调用复制构造函数:

    Point ob1;
    Point ob2;
    ob2=ob1;
    
  2. 对象作为一个函数实参传递给函数的形参时,需要将实参对象去初始化形参对象时,需要调用复制构造函数。

    fun(Point ob1);
    
  3. 当对象是函数的返回值时,由于需要生成一个临时对象作为函数返回结果,系统需要将临时对象的值初始化另一个对象,需要调用复制构造函数。

    Point fun()
    {
    	Point ob2(2,6);
    	return ob2;
    }
    

关于深复制:

● 通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式称为深复制。
● 自定义复制构造函数所进行的复制是浅复制。

深复制构造函数必须显式定义

深复制构造函数的特点:
  • 定义:类名::类名([const] 类名 &对象名);
  • 成员变量的处理:对复杂类型的成员变量,使用new操作符进行空间的申请,然后进行相关的复制操作

(五)在第五周的学习中,我们学习了静态成员函数和友元函数,学习友元函数只是为了后面的重载,因为友元函数会破坏类的封装性:

静态成员:

  • 类成员冠以static声明时,称为静态成员。
  • 静态数据成员为同类对象共享。
  • 静态成员函数与静态数据成员协同操作。

静态成员不属于某一个单独的对象,而是为类的所有对象所共有

class A
{
  	int n;
	static int s;
};

定义静态成员函数的格式如下:
static 返回类型 静态成员函数名(参数表);

公有访问权限的静态成员,访问形式如下:

  1. 类名::静态成员函数名(实参表)
  2. 对象. 静态成员函数名(实参表)
  3. 对象指针->静态成员函数名(实参表)
  4. 在静态成员函数内部,直接访问。

在类外进行静态数据成员的声明:

类型 类名::静态数据成员[=初始化值];   //必须进行声明

对于类的普通数据成员每一个对象都各自拥有一个副本。(分配不同的存储空间)
不能在成员初始化列表中进行初始化

静态成员函数没有this指针,只能对静态数据操作

(六)在第六周的学习中,我们学习了运算符重载,因为在我们自己定义的数据类型中,C++所提供的运算符难以满足我们的需求,这就需要我们来重载运算符,以达到我们需要的结果:

运算符重载规则:

  • 不能重载的算符. :: .* ?: sizeof
  • 不改变运算符的优先级
  • 不改变运算符的结合性
  • 不改变运算符所需要的操作数
  • 不能创建新的运算符

几个特殊的运算符:

赋值运算符、[] 和 () 只能用成员函数重载,不能用友元函数重载

重载流插入和流提取运算符,只能被重载成友元函数 ,不能重载成成员函数

成员函数重载:

成员运算符函数的原型在类的内部声明格式如下:

class X {
    //…
返回类型 operator运算符(形参表);
  //…
}

在类外定义成员运算符函数的格式如下:

返回类型 X::operator运算符(形参表)
{
     函数体
}
友元函数重载:
class X {
    //…
friend ostream & operator 运算符(形参表);
  //…
}

操作数类型不相同时,必须使用友元函数。

通过这一段时间的学习,我感受颇多:

  1. 首先就是学习上知识的收获,通过对程序设计B的学习,一方面,进一步加强理解了数据结构的知识,对指针的用法也进一步提高;另一方面,虽说和Java的面向对象有点区别,但是用比较的方法来学习,无疑收获会倍增。
  2. 对时间的把控。可能因为坚持“先苦后甜”的原则,我通常就是想赶紧完成任务,这样虽然代码交的比较早,但总有一些方面考虑的不是很周全,代码的性能也就有点低了。所以,以后还是得做好兼顾,在保证质量的前提下提高效率。
  3. “享受”代码。我总感觉自己的耐性不是很好,题目代码调试不出来时,总会感到急躁,看着自己的代码,就会感觉自己写的程序不叫程序。更头大的是自己看着代码,还找不出错误。自己还是太菜,仍需努力。
  4. 认知的提高。毕竟这是一门饭碗课,之前好像看到过,如果在IT行业不想被淘汰,平均3.5个月就得掌握一门技术。不怕别人看不起,就怕自己不争气,如果现在这门课学不好,没有一种学习方法的架构,可能以后会有好几个3.5个月才能够掌握一门技术。
  5. 感觉大家都很努力,也有不少的同学都比较熟练地使用STL中的知识了。当然,有句话是这么说的,你知道的越多,不知道的也就越多,然后知道的就会更多。所以,感觉还是得多多查阅相关的资料,要学的东西还会有很多很多。
  6. 最后,感谢老师的严格要求,这段时间过得比较充实,而又不乏乐趣,因为有代码调试成功的欣喜,感觉得自己也进步了很多。总而言之,感谢老师,感谢老师为培养您的每一位学生而努力奋斗着。

Fighting,forever!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫余

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值