程序设计B阶段学习总结
首先,在这份学习总结中,我会分为四部分总结:
1.阶段学习中学过什么知识
2.怎么运用学些过的知识
3.学习知识中要注意的细节跟技巧
4.课堂感想
一.学习过什么知识
在我这段时间的程序设计学习中,最重要的就是学习了与类相关的知识,所有的知识点基本都是围绕着“类”来进行的,而且我主要是找了一些我认为是重点的知识点进行了总结。
首先学习的是复合数据类型,重点学习了数据类型中的自定义类型,从结构体开始逐渐引入了类的概念。
1.结构体内容
结构体的定义格式如下:
struct 类型名
{
数据类型1 成员名1;
数据类型2 成员名2:
...
}
结构体主要应用于把一系列相同类型或者不同类型的数据整合到一起
例如:一个学生信息可以看作一个结构体,结构体中包含有姓名,年龄,年级,班级,学院,性别等等不同数据类型的信息,利用结构体便可以把这些信息都整合成一个结构体数据成员。
也可以在结构体中定义成员函数
struct Student
{
string name;
int age;
bool sex;
string class;
...
void input();{
cin>>name>>age...
}
void output();{
cout<<name<<age....
}
...
}
2.运算符重载
“运算符重载”常用于解决结构体或自定义数据类型的加法、减法等特殊含义的运算。运算符重载的一般格式为:
类型名 operator 运算符 (const 类型名 变量)const{
…
}
3.string类
string为字符串对象
string 可以支持字符串数组的各种操作
例如:
①各种不同的初始化方式;
②字符串之间的复制,比较,链接
③查询字符串长度
④访问字符串中的单个字符等等
string s1, s2; //创建两个空字符串对象
string s3 = "Hello, World!"; //创建s3,并初始化
string s4("I am ");
s2 = "Today"; //赋值
s1 = s3 + " " + s4; //字符串连接
s1 += " 5 "; //末尾追加
cout << s1 + s2 + "!" <<endl; //输出字符串内容
还有几个小知识点:
①在读入数据的时候要注意使输入流对象处于有效状态;
②可以使用getline()函数读取信息
③empty()函数判断string对象是否为空
④size()函数获取对象长度
⑤"+"可以连接多个string对象(要求至少有一个运算对象为string )
⑥string 对象的下标范围是从0到s.size()-1(所以在使用数组对象是要注意下标的问题)
4.指针
要学习指针主要是要明白指针“指”的是什么。
指针指的是一个对象的地址,称为指针”指向”该对象
①要获取对象的地址,需要使用取地址运算符“&”
int ival = 120;
int *pi = &ival;
// pi存放int变量ival的地址
// 或者说pi指向ival
char ch = 'a', *pc = &ch;
// pc指向字符型变量ch
②如果指针指向一个对象,则可以通过指针间接访问该对象。使用指针解引用运算符“*”
int x = 100, y = 20;
int *pi = &x;
*pi = y;
// 间接操作pi指向的x,即x = y
③指针的类型即指针指向的类型
例如,如果指针指向整型
int *pi=&x;
④指针的值只能为地址,不能保存非地址值,也不能被赋值或初始化为不同类型的地址值
int *pi = &ival; // pi 被初始化为ival的地址
int *pi2 = ival; // 编译错误,ival不是地址
5.类和对象
有了前部分结构体的学习,再接触类的知识就显得很从容了,虽然是两个不同的知识点,但在用法和结构上又很大的相似点,所以可以相互对比着学习。
①类的定义
Ⅰ.类是对具有相同属性和行为的一类客观事物的概括描述。是用户自定义的数据类型(程序设计语言角度)
Ⅱ.类的定义包括行为和属性两部分(可以简单理解为成员和操作两部分)
举例:以学生类为例,数据成员有姓名,学号,性别,年龄,成绩等等。行为也就是成员函数可以有输出函数等。(与结构体的定义基本相似。只不过类的访问属性有区别)
class Student //定义学生类Student
{
private:
string name;
string id;
char sex;
int age;
double score;
...
public: //声明类成员
void display();
...
};
②类的访问属性有:
访问控制 含义 | 属性 |
---|---|
public 公有成员 | 类的外部接口 |
protected 保护成员 | 仅允许被雷成员函数以及派生类成员函数访问 |
private 私有成员 | 仅允许本类成员函数访问 |
如果外部的类需要访问private成员时,需要在本类中加入该成员的公有get,set函数。get函数用来使外部的类获取该成员,set函数可以使外部的类修改该私有成员。
③类的函数定义可以分为类内定义与类外定义两种
类内定义时可以首先声明,也可以同时写入函数体
类外定义格式:
返回值类型 类名::成员函数名(参数表)
{
函数体
}
例如:
void student ::display(int x)
{
cout<<x;
}
④类成员的访问
可以采用对象名.成员名方法访问
也可采用对象指针变量名->公有成员方式访问
⑤成员函数也可以重载
函数重载:
函数名相同,但参数不相同(类型不同,或者个数不同)的一组函数。
函数重载用于处理不同数据类型的类似任务
例如:
#include<iostream>
using namespace std ;
int a(int a)
int a(int b,int c)
int main()
{
int a(int a)
{
cout<<a;
}
int a(int b,int c)
{
cout<<b<<c;
}
如果在定义的时候形参为一个整型数,则自动调用只有一个整型形参的函数;
如果形参为两个整型数,则自动调用含有两个整型形参的函数。
6.深复制浅复制问题
关于浅复制:
(1)对于复杂类型的数据成员只复制了存储地址而没有复制存储内容
(2)默认复制构造函数所进行的是简单数据复制,即浅复制
关于深复制
通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式称为深复制。
深复制构造函数的特点
定义:类名::类名([const] 类名 &对象名);
成员变量的处理:对复杂类型的成员变量,使用new操作符进行空间的申请,然后进行相关的复制操作
7.静态数据成员
类成员冠以static声明时,称为静态成员。
静态数据成员为同类对象共享。
静态数据成员的特点主要在其共享性上,静态成员不属于某一个单独的对象,而是为类的所有对象所共有。
除静态数据成员以外,一个类还可以有静态成员函数。
静态函数仅可以访问静态成员。
8.友元函数
友元有三种:
(1)友元函数
(2)友元类
(3)友元成员函数
通过让函数成为友元,可以赋予该函数与类成员函数相同的访问权相。
上面例子中,左侧的操作数是调用对象,也就是说:
Time A,B;
A = B*2.75;//allow
A = 2.75*B;//not allow,because 2.75 not Time
为了解决这种情况,使用非成员函数
Time operator*(double m, const Time & t);
但是非成员函数不能访问私有数据,那么必须声明为友元,才可以访问。
friend Time operator*(double m, const Time & t);//定义的时候不需要friend
A.虽然operator * () 函数是在类声明中声明的,但它不是成员函数,因此不能使用成员操作符来调用。
B.虽然operator * ()函数不是成员函数,但它与成员函数访问权限相同。
9.运算符重载和函数重载
①定义:
重载就是赋予新的含义。
函数重载可以让一个函数名有多种功能,在不同情况下有不同的操作,运算符重载也是同样。
实际上,我们已经在不知不觉中使用了运算符重载,例如:+号可以对不同类型的数据进行加法操作; << 既是位移运算符,又可以向控制台输出数据,C++本身对这些运算符进行了重载。
②作用
用复数类举例
//Complex c3 = c1 + c2;
//原因 Complex是用户自定义类型,编译器根本不知道如何进行加减,编译器给提供了一种机制,让用户自己去完成,自定义类型的加减操作。
③ 规则
1)不是所有运算符都可以重载
能重载的运算符:+ - * / % ^ & | ~ ! = < > += -= = /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ – , -> -> () [] new new[] delete delete[]
[]是下标运算符,()是函数调用运算符。
不能重载的运算符:长度运算符sizeof、条件运算符: ?、成员选择符.和域解析运算符::以及 ->成员指针访问运算符、#预处理符号。
2)重载不能改变运算符的优先级和结合性。
3)重载不会改变运算符的用法。
4)运算符重载函数不能有默认的参数,否则就改变了运算符操作数的个数,这显然是错误的。
5)运算符重载函数既可以作为类的成员函数,也可以作为全局函数。
将运算符重载函数作为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数。之所以少一个参数,是因为这个参数是隐含的。
另外,将运算符重载函数作为全局函数时,一般都需要在类中将该函数声明为友元函数。因为,该函数大部分情况下都需要使用类的 private 成员。
6)箭头运算符->、下标运算符[ ]、函数调用运算符( )、赋值运算符=只能以成员函数的形式重载。
下面是函数重载示例
#include <iostream>
using namespace std;
class printData
{
public:
void add(int i, int j) {
int num = i + j;
cout << "两个整数和为: " << num << endl;
}
void add(float f, float g)
{
float num = f + g;
cout << "两个浮点数和为: " << num << endl;
}
void add(int f, int g, double k) {
double num = f + g + k;
cout << "三个数和: " << num << endl;
}
};
int main(void)
{
printData pd;
pd.add(5, 5);
pd.add(5.5f, 4.5f);//传入的参数必须加f
// 如果传入的参数不带f,会报错
// 原因是传入的参数5.5,C++里直接的实数字面值常量系统会解释为double类型,那么从double可以隐式转化为float或是int,编译器就会报错,有两个函数可以调用,到底用哪个?修改为pd.add(5.5f, 4.5f),就好了,这样显式声明为float类型。
pd.add(5, 5, 1.2);
return 0;
}
运算符重载
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
Box operator+(const Box&);
声明加法运算符用于把两个 Box 对象相加,返回最终的 Box 对象。大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果定义上面的函数为类的非成员函数,那么需要为每次操作传递两个参数,如下所示:
Box operator+(const Box&, const Box&);
二.怎样运用所学过的知识
在这一阶段,主要学习的是与类相关的知识,所以要在类上进行运用,到目前为止已经进行过了两次代码作业的编译,第一次是链表类。
在链表类中其实说到底也就是最初的增删查改功能,因为通过数据结构的学习,我认为定义一个Node类型的结构体的话,做题会更加的便捷,所以使用了类与结构体相结合的方法。
第二个作业是通讯录,说到怎样运用所学知识,我做题之前会大体要先明确我需要添加的数据成员有哪些,具体的成员函数有哪些,然后会画一个简易的结构图,或者是思路图,然后会通过思路图去联系所学的知识,如果对知识比较熟悉的话,就紧接着实现代码,如果比较陌生,就会进行复习,然后写几个小的demo来简单实现一下,如果代码可以实现,在运用到程序当中去。如果遇到新的知识,或者是没有见到过的,也会先查阅相关资料,学会之后还是先通过demo的方式调试通过后在进行应用。
三.学习知识中要注意的细节跟技巧
①因为我这次的学习是重修,有了上一次的失败的经验后,我知道了我学习中的缺点是在哪里,关键就是在尝试少,也就是说看得多,动手少。
②所以从这学期学习开始我都是左边是平板,看着老师讲课。右边是电脑,随时进行老师上课所讲述知识的尝试,真的保证了老师所讲的每一个内容我都是亲手去尝试了一边,并且在课间或者是课下进行了相关知识的扩展。如何有不会的知识,立马会通过查资料或者是回放的方式来进行复习。
③我认为老师给出的OJ上的题目都很好,虽然没有做硬性要求,但是我也跟着做了一个,上面的题目虽然不如平时老师给的题目要求多,要求复杂,但是都是最基础的题目和要求,如果能把上面的题目熟练掌握了,对于平时的编程就会感觉得心应手很多了。
④老师上课经常会强调一些重点,这些重点就是我们需要着重记忆也是需要注意的点
四.课堂感想
在课堂上其实感想并不多。。。因为一直都在紧张的一边听课一边自己码代码去尝试老师讲述的问题,其实我最大的感受就是有点累但是同时感觉很充实。老师讲解的细致周到,该强调的地方也会着重强调。
在课上详细地听取了老师的要求,边听取老师的分析,再自己进行总结,然后开始进行简单地类的设计,再逐步深入地进行函数总结,在一步一步地调试程序中,看着“黑色框框”的交替出现,虽然已经进行了一年半的编程生活了,但是每次在写c++是出现“黑色框”的那种愉悦感和幸福感是无法替代的。
费老师的讲课风格其实跟其他老师略有些不同,费老师比较着重于我们的自我学习能力方面,很明显可以感觉到,也可能是老师想培养我们的自主学习能力吧,而且我认为这种学习的方式是很适合程序员学习的,因为很多知识是需要我们自主学习并且掌握的,老师布置作业是会偶尔加一些新的知识,并且要求我们自己查阅资料进行学习和掌握,这其实就是让我们自主学习的过程。
最后,进行一下课堂的总结吧。
①.最重要的一点,每次打完一个类或者一个函数,都写一个主函数进行一边测试,千万不要全部打完然后再进行程序的调试,那样不仅会增大工作量,而且还可能会出现各种不必要的麻烦。
②.要多打几个demo测试一下不同的功能,这样会帮助我更好的进行类的运行,都是在为最后程序的成功运行做铺垫
③.必要的注释一定要加。虽然老师总是强调不允许加注释,但是我认为,必要的注释还是很有用的,尤其是在最后的调试程序和优化程序上,由于程序可能过长或者功能过多时,如果没有注释的话,找某个功能函数或者类比较困难,这时候如果能有注释的话便可以一目了然。