(一)C++学习 | 基础知识


1. 引用

引用 C {\rm C++} 相对于 C {\rm C} 增加的新概念。首先,在 C {\rm C++} 中,引用的格式为类型名& 引用名 = 某变量名。如int& r = a;,则定义了一个指向变量a的引用rr的类型是int&。首先来看一下 C {\rm C} C {\rm C++} 中交换函数 s w a p {\rm swap} 的书写:

// C
void swap(int* a, int* b){
	int temp;
	temp = *a; *a = *b; *b = temp;
}	
// C调用,这里&不是引用,而是取地址符号
swap(&m, &n);
// C++,这里&表示引用
void swap(int& a, int& b){
	int temp;
	temp = a; a = b; b = temp;
}
// C++调用
swap(m, n);

观察上面,有了引用的概念后, s w a p {\rm swap} 函数的实现和调用变得更加简洁。注意,某个变量的应用,就等价于该变量,相当于该变量的一个别名。如果变量名所指向的值改变时,引用名对应的值也会改变。如:

int m = 5;		
int& n = m;			// 定义n为变量m的应用
n = 6;
cout << n << "";    // 输出6
cout << m << "";	// 输出6
m = 7;
cout << n << "";	// 输出7

关于引用需要注意的几点:
(1)定义引用时要将初始化成引用某个变量;
(2)一旦初始化后,只会一直引用该变量,不会再引用其他变量;
(3)引用只能引用变量,不能引用常量和表达式。


2. const关键字

C {\rm C++} 中, c o n s t {\rm const} 关键字用于定义一个常量。如const int MAX = 100;则定义了一个 i n t {\rm int} 型的常量 M A X {\rm MAX} ,其值为 100 {\rm 100} 。在 C {\rm C} 语言中定义常量使用 d e f i n e {\rm define} 关键字,如#define MAX 100。相比较而言, c o n s t {\rm const} 关键字定义常量时有类型检查。此外,还可以利用关键字 c o n s t {\rm const} 定义常量指针,如const int* p = &n;其中 n {\rm n} 都是整型变量。对于常量指针,需要注意几点:
(1)不可通过常量指针修改其指向的内容;
(2)不能把常量指针赋值给非常量指针(可以通过强制类型转换),反之可以;
(3)函数参数为常量指针时,可避免函数内部对参数指针所指内容的修改。如:

int m, n;
const int* p = &n; // p是一个常量指针,指向n
*p = 5;			   // 编译出错,不能通过常量指针修改其指向的内容
n = 6;			   // 正确,可以通过变量本身修改其内容
p = &m;			   // 正确,常量指针的指向可以改变
const int* p; int* q;
p = q;			// 正确
q = p;			// 出错
q = (int*) p;	// 通过强制类型转换将常量指针赋值给非常量指针
void func(const char* p){
	strcpy(p, "hello");	// 出错,企图修改常量指针所指内容
	printf("%s", p);	// 正确,打印函数不修改p
}

综合引用和 c o n s t {\rm const} 关键字可以定义常引用,其形式为const int& p = q;。则常引用的性质为不能通过常引用修改其引用的内容,但可以通过变量本身修改其内容,且 p {\rm p} 的值随着 q {\rm q} 的改变而改变。注意,const T&T&为不同类型,后者可以初始化后者,反之不行(除非进行强制类型转换)。


3. 动态内存分配

