写在前面:OI打的好不等于这堂课不用认真学.OI是面向过程设计,算出答案就完了,这个侧重封装.OI确实可以让人灵活运用各种语法,但是这个$class$用法很多,都要认真看.
程序=(算法+数据结构)s,使用对象框架组装程序.也就是,时代变了,有$MONEY$了,撑得起更大的程序了,不面向过程了,都有对象了(雾)…
一个学期就只学了一个$class$的用法,有封装,继承,多态,这是三个基本特征.
类与对象:类($class$)只是一个空的框架,对象是由类衍生出来的.它和结构体($struct$)的区别有以下三点:
1.有权限划分.这就是接下来会讲的$public,private,protected$.
2.有全局变量.就是那个$static$.
3.有合构析构函数,更方便用了.
$\mathbf{public,private,protected}$三种属性:$public$所有人都能访问的,$private$和$protected$都是对象内部随便访问,对象外不可访问的,区别在继承那里会有介绍.默认是$private$,在碰到下一个标志前都是这个权限.
$\mathbf{static}$关键字:静态成员,静态函数.用法和$inline,register$一样,加在函数或者变量名前就好.$static$让函数或变量变成静态的,想象一个学生对象,老师就是静态的,学生一届又一届,但是老师不变(排除特殊状况),老师就是静态的.老师根本不认识对象,只知道有多少个学生,学生去哪了被销毁了和老师都没关系.注意静态变量使用前记得先分配内存.举例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class node{
public:
node(){
cnt++;
}
~node(){
cnt--;
}
void prr(){
printf("%d",cnt);
}
private:
static int cnt;
};
int node::cnt=0;
signed main(){
node a;
a.prr();
return 0;
}
那句$cnt$声明删了会出错,因为没分配内存.$static$修变量的作用主要有以下三点:
- 流动统计.实时统计当前开了多少个对象.
- 作为标记符,代表特定的事件是否发生,比如磁盘读写,同时只能有一个读写磁盘,就用标记表示.
- 链表头指针或尾指针.
类名遮挡:名字重了咋办.类名允许和变量名一致,每次需要使用变量时就直接用,用到同名类时就加$class\space name$即可.同理函数中的变量名可以与类中的变量名重,使用的时候加上$::$即可.
合构函数,析构函数:类新建成员初始化会调用的函数,成员被delete时调用的函数.新建一个对象默认会分配一个合构函数和一个析构函数,但是他们什么也不做,通过自己写合适的函数实现合理的初始化.
格式:与类同名,没返回值,析构加一个 ~ 即可.
注意系统在编译阶段检查到你写了合构或者析构之后默认什么也不做合构或者析构函数会消失,也就是说你要是想合构函数传参的话记得写默认的情况,省的运行出错.下面是一个简单的示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class node{
public:
node(int val){
a=10;
b=val;
c=0;
cnt++;
}
node(int val,int vval,int vvval){
a=val;
b=vval;
c=vvval;
cnt++;
}
~node(){
cnt--;
}
void prr(){
printf("%d %d %d %d",cnt,a,b,c);
}
private:
int a,b,c;
static int cnt;
};
int node::cnt=0;
signed main(){
node a(0);
node b(1,1,4);
a.prr();
return 0;
}
:: 类外可以写函数.方法对是类内声明,类外写$xx::xx(xx){xx}$函数即可写函数.类直接访问成员都是$::$,指针访问类成员用$->$,一个声明过的对象的直接调用$.$就行了.
默认值:函数在声明时候传参可以这样:1
int ko(int val=10,int num=20){xx}
如果调用这个函数时缺少参数:
1 | koi=ko(0); |
第一个数就会被调用的传参顶掉,第二个参数由于少会使用20这个默认值.注意缺省参数只能在后面缺,前面(比方说下面这个就是错的)缺参数不能过编译:
1 | koi=ko(,0); |
类之间的关系:互不干涉.比如我需要一个学生类,学生里面套一个学生ID的类,此时声明一个学生会优先调用套娃里面的ID合构函数,然后再调用套娃外面的学生的构造函数,自动调用的.
但是这导致一个问题.我希望给ID传参该怎么办?在学生的合构函数不能调用ID的合构函数,因为不能干涉,但是如果新建一个ID会直接在合构函数运行之后销毁掉(函数内部声明变量开的栈区空间).
新语法来了,专门解决这个问题的(如果有好多个对象就逗号隔开,像下面一样).
1 | Student(int a=10,int b=10):ID(b),xx(xx){xx} |
这个冒号后面大括号前面的就是对ID先进行初始化,然后再对主的学生对象进行合构的体现.如果不写冒号以及后面的合构函数,就会调用默认无参数的合构函数.
这个冒号很灵性,就可以对常量数据成员和引用数据成员进行初始化.比方说下面一段代码就初始化了一个常量和一个引用成员.
1 |
|
构造对象的顺序:以下几点:
- 局部和静态对象按照声明顺序构造(函数中新建一个变量)
- 静态对象只被构造一次
- 全局对象都在$main$之前进行构造
- 全局对象构造时无特殊顺序
- 成员以其在类中的声明顺序构造:解释一下
1 |
|
输出1
-858993459 3123
这份码因为最底下$ab$顺序导致调用合构函数时顺序变化,产生了野值.
重载运算符:这里主要讲$++$和$—$的运算.
首先内部类型不允许重载,比方说$int$.这个很好理解,基本数据结构被重载以后$C++$会大乱的.
然后是操作数变不了,还有几个诸如$->$,$?:$,$::$,$.$,$@$(新运算符)不允许重载之类的规定.
举例如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class ko{
public:
ko(int val=10,int vval=10):b(val),a(vval){}
~ko(){}
ko& operator ++(){
a++;
return *(this);
}
ko operator ++(int){
ko tmp(*this);
a++;
return tmp;
}
void prr(){
printf("%d %d\n",a,b);
}
private:
int a,b;
};
signed main(){
ko a(4,4);
(a++).prr();
(++a).prr();
return 0;
}
这就是自加,$C++$约定区别在于一个$int$.
$\mathbf{new,delete}$:为什么我们需要它?
分配空间的时候,$new$会调用合构函数,而$delete$的时候又会调用析构函数.也就是说,不常用的1
int *p=new int(10);
其实是一个调用合构函数的过程.原来是这么回事.
拷贝构造函数:为了防止乱用$=$导致权限分配或者数据分配混乱的问题,有了拷贝构造函数.一般传参传$\&$对象.
注意:有的时候对象分配了资源(比如堆内存),拷贝直接复制地址是会出错的,所以自己写一个拷贝构造函数分配内存很有必要.
无名对象:正如你所见,没名字的对象.这玩意有用,写作:1
ko(10);
用法有:
- 函数参数.假如函数传参要一个对象,就可以写一个无名对象顶上去.
- 初始化引用以及初始化对象定义.如:
1 | ko& koi=ko(10); |
C++的试探:在$C++$中,$5/2$和$5.0/2$是两个完全不一样的东西.$C++$知道如何把整数转成$double$,也知道计算结果.但是对于我们写的类,$C++$的格式转换要靠我们实现.
如何实现呢?就靠我们写的合构函数.
如下是一段$C++$进行格式转换的代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ko{
public:
ko(const char arg[]){
strcpy(arr,arg);
}
void prr(){
printf("%s",arr);
}
~ko(){}
private:
char arr[30];
};
void koi(ko op){
op.prr();
}
signed main(){
koi("hello");
return 0;
}
我们可以看到,传参传一段字符串,自动匹配了一个合构函数然后调用了,进行后续运算($const\space char[\space]$和$char[\space]$是不一样的).
$C++$有几点要求:
1. 只会尝试有一个参数的合构函数
2. 当有二义性时立即放弃尝试(比如,学生老师用一个打印函数,名字又是都有的部分,$C++$发现可以是老师也可以是学生,立刻退出了).
$\mathbf{friend}$:友元函数.有的时候普通函数也需要访问对象的保护成员,为了加快效率.比如矩阵和向量的乘法,乘法的函数不可能同时是两个函数的成员,所以就让它是个普通函数,通过友元的联系来实现乘法.举个例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class tsc;//这行的作用是让下面的friend中的prr认识tsc
class ko{
public:
ko(){
for(int i=0;i<10;++i){
num[i]=i;
}
}
friend void prr(ko a,tsc b);
private:
int num[10];
};
class tsc{
public:
tsc(){
for(int i=0;i<10;++i){
num[i]=i;
}
}
friend void prr(ko a,tsc b);
private:
int num[10];
};
void prr(ko a,tsc b){
for(int i=0;i<=9;++i){
printf("%d ",a.num[i]+b.num[i]);
}
}
signed main(){
ko a;
tsc b;
prr(a,b);
return 0;
}
友元函数除了对于标记友元的可以看他的内部成员外,就是个普通函数.一个类的成员可以是另一个类的友元,使用$::$选中函数,一个类也可以是另一个类的友元,直接$friend\space class\space name$.友元的第二个作用:方便重载操作符的使用.
继承:就是在原有类上加点东西,让他变成一个新的类.比如,研究生在大学生基础上加点自己的东西.语法如下:1
class yanjiusheng:public daxvesheng{xx};
继承有什么作用呢?
- 可以通过改一个小类来实现继承大类的修改,更方便维护.
- 继承可以让$C++$做隐式格式转换.比如函数要求传大学生的参,我传一个研究生的参,也是可以被接受的.如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class tsc;
class ko{
public:
ko(){
for(int i=0;i<10;++i){
num[i]=i;
}
}
friend void prr(ko a);
private:
int num[10];
};
class tsc:public ko{
public:
tsc(){
for(int i=0;i<10;++i){
num[i]=i;
}
}
private:
int num[10];
};
void prr(ko a){
for(int i=0;i<=9;++i){
printf("%d ",a.num[i]);
}
}
signed main(){
ko a;
tsc b;
prr(a);
prr(b);
return 0;
}
继承方式:在这里,$protected$和$private$会进行区分.
一个类作为基类(大学生)时,其$public$和$protected$都可以随便被派生类(研究生)任意访问和调用,但是$private$真的就是谁也用不了,除非声明友类.
看例子,冒号后面的$public\space ko$这个权限分给的是类之后的东西.假如改成$private$或者$protected$,下面的$prr(b)$就会报错,理由是成员不可访问.(记住$private$权限最严就行)
注意到例子中的$ko$和$tsc$都有名字叫$num$的数组,为什么不冲突?其实只要访问$ko$中的$num$数组时加个$ko::$就没问题了.
调整访问控制:冒号后面加的权限因为是取高的很容易什么也看不到,就需要改权限.如下:1
2
3
4class tsc:public ko{
public:
using ko::num;
};
这就把$tsc$派生类的$ko$中的$num$调成了公有了.
继承和组合的关系:略.
多继承:加逗号隔开,加权限即可.但是这个时候注意变量名字加$::$区分是源自哪里的.
虚拟继承:加$virtual$.虚拟继承的含义是,如果没有该类就新建一个,如果有了就不用动了,用建好的那一个.比如,$victim$和天选和$tsc$(再临)都是$\mathbf{Alan\space Becker}$画的,但是再临拥有前两者的一切战力,怎么表示?代码如下:
1 |
|
这样加$virtual$就会让再临只有一个$animation$了.
注意:虚拟继承和虚拟函数是两个截然不同的概念.
构造顺序:成员里面套类,继承,虚拟,etc.
但是真的建一个类他们的顺序怎么办呢?为此规定:
- 虚拟先构造,顺序按照继承顺序
- 非虚拟的继承构造,按照继承顺序
- 成员对象
- 类自己的合构函数
多态:若语言不支持多态,则不能被成为面向对象的语言.
$virtual$的用法:比如一个订单系统,分普通用户和$\mathbf{VIP}$用户,他们的买东西结算算法不太一样(打折),但是VIP除了打折没什么不同,我只想用一个函数实现计算,就需要用到虚函数.
$\mathbf{virtual}$:和$inline$一样,挂在函数的前面发挥作用.它的意思是迟后联编,后面的同名函数会覆盖前面的函数,所以后面的函数加不加$virtual$其实没区别,只要前面加了就行了.比个例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class user{
public:
user(int val=998){
buy=val;
}
virtual int calc(){
return buy;
}
protected:
int buy;
};
class VIP:public user{
public:
VIP(int val=998):user(val){}
int calc(){
return buy/2;
}
};
signed main(){
VIP a(10);
printf("%d",a.calc());
return 0;
}
这就是一个简单的VIP用户打折的程序,重写了$calc$让不同用户计算方式不同.
失败的迟后联编:计算函数传参不同,返回值不同,etc所有不能被看成相同函数的情况.
可返回不同类:B继承A的,函数有两个,一个返回值是A,一个返回B,这个时候就可以用$virtual$进行联编.
虚函数的限制:众所周知,$C++$追求快.所以只会选择个别的函数整成虚函数,那么限制就来了:内联不可以,只有类的成员函数才可以,合构析构不可以,静态不可以.
抽象类与纯虚函数:只要有至少一个纯虚函数,这个类就是抽象类.纯虚函数就是函数声明时后面加=0,前面加$virtual$.比如:1
virtual int ko()=0;
首先注意,纯虚函数不可以实例化.抽象类不可以实例对象,抽象类就是用来继承的,继承的子类重写那个纯虚函数,子类可以对象化.所以抽象类又被称作接口.
为什么要抽象类?方便指针的使用.先前提到继承的情况下,派生类的指针完全可以当成母类的指针去用,因为成员是一样的.这里就是可以用抽象类指针传参,然后调用直接放上派生类的指针,$C++$会自动匹配的.
分文件编写
做课设几千行代码不分文件很难维护.
现在你要写一个$Visual Studio$程序.人有五名,主文件有三个.
首先要写一个头文件.头文件一般是$.h$的格式.新建一个空项目,添加一个空项.
头文件的基本结构:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17//name:function.h
//author:NaraFluorine
//#include<xxx>
//头文件开始写了
extern int n;//在function.cpp中定义的变量这里写成这个
void prr(int num);//在function.cpp中声明的函数这里写成这个
头文件对应的实现文件的基本结构(头文件只用来画大饼):
1 | //name:function.cpp |
主文件的基本结构:
1 | //name:main.cpp |
这就完了.每个模块负责不同的函数,可以把大工程划分为一个一个小零件,一部分出错不需要整体重新编译.
有个部分忘写了,是$class$的用法,记住一个事情,$class$的声明都在头文件里面,然后函数就是正常的画大饼就好,但是对应的$cpp$要写成展开的,同时注意标清哪个$class$,比如下面的例子:1
2
3
4
5//poly.h节选
class poly{
public:
void a(int x);
}1
2
3
4//poly.cpp节选
void poly::a(int x){
//展开写函数
}
然后对于重载运算符实例化可以写在外面,但是有两点不同,一是操作数记得整俩,二是记得声明友元,否则看不了成员变量(这是全局重载和成员重载的区别).
常见问题:
1. 安全问题:$VS$不赞成使用$scanf$和$printf$,因为他们”不安全”(缓冲区溢出),VS强推更安全的$scanf_s$,或者加上这句话 #define _CRT_SECURE_NO_WARNINGS 就可以无视警告接着用.
2. 关于$include$后面的 <>"" :尖角和引号的差异在于优先搜索哪里.正常的使用尖角的情况是使用库文件的时候,如$stdio.h$或者$algorithm$,系统看到尖角会优先搜索库文件.引号的意思是系统优先搜索该$.cpp$对应的文件夹找这个头文件,一般自己写头文件的会用引号包起来,当然用引号包库文件也不会有错,使用引号包住功能实现良好的$.cpp$文件也能运行的.
3. $VS$:$Microsoft\space Visual\space Studio$,简称$VS$,是一个IDE.一般写大型项目会用.为什么要用$VS$而不是$Dev$,因为功能全.但是由于安全(上文)或者不让用$__int128$,编译慢(初次启动编译三十秒,后面一两秒出来)之类的,打算竞还是用$Dev$更好.
UPD20240609:
做题总结
众所周知,学的和考试考的往往是两个东西.
C++内存分配:算了,懒得写了,看这个吧
C++多文件的好处不是能同时编译生成多个可执行文件.
执行a.f(100)成功时,f可能的参数表不可以是f(int&),但是可以是f(const int&)
protected方式下,派生类对象的指针不可以转换成基类指针.
静态成员的初始化:
一个类不能实例化对象有哪几种情况:1抽象类2构造函数是私有的
静态成员函数没有this指针(所以不可以加virtual,const).
this指针是一个指针常量.(const A*)指向类对象 而不是类类型,看清楚了
友元:C++友元不具有传递性
某些运算符重载只能在类内实现:= () [] ->
const的作用:先向左匹配,左边没有东西才会向右匹配,如:int* const p表示一个常指针,而const int* p和int const* p表示都是一个指向常量的指针.
构造函数要么都有缺省值,要么都没有缺省值. √
内联函数:运行时插到每一个调用函数的地方.
抽象类通常也需要构造函数.
常成员函数:可以被非常成员调用.
常量对象:只可以调用类的常成员函数和静态成员函数,不可以调用非常成员函数.
不允许创建指向自身类型的常量指针和引用.(套娃的官方说法)
构造函数重载错误:A();A(int=0,int=0);
耦合度:继承的耦合度高于组合,实战中应尽量选择组合而不是继承(耦合度要尽量低).
通过声明私有禁止乱拷贝,拷贝构造函数.
虚表和虚指针:虚指针每个对象都有一个,但是虚表是每个类只有一个的东西(也可以有虚表组).
虚基类:C++由于支持多重继承可能导致名字冲突,所以提供了这个.虚拟继承的基类就叫虚基类.
虚函数访问:非虚非静可以访问虚函数.
接口:C++支持接口.
B b和B* pB两种格式作为类A的数据成员的区别:Bb是一般不需要拷贝构造函数的,而pB通常需要拷贝构造函数.pB的时候B可以是抽象类而Bb不可以是抽象类.
关联,聚集关系:关联分为单向关联和双向关联,双向关联是A中有B,B中有A的这么一个关系,聚集可以理解为组合,代码上没有差异.
封装:可以定义私有成员和保护成员.
多态:面向对象语言中,接口的多种不同实现方式即为多态.多态性允许父对象被设置为和子对象相等的技术,赋值以后父对象可以根据当前赋值给子对象的特性以不同方式运作,允许子类将类型指针赋值给父类型指针.多态性在C++和Object Pascal中都是用虚函数实现的.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class a{
public:
virtual void fuck()=0;
};
class b:public a{
void fuck()override{
cout<<"aaa";
}
};
class c:public a{
void fuck()override{
cout<<"bbb";
}
};
signed main(){
a *ppp=new c;
ppp->fuck();
return 0;
}
多态:声明一个大的,然后因为大的覆写抽象类了,
类中没虚函数就没虚表了吗?x,如果他的基类有,他还是会有虚表的.
private和protected的区别:继承后子类可见不可见的问题.
catch支持多态地捕获派生异常.异常可以本层处理也可以部分处理后向上层抛出.(类型不需要严格相同)异常可以在外层函数中捕获,也可以在当前函数中捕获.举例:1
try{f();}catch(){}
如果f中没有try catch,f可以被catch捕获.
父子同名函数:1都不是虚函数2父不是虚函数子类是虚函数3都是虚函数
函数占位参数:和默认值相反,占位参数只要出现必须填满.而且,正如其名,他只有类型没有名字,而且必须对应上,比个例子:f(int,int k,int i=0)这里的没名字int就叫占位参数,他只要出现就必须被填上,否则函数会匹配失败.这种占位的也可以有参数,比方说int=0之类的
内存:构造时new了好多内存是不算在类大小里面的.
成员函数:A以下情况不可以调用B:1A是静态函数B不是2A是常成员函数B不是
函数重载:体会一下,必须完全一样 才能触发重载.1
2int fun(int);和int fun(int,int=0);
int f()和int f()const
不会构成二义性,会构成重载.判断依据:参数个数,参数类型,参数顺序,函数是否为const.
基类的成员函数可以和派生类重名,但是数据成员不可以重名
抽象类的基类也是抽象类.
如何避免A外再派生其他类:A的构造函数正常public写,且A的析构函数设置成私有而且不进行实现(或者设置成纯虚函数).
初始化列表:a(),b(){}这个部分.有四种情况:1常量2引用3基类缺少无参数构造函数4类套类需要传参的情况.5其他需要在类初始化之前就需要初始化的情况.
前加加:A& operator ++(){}后加加A& operator ++(int){}区别在于一个int.
所有的operator返回值参考:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29class a{
int dat;
a operator +(a& io);
a operator -(a& io);
a operator *(a& io);
a operator /(a& io);
a& operator =(a& io);
a& operator ++(){
dat++;
return *this;
}
a& operator ++(int){//注意运算顺序
a tmp(*this);
++(*this);
return tmp;
}
a& operator --();
a& operator --(int);
a& operator +=(a& io);
a& operator -=(a& io);
a& operator *=(a& io);
a& operator /=(a& io);
bool operator ==(a& io);
bool operator !=(a& io);
};
原因:赋值运算的结果是左值,应当按引用返回.
常见错误:
double转float是不安全的.
析构函数有参数
类A开头默认私有的
乱加const的
继承未完全覆盖虚函数的(不能实例化)
继承调用私有参数的(权限问题)
不写using namespace std;然后用标准库的
少隐式格式转换的
少构造函数的
大题
看到一个写法是:std::vector<std::string> f(){return {"message1","message2"};}维克托好像可以用大括号构造的.
关键字
overide:覆写虚函数时加上的,比个例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21class a{
public:
virtual void fuck()=0;
};
class b:public a{
public:
virtual void fuck(){
cout<<"fuck you!\nCyka blyat!";
}
void fuck(){
cout<<"fuck you!\nCyka blyat!";
}//这三份代码实际跑起来没有差异,所以知道override是什么就行了
void fuck()override{
cout<<"fuck you!\nCyka blyat!";
}//
};
b aa;
signed main(){
aa.fuck();
return 0;
}
加强代码规范的.
namespace:名字空间.有的时候有好多函数都叫一个名字,就需要名字空间来进行区分.名字空间不应当被放在头文件里面.名字空间也可以嵌套.
dynamic_cast<>():类型的向上转换.比如父类派生好多子类,子类转父类是安全的,但是dynamic_cast<儿子>(父类变量)则是转换成儿子的.众所周知每个爹都不想当儿子,于是这种转换需要代价.
explicit:构造函数加一个这个可以禁止隐式格式转换.
应试
这是一个很关键的部分,而且不止这场考试适用,将来几乎所有大学考试都适用(不适用于四六级和竞赛)
首先要明确一点,大学的考试是合格性考试,和初高中的选拔性考试不同.
具体地,初高中的考试有明确的答案,写到哪里得多少分明码标价,会做分就是会很高.
但是大学的应试规则和高中完全不一样.你可能上大学前见过”一天速通线代”然后评论”没打过这么富裕的仗”一类的言论,但我想说,这是真的,而且这是一个相当高明的战略.
Flu给读者的建议:
- 如果你通过了这门考试,请忽略这篇文章,这对你的收益非常少,有这时间不如刷会抖音,或者看看Flu的其他文章:)
- 如果你正在为这科考试复习,你要想清楚了:
这门考试怎么能拿分?(看历年卷子推测要靠考什么,怎么考,不要看课内讲什么,要看考什么)
这门课知识容量大概多大?几天能够拿下?(人是会忘的,一个月前你学的东西不见得能记住多少,所以速通是正确的策略,长痛不如短痛,很多满绩的同学也是这么搞的)这很关键,时间太长会导致战线太长(都开始期末了)会很煎熬,时间太短会预习不完
网上有哪些资料能够参考的?(可以看一看其他人对于这门课是怎么说的) - 应试:
下发的答题纸有多大?考试时间有多长?
你大概要给每个题多大的空间答题?
大学课程期末考试的卷子很可能就是教你课的老师出的,卷子很马虎,判卷显然也不可能严到哪里去(听说还有让老师手底下研究生判卷的情况发生),所以请记住一个最重要的原则就是答满,进你所能扯淡,不管会不会都要尽可能把答题纸写满,让老师看到你的态度,你的成绩就不会差,这就需要规划答题纸了,建议考前大致分划一下随机应变. - 关于大作业:
原则1:能不手写就不手写.你或许可以先查查网上有没有历年的学长学姐大作业能抄?
你也许可以先vibe coding一个出来再加功能?
原则2:抄袭并不可耻.或许你在想,这门课没考试只交一个大作业就行了,大作业我想自己写!
这是错的.很多大学课程开课的年限比你出生还早,非常落后时代的课程有什么学习的必要吗?
你上大学就是为了门门考试考满分吗?如果是,我们没办法说服彼此,您可以关闭这个页面了.
祝大家都能取得令自己满意的成绩.