CS100期末Review

CS100期末Revision

写在前面:这个文档是我在复习CS100期末考试的时候整理的,主要是对于自己一些不熟悉的知识点的整理,并非对于CS100知识点的全面复习。同时,本文可能会有一些错误,如果发现错误,欢迎指出。


1. 区分底层const和顶层const

  • 顶层const:指针本身是个常量, 指针所指的对象不是常量(指针不可以指向别的对象,但是可以改变所指对象的值)
  • 底层const:指针所指的对象是一个常量(指针可以指向别的对象,但是不可以改变所指对象的值)
    e.g.
    [1].const int* const p:第一个const是底层const,第二个是顶层const
    [2].const char& operator[](int index) const:第一个const是底层const,第二个const是加在this指针上的底层const,表示对象的所有成员都是常量,不可以被改变!!!

Remark: 为什么对一个类要定义[]运算符const和non-const两个版本的重载?
const对象只能调用const成员函数,而non-const对象可以调用const和non-const成员函数,所以为了让const对象也能调用[]运算符,就要定义const版本的[]运算符重载。如果a本身就带const,而fun不是const成员函数,那这个调用就是在试图去除底层const,这是不允许的。

2. C&C++中的运算符

  • / int/int 为向零取整
  • % 满足 (a / b) * b + a % b == a
  • ||&&短路求值:(short-circuited):先求左边,如果左边的结果能确定表达式的结果,就不再对右边求值。
  • , 先对左边求值,再对右边求值,返回右边的值
  • 运算符的优先级结合性不会决定求值顺序
    e.g:
    f() - g() + h() 中的 f()g()h() 的调用顺序是 unspecified 的。
    f() + g() * h() 中的 f()g()h() 的调用顺序是 unspecified 的。
    Remark: 只有&&, ||, ?:,,的求值顺序是确定的,其他的都是unspecified的。

3. 变量的声明和初始化

  • 空初始化

    对于全局 (global) 或者局部静态 (local static) 变量,不显式初始化的情况下执行空初始化
    对于局部非静态 (local non-static) 变量,不显式初始化的情况下将持有未定义的值:你不能对它的值作任何假定,使用未定义的值的行为是未定义的行为
    对于类内成员的默认初始化(调用默认构造函数)在未指定默认值时的值是未定义的值

4. 指针

  • 指针的值是一个地址,这个地址指向某个对象
  • p + i 得到的地址是 (void *)p + i * sizeof(Type),即和 p 相距 iType
  • 如果指针 p1p2 分别指向某一个数组的下标为 ij 的位置,则 p1 - p2
    • 结果是 i - j
    • 类型为 ptrdiff_t:一个定义在 <stddef.h> 里的类型,是一种带符号整数,其具体大小是 implementation-defined。

二维数组

  • 数组指针:int (*p)[10] 指向一个含有10个整数的数组
  • 指针数组:int *p[10] 含有10个指向整数的指针的数组
    Remark: 如何理解 二维数组int a[m][n]
  1. 一个指向int[n]的指针,即 int (*p)[n]
  2. 存放了 m 个数组的地址,每个数组有 nint,即 int *p[m]。(二维数组退化degrade为指向首元素int [m]的数组)

5. 字符串

  • 字符串字面值:类似这种 "abcde"双引号!!!
    • C:类型为 char [N+1],其中 N 是它的长度,+1 是为了放空字符。
    • C++:类型为 const char [N+1]
  • 'a'的字符串字面值类型
    • C:int
    • C++:char

<string.h>的函数

  • strcmp(s1, s2) 按字典序 (lexicographical order) 比较两个字符串的大小。
    • 如果 s1“小于”s2,返回一个负数
    • 如果相等,返回 0
    • 如果 s1“大于”s2,返回一个正数
    • 不可以认为它的返回值 $\in{-1,0,1}$!!!
  • strcpy(to, from)from 的内容拷贝给 to

<string>

  • 默认初始化一个 std::string 对象会得到空串,而非未定义的值!
  • 字符串的IO:
    • std::cin 会忽略开头的空白字符,直到遇到下一个空白字符为止。
    • getline(std::cin, s) 会读入一整行,包括开头的空白字符,直到遇到换行符为止。

6. Class

  • this 指针:指向当前对象的指针,是一个隐式参数,成员函数内部使用。
    • 特别的,static成员函数没有this指针,以class::static_func()调用。
  • 构造函数通常是重载(Overload)的,构造函数不声明返回值类型,可以含有 return; 但不能返回一个值,但不能认为它的返回值类型是 void
    • 重载匹配规则:最佳匹配(Best Match)

单例模式(Singleton

1
2
3
4
5
6
7
8
9
10
11
class Widget {
// 构造函数是 private 的
Widget();
public:
Widget(const Widget &) = delete;
Widget &operator=(const Widget &) = delete;
// Magic happens here!!
static Widget &get_instance() {
static Widget w;
}
};

继承和多态(Inheritance and Polymorphism

  • 父类的所有成员(除了构造函数和析构函数)都被继承下来,无论能否访问。(private成员也被继承下来,只是不能访问而已)
  • 向上转型:Base *p = &derived;(由派生类指针转换为基类指针)
  • 向下转型:dynamic_cast<Derived *>(p)(由基类指针转换为子类指针):如果不能成功,dynamic_cast<T*> 返回空指针,dynamic_cast<T&> 抛出 std::bad_cast 异常。

符号重载(Operator Overload

  • ++i 返回 i 的引用,i++ 返回递增前的 i 的一份拷贝。
    • ++iclass &operator++()
    • i++class operator++(int) 其中 int 是一个不被使用的形参,用于区分前置和后置。
  • 赋值、复合赋值都返回左侧运算对象的引用。
  • IO运算符:这两个运算符只能是非成员:你无法给 std::istreamstd:ostream 添加成员。
    • std::istream &operator>>(std::istream &, Rational &r);
    • std::ostream &operator<<(std::ostream &, const Rational &r);

7. 客观题知识点整理

  • Hw5:
    • Q4: &a返回lvalue,a[3],*a都是rvalue。
    • Q7: std::string s3(); 是函数声明,而非定义空字符串。
    • Q9: std::vector v;声明一个vector时必须指定元素类型,或者给出足够条件使得编译器能够推断出元素类型。
    • Q10: 永远不能去除底层const
    • Q12: sizeof()在编译时求值
    • Q14:int fun(std::vector<int>),int fun(std::vector<double>)构成重载。
  • Hw6:
    • Q7:对于一个类,value-initialization就是default-initialization,调用默认构造函数(大部分情况,在某些情况下会调用zero-initialization)。
    • Q8: int* ptr = nullptr; delete[] ptr; // 是合法的
    • Q10:const成员函数的const是加在this指针上,所以类内的int*指针会被视为int* const,而非const int*,可以修改指针指向的内容。
    • Q12:编译器执行析构函数时是在函数体之后销毁成员
    • Q14:Dynarray中在让m_storage指向新的内存之前,应该先释放原来的内存。(移动赋值和拷贝赋值)
    • Q18: unique_pointer只能移动,不能拷贝。
    • Q19:拷贝一个shared_ptr会增加引用计数,而不会拷贝指向的对象。

CS100期末Review
http://example.com/2023/05/14/CS100期末Review/
作者
KesonStar
发布于
2023年5月14日
许可协议