在程序运行过程中,有时候需要进行动态内存分配。在 C {\rm C} 语言中动态内存分配采用关键字 m a l l o c {\rm malloc} ,其形式为int *p = (int *)malloc(sizeof(int));,则为 p {\rm p} 申请一个 i n t {\rm int} 型变量大小的空间。在 C {\rm C++} 中使用 n e w {\rm new} 关键字完成动态内存分配。其具有两种基本用法:
第一,分配一个变量。如P = new T;,完成的功能是动态分配出一片大小为 s i z e o f ( i n t ) {\rm sizeof(int)} 的内存空间,并且将该内存空间的起始地址赋值给 P {\rm P}
第二,分配一个数组。如P = new T[N];,完成的功能是动态分配出一片大小为 N s i z e o f ( i n t ) {\rm N*sizeof(int)} 的内存空间,并将该内存空间的起始地址赋值给 P {\rm P}
C {\rm C++} 中使用 n e w {\rm new} 关键字动态分配内存空间,在程序结束前,需要将不用的内存空间释放掉,这里使用关键字 d e l e t e {\rm delete} 。其形式为delete 指针;,这里的指针必须指向 n e w {\rm new} 关键字分配的控件。关于 d e l e t e {\rm delete} 关键字需要注意几点:
(1)不能delete多次;
(2)delete数组时候,加上 [] ,否则只能释放一个位置,没有释放的空间在程序运行期间就浪费了。如:

int *p = new int;		// 动态分配一个变量
*p = 5;
delete p;				// 成功
delete p;				// 错误,不能delete多次
int m = new int
int* p = new int[10];   // 动态分配一个数组
p[0] = 5;				
delete p;				// 没有完全释放分配的内存空间
delete []p;				// 正确释放所有分配的内存空间

4. 内联函数

  • 函数调用有额外开销:调用函数时首先将参数放入栈中,函数的返回值也要放入栈中。执行完函数后,再从栈内取返回值。如果函数本身只有几条语句,而且被反复调用多次。相比之下函数调用所产生的额外开销就比较大。
  • 为了减少函数调用的开销,引入了内联函数机制。编译器在处理内联函数的调用语句时,不同于普通函数的调用,而是将整个函数的代码插入到调用语句处。即内联函数调用时不会产生上述栈的操作。
  • C {\rm C++} 中使用 i n l i n e {\rm inline} 关键字定义内联函数。
  • 为了保证效率,内联函数通常只有几行代码。如:
inline int max(int a, int b){
	if(a > b){
		return a;
	}
	return b;
}

在调用上述 m a x {\rm max} 函数时如c = max(m, n);,其大致流程为:

if(m >n){
	temp = m;	    // 使用临时变量temp存储较大值
}else{
	temp = n;
}
c = temp;			// 将临时变量值赋值给结果

5. 函数重载

定义:在 C {\rm C++} 中,一个或多个函数,名字相同、而参数个数或参数类型不同。而在 C {\rm C} 语言中不允许使用函数名相同的函数。例如下面为函数重载的三种形式:

  • i n t   M a x ( i n t   a , i n t   b ) { } {\rm int\ Max(int\ a, int\ b)\{\}}
  • i n t   M a x ( d o u b l e   a , d o u b l e   b ) { } {\rm int\ Max(double\ a, double\ b)\{\}}
  • i n t   M a x ( i n t   a , i n t   b , i n t   c ) { } {\rm int\ Max(int\ a, int\ b, int\ c)\{\}}

函数重载使函数命名变得简单,编译器根据调用语句中实参个数参数类型自动判断应该调的函数。调用实例:

Max(5, 6);			// 调用上述第1个函数
Max(5.1, 6.1);		// 调用上述第2个函数
Max(5, 6, 7);		// 调用上述第3个函数
Max(5, 6.1);		// 出错,出现二义性

:不以两个函数的返回值类型判断是否为重载函数。


6. 函数的缺省参数

C {\rm C++} 中,定义函数时可以让最右边的连续若干个参数有缺省值。在函数调用时,若相应位置不指定参数,则就会使用缺省值。如由函数定义为void fun(int a, int b=6, int c= 7){},则在以下函数调用的例子中:

func(5);			// 等价于func(5, 6, 7);
func(5, 8);			// 等价于func(5, 8, 7);
func(5, ,8);		// 出错,只能最右边连续若干个参数有缺省值

函数的缺省参数的作用是可以使函数既可以执行默认的参数值,也可以执行用户指定的参数值。


参考

  1. 北京大学公开课:程序设计与算法(三)C++面向对象程序设计.


猜你喜欢

转载自blog.csdn.net/Skies_/article/details/105151246