4、C++ Primer 4th 笔记,基本语言相关的概念[3]

时间:2022-09-08 18:51:51

1case 标号必须是整形常量表达式。

对于switch结构,只能在它的最后一个case标号或default标号后面定义变量;制定这个规则主要是为了避免代码跳过变量的定义和初始化的情况。可以为某个特殊的case定义变量通过块语句。

2、异常类型[2]

    标准库异常类定义在四个头文件中:

1exception 头文件定义了最常见的异常类,它的类名是 exception。这个类只通知异常的产生,但不会提供更多的信息。

2stdexcept 头文件定义了几种常见的异常类,这些类型在表1中列出。

3new 头文件定义了 bad_alloc 异常类型,提供因无法分配内存而由 new抛出的异常。

4type_info 头文件定义了 bad_cast 异常类型。

1

exception

最常见的问题。

runtime_error

运行时错误:仅在运行时才能检测到问题

range_error

运行时错误:生成的结果超出了有意义的值域范围

overflow_error

运行时错误:计算上溢

underflow_error

运行时错误:计算下溢

logic_error

逻辑错误:可在运行前检测到问题

domain_error

逻辑错误:参数的结果值不存在

invalid_argument

逻辑错误:不合适的参数

length_error

逻辑错误:试图生成一个超出该类型最大长度的对象

out_of_range

逻辑错误:使用一个超出有效范围的值

 

3、使用预处理器进行调试

1)默认,NDEGUG未定义。

#ifndef NDEBUG

cerr << "starting main" << endl;

#endif

    预处理器还定义了其余四种在调试时非常有用的常量:

__FILE__ 文件名

__LINE__ 当前行号

__TIME__ 文件被编译的时间

__DATE__ 文件被编译的日期

__FUNCTION__ 函数名

2assert(expr) //cassert

只要NDEGUG未定义,assert就求解。

4、语法上块就是单语句。

5、函数不能返回另外一个函数或者内置数组类型,但可以返回指向函数的指针,或指向数组元素的指针的指针

6、可以将指向const对象的指针初始化为指向非const对象,反之不成立

应该将不需要修改的引用形参定义为const引用。普通的非const引用形参在使用时不太灵活;这样的形参既不能用const对象初始化,也不能用字面值或产生右值的表达式实参初始化。

如下示例

#include "iostream"
#include "string"
using namespace std;

string::size_type find_char(string &s, char c)
{
	string::size_type i = 0;
	while(i != s.size() && s[i] != c)
		++i;
	return i;
}

int main()
{
    if(find_char("hello world", 'o'))
		cout << "Yes";
	return 1;
}

应当把string &s写成const string &s

7、指向指针的引用

void ptrswap(int *&v1){}

8C++程序员倾向于通过传递指向容器中需要处理的元素的迭代器来传递容器。

示例

// pass iterators to the first and one past the last element to print
void print(vector<int>::const_iterator beg,
vector<int>::const_iterator end)
{
while (beg != end) {
cout << *beg++;
if (beg != end) cout << " "; // no space after last element
}
cout << endl;
}

9、数组的两个特殊性质:

一是不能复制数组;二是使用数组名字时,数组名会自动转化为指向其第一个元素的指针。

当编译器检查数组形参关联的实参时,它只会检查实参是不是指针、指针的类型和数组元素的类型时是否匹配,而不会检查数组的长度。

一般来说,非引用类型的形参会初始化为其相应实参的副本。

10、多维数组就是数组的数组。

11、传递给函数的数组的处理

1)在数组本身放置一个标记来检测数组的结束。C 风格字符串就是采用这种方法

的一个例子,它是一种字符数组,并且以空字符 null 作为结束的标记。处理 C

风格字符串的程序就是使用这个标记停止数组元素的处理。

2)第二种方法是传递指向数组第一个和最后一个元素的下一个位置的指针。如同前面的例子所示。

