考前复习笔记

1. if的短路效应:

如果&&前面条件不满足,或者||前面条件满足了,那么直接跳出,不做后续操作,意思是如果后面有赋值也没用啦

2. 局部变量会覆盖全局变量

3. do{ }while()

语句是先执行一次,然后看符合条件继续,不符合跳出

4. while小心数组越界!!!

毕竟for里面有判断越界的条件,while里面很容易忘记写

5. 缺省值

要从最右边的变量开始写,右边的有缺省值了左边才可以有缺省值

6. 内存分配

在这里插入图片描述

7. 一些重载

  • 下标运算符
int & IntArray::operator[](int index){ 
	(index < low || index > high){
		cout << "下标越界"; exit(-1); }//越界就直接停掉了
 	 return storage[index - low];
		//返回的是引用类型,来修改数据元素
}
  • 函数调用运算符
    (用圆括号里面写参数值,来对某个对象进行操作,视作函数)如调用arr1 = arr(12, 15, 2),其中arr和arr1都是Intarray类的对象
IntArray operator()( int start,  int end,  int lh){
	if (start > end || start < low || end > high ) {
        cout << "下标越界"; exit(-1);
   }
	IntArray tmp(lh, lh + end - start);             
	for (int i = 0; i < end - start + 1; ++i) 
        tmp.storage[i] = storage[start + i - low];
	return tmp;
} 
  • ++&–
    成员函数
    ++ob重载为:ob.operator++()
    ob-- 重载为:ob.operator–(int)
    友元函数
    ++ob重载为:operator++(X &ob)
    ob–重载为:operator–(X &ob, int)
    调用时,参数int一般传递给值0。
Counter & Counter::operator++(){ 
	if (value == alarm) cout << "已超过报警值\n";
	else { 
		++value;
		if (value == alarm) cout << "已到达报警值\n";
	}
  return *this; //返回修改后的状态
}
Counter Counter::operator++(int x){ 
	Counter tmp = *this; //保存对象修改前的状态
	if (value == alarm) cout << "已超过报警值\n";
	else { 
		++value;//这里*this其实是改变了的!
		//因为是引用了++前的参数,也就是main里面的cnt,所以是可以直接改变的,只是return的时候return的是++之前的情况。
		if (value == alarm) cout << "已到达报警值\n";
	}
   return tmp; //返回修改前的状态,为什么不是返回引用:因为局部变量不可以返回引用
} 

int main(){ 
   Counter cnt(3); //定义一个Counter类的对象,报警值为3
   cnt.print(); /显示对象的当前值,此时输出为0
   ++cnt;
  cnt.print(); // 此时输出为1
  (++cnt).print(); //调用前缀的++,输出2
  (cnt++).print(); //调用后缀的++,当前对象的value已经加1报警。但输出的是2
  cnt.print(); //输出值为3
  return 0;
}
  • 输入输出流
ostream & operator<<(ostream &  os, const ClassType &obj){ 
	os << 要输出的内容;//有时候不加const会出问题的!
  //用os,不写cout,因为有时候不是屏幕输出!
  //只进行最小限度格式化,由用户控制输出细节,不应输出换行符
	return os;
} 
istream & operator>>(istream & is, ClassType &obj){
//这里第二个形参千万不要加const
  is >> 要输入的内容;
  return is;
} 
  • 类型转换
    将单参数的构造函数定义为explicit,将告诉编译器不允许执行隐式转换。
operator 目标类型名 ( ) const 
      {return (结果为目标类型的表达式)}

8. 重载和重定义

重载的意思是:使参数个数不同、参数类型不同或两者兼而有之的两个以上的函数取相同的函数名;重定义是在子类里面重新写一个参数表都一模一样的函数

9. 友元:

为了访问私有成员而开的后门,有友元函数(一般函数)、友元成员(成员函数)、友元类;
声明在类内friend fun(参数表);,但具体定义在哪都行:friend 函数返回类型 类名标识符::函数名(参数列表); 注:参数表甚至可以不写类型后面的变量名,只写类型就ok

10. 成员函数put输出字符

cout.put('A');cout.put(65);都输出A;可以写cout.put('A'),put('\n');意思是可以重复写put语句,因为put的返回值是当前对象的引用。

11. write成员函数无格式输出

char buffer[]="HAPPY BIRTHDAY";cout.write(buffer,10);cout.write("ABCDEFGHIJKLMN",10);都是输出前十个字母的意思。

12. 输入流:

cin>>跳过开头的空白字符(space,tab,\n),开始读取,直到读到空白字符作为结束符,该结束符仍留在缓冲区里。
cin.get();读入一个字符,包括space和EOF,并将读入值作为函数返回值。
cin.get(a);读入一个字符,存储在参数a中,返回值是当前输入流对象的引用。
cin.get(ch,80,'\n');表示输入字符串,结束符默认为'\n'(可以不写),结束时自动插入一个'\0'到末尾。注意结束符仍在缓冲区中!
cin.getline(ch,80,'.');输入字符串,结束符不留在缓冲区中。

13. cin.read(buffer,10);

无格式输入。

14. 文件操作:

  • open