3)第三种方法是将第二个形参定义为表示数组的大小。

12、函数的返回值用于初始化在调用函数处创建的临时对象。在求解表达式时,

如果需要一个地方储存其运算结果,编译器会创建一个没有命名的对象,这就是

临时对象。

千万不要返回局部对象的引用或指针。

13、默认实参

如果有一个形参具有默认实参,则它后面所有的形参都必须有默认实参。默认实参只能用来替换函数调用缺少的尾部实参。在一个文件中,只能为一个形参指定默认实参一次。通常在函数声明中指定,并把该声明放在合适的头文件中。

如果在函数定义的形参表中提供默认实参,那么只有在包含该函数定义的源文件中调用该函数时,默认实参才是有效的。

14、作用域和生存期

名字的作用域指知道该名字的程序文本区。对象的生存期是在程序执行过程中对象生存的时间。

示例代码

size_t count_calls()
{
static size_t ctr = 0; // value will persist across calls
return ++ctr;
}
int main()
{
for (size_t i = 0; i != 10; ++i)
cout << count_calls() << endl;
return 0;

输出1,2,3...

15、重载

函数不能仅仅基于不同的返回类型而实现重载。

值得注意的是,形参与 const 形参的等价性仅适用于非引用形参。有 const 引用形参的函数与有非 const 引用形参的函数是不同的。类似地,如果函数带有

指向 const 类型的指针形参,则与带有指向相同类型的非 const 对象的指针形参的函数不相同。

在函数中局部声明的名字将屏蔽在全局作用域内声明的同名名字。这个关于变量名字的性质对于函数名同样成立。同样,作用域规则也适用于重载函数名。如果局部地声明一个函数,则该函数将屏蔽而不是重载在外层作用域中声明的同名函数。

同名查找发生在类型检查之前。

可基于函数的引用形参是指向 const 对象还是指向非 const 对象,实现函数重载。不能基于指针本身是否为const 来实现函数的重载。

16、常量成员函数不能修改所操作的对象的数据成员。

17、函数指针

1)在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指

针。假设有函数:

// compares lengths of two strings

bool lengthCompare(const string &, const string &);

    除了用作函数调用的左操作数以外,对 lengthCompare 的任何使用都被解

释为如下类型的指针:

bool (*)(const string &, const string &);

2)可使用函数名对函数指针做初始化或赋值。函数指针只能通过同类型的函数或函数指针或 0 值常量表达式进行初始化或赋值。将函数指针初始化为 0,表示该指针不指向任何函数。指向不同函数类型的指针之间不存在转换。

3)如下一下定义:

int (*ff(int))(int*, int);//ff声明为一个函数,它带有一个int型的形参。该函数返回int (*)(int*, int);

允许将形参定义为函数类型,但函数的返回类型则必须是指向函数的指针,不能是函数。

4)函数指针形参

按两种形式编写:

// third parameter is a function type and is automatically treated as a pointer to function
void useBigger(const string &, const string &,bool(const string &, const string &));
// equivalent declaration: explicitly define the parameter as a pointer to function
void useBigger(const string &, const string &,bool (*)(const string &, const string &));

5)指向重载函数的指针

指针的类型必须与重载函数的一个版本精确匹配。

extern void ff(vector<double>);
extern void ff(unsigned int);
// which function does pf1 refer to?
void (*pf1)(unsigned int) = &ff; // ff(unsigned)

18、静态局部对象和全局变量在程序开始执行时创建,main结束时撤消。默认初始化值为0,而其它局部变量则默认初始化未定义。

19this指针

    成员函数的隐式形参。this指针指向调用该函数的对象,是指向类类型的指针。在 const 成员函数中,该指针也指向 const 对象。

参考:

[1] http://blog.163.com/zhoumhan_0351/blog/static/3995422720104881216900/

[2] http://blog.163.com/zhoumhan_0351/blog/static/39954227201048103141504/