在这里插入图片描述 在这里插入图片描述

  • 文件的随机读写
    文件定位指针(long)类型,in.tellg();返回in的读文件定位指针;out.tellp();返回out的写文件定位指针。
    文件定位指针成员函数:in.seekg(10);是指in指针找到第10个位置,从第11个字节开始读;out.seekp(10);是指out指针找到第10个位置,开始在第11个字节上写东西进去,效果是覆盖原来的。
  • 流式文件处理含记录的文件

在这里插入图片描述

15. 函数模板

定义方法:

template<class T>
T max(T a,T b){
    return a>b ? a:b;
}

实例:

template <class T>
T power(T base, int exponent){
    T result=base;
    if (exponent==0) return (T)1;
    if (exponent<0)  return (T)0;
    while(--exponent) result*=base;
    return result;
}

注意:不允许自动进行类型转换,要是传进去两个数据类型不一样,就是编译错误。
在这里插入图片描述注:如果有对应类型的非模板函数,则优先调用非模板函数;没有才用模板函数。

16. 带const的指针

	`const int *p=&a;  int const *p=&a;`  p是指向const int的指针,意思是a不能变,但p可以变
	`int *const p=&a;`  p是const,意思是p始终指向a,但a可以变

17. static

  • 静态数据成员:对类中所有变量共用。
    静态数据成员不属于对象的一部分,而是类的一部分;静态数据成员的初始化不能放在类的构造函数中;类定义并不分配空间,空间是在定义对象时分配;但静态数据成员属于类,因此定义对象时并不为静态成员分配空间。类的实现时为静态数据成员赋值。
    可以通过作用域操作符从类直接调用。如:SavingAccount::rate 但从每个对象的角度来看,它似乎又是对象的一部分,因此又可以从对象引用它。如有个SavingAccount类的对象obj,则可以用:obj.rate
    由于是整个类共享的,因此不管用哪种调用方式,得到的值都是相同的
  • 静态成员函数:为类的全体对象服务,而不是为某个类的特殊对象服务
    由于静态成员函数不需要借助任何对象就可以被调用,所以编译器不会为它暗加一个this指针。因此,静态成员函数无法处理类中的非静态成员变量。//非静态函数可以操作静态成员
    静态成员函数的声明只需要在类定义中的函数原型前加上保留词static。
    类外定义static函数的时候只需要写类的名字::函数名即可,不需要加static。
  • 静态的常量数据成员:整个类的所有对象的共享常量
    静态的常量数据成员的声明:
    static const 类型 数据成员名 = 常量表达式;
    注意const数据成员和static const数据成员的区别 :const是每个变量一个,可以不同,static const必须都一样
  • 关于析构顺序做一个很完整很完整的总结:
#include <iostream>
using namespace std;
int a;
class A {
   public :
   A(int x){
      tmp = x;
      cout << "tmp : " << tmp << endl;
   }
   ~A(){
      cout << "tmp " << tmp << endl;
   }
   void f(){
   		A a7(7);
		static A a8(8);
		A a9(9);
   }
   private :
      int tmp;
};
A a1(1); // 全局变量;
static A a2(2);
A a3(3);
int main()
{
   A a4(4);//局部变量;
   static A a5(5);//静态局部变量;
   a5.f();
   static A a6(6);
   a6.f();
    return 0;
}

运行结果:

tmp : 1
tmp : 2
tmp : 3
tmp : 4
tmp : 5
tmp : 7
tmp : 8
tmp : 9
tmp 9
tmp 7
tmp : 6
tmp : 7
tmp : 9
tmp 9
tmp 7
tmp 4
tmp 6
tmp 8
tmp 5
tmp 3
tmp 2
tmp 1

说明:

  • 非main函数中,非静态的在函数结束时析构,顺序倒过来
  • main函数中的非静态析构,顺序倒过来
  • main函数倒着走,遇到静态就析构,遇到局部函数最后一次出现的时候到里面去析构掉里面的静态成员(倒着)
  • 局部变量全部析构完了,现在去析构全局和全局静态
  • 直接倒着走,全局变量不区分是否是静态

18. 关于初始化列表

19.有的时候,你的类是继承来的,用初始化列表调用基类的构造函数事半功倍
可以看看这篇文章,里面讲了不止两种情况,继承类也要用初始化列表

19.一些知识点

  • 析构函数只能有一个,不能重载
  • 字符串:实验验证,用char ch[]="abcd";的空间开了5个,加上了\0;char ch[] ={'a','b','c','d'};的空间开了4个,大概是没加\0;如果开多了又没全部定义,则后面都补0;
  • 整数补码表示
  • 指向结构体的指针声明时不开结构体空间的
  • 为什么我的文章还没有审核通过,我想考前在手机上看可不可以

20. 字符串与指针

  • 指针使用前必须初始化!!!!!!!不初始化不许用!!!!包括strcpy什么的,连空间都没指的话根本用不了!!如果你写char *p;p[2]='a';也是错的,因为根本没有指向的空间
  • 已经指向常量区字符串的指针不能用strcpy,因为strcpy是针对指针指向的地方进行修改,而常量区不可以修改!!!
  • 字符数组的数组名也是常量指针,不可以进行修改.如char ch[]="xyz";ch="abc";是不对的,因为没法修改常量指针的指向。

21.练习题里面扯皮拉筋的知识点

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值