C++课程学习笔记第一周:从C到C++

前言:本文是根据MOOC网北大课程——《程序设计与算法(三):C++面向对象程序设计》内容整理归纳而来,整理的课程大纲详见 https://www.cnblogs.com/inchbyinch/p/12398921.html

本文介绍了从C到C++的基础过渡知识,包括引用、const和new关键字,以及函数。

1 引用

定义:类型名 & 引用名 = 某变量名。比如 int & r = n;

三点注意:

  • 定义引用时一定要将其初始化成引用某个变量。
  • 初始化后,它就一直引用该变量,不会再引用别的变量了。
  • 引用只能引用变量,不能引用常量和表达式。

定义引用时,前面加const关键字,即为“常引用”:const int & r = n;

  • r 的类型是 const int &,注意const T & 和T & 是不同的类型!!
  • T & 类型的引用或T类型的变量可以用来初始化 const T & 类型的引用。
  • const T 类型的常变量和const T & 类型的引用则不能用来初始化T &类型的引用(否则就可以通过T & 来改变引用对象了),除非进行强制类型转换。
//某个变量的引用,等价于这个变量,相当于该变量的一个别名。
//示例1
int n = 4;
int & r = n;  // r引用了n,r的类型是int &。此后,n就是r,r就是n
r = 4;
cout << r; //输出 4
cout << n; //输出 4
n = 5;
cout << r; // 输出5

//示例2
double a = 4, b = 5;
double & r1 = a;
double & r2 = r1; // r2也引用 a
r2 = 10;
cout << a << endl; // 输出 10
r1 = b;  // r1并没有引用b
cout << a << endl; //输出 5


//引用的作用一:作为函数形参
//C语言中利用指针交换两个数字,而C++中可以利用引用
void swap( int & a, int & b){
    int tmp;
    tmp = a; a = b; b = tmp;
}
int n1, n2;
swap(n1,n2) ; // n1,n2的值被交换


//引用的作用二:作为函数的返回值
int n = 4;
int & SetValue() { return n; }
int main(){
    SetValue() = 40;
    cout << n;  //输出 40
    return 0;
}   


//不能通过常引用去修改其引用的内容,但内容可以用其它方式改变
int n = 100;
const int & r = n;
r = 200; // 编译错
n = 300; // 没问题


//小测验:下面哪个选项正确?
A)  int n = 4;
    int & r = n * 5;
B)  int n = 6;
    const int & r = n;
    r = 7;
C) int n = 8;
    const int & r1 = n;
    int & r2 = r1;
D))  int n = 8;
    int & r1 = n;
    const int r2 = r1;

我的理解:

  • 引用和指针类似,但是多了一些限制条件。比如前者定义的时候就要用变量初始化;要从一而终;定义时候初始化,此后所有赋值都是普通赋值。

2 const关键字的用法

  • 定义常量;(多用const,少用define,便于类型检查)
  • 定义常量指针;
  • 定义常引用;
const int MAX_VAL = 23 ;
const string SCHOOL_NAME = "Peking University" ;

//不可通过常量指针修改其指向的内容,但内容可被其他方式改变,常量指针也可以指向其他地方
int n,m;
const int * p = & n;
* p = 5; // 编译出错
n = 4; //ok
p = &m; //ok

//不能把常量指针赋值给非常量指针,反过来可以
const int * p1; int * p2;
p1 = p2; //ok
p2 = p1; //error
p2 = (int * ) p1; //ok,强制类型转换

//函数参数为常量指针时,可避免函数内部不小心改变参数指针所指地方的内容
void MyPrintf( const char * p ){
    strcpy( p,"this"); // 编译出错,strcpy要求p为char * 类型
    printf("%s",p); //ok
}

3 用new 运算符实现动态内存分配

  • 第一种用法,分配一个变量;
  • 第二种用法,分配一个数组;
  • 用“new”动态分配的内存空间,一定要用“delete”运算符进行释放,delete 指针必须指向new出来的空间。
int * pn;
pn = new int; //动态分配大小为 sizeof(int)内存空间,并将该空间的起始地址赋值给pn
* pn = 5;
delete p;
delete p; //导致异常,一片空间不能被delete多次

int * pn;
int i = 5;
pn = new int[i * 20];
pn[0] = 20;
pn[100] = 30; //编译没问题。运行时导致数组越界
delete [] p;  //注意数组的释放方式

4 内联函数

  • 为了减少函数调用的开销,引入了内联函数机制。编译器处理对内联函数的调用语句时,是将整个函数的代码插入到调用语句处,而不会产生调用函数的语句。
  • 用法:只需要在函数前加个 inline 关键字即可。

5 函数重载

  • 一个或多个函数,名字相同,然而参数个数或参数类型不相同,这叫做函数的重载。(注意:若只有返回值不同,则错误)
  • 编译器根据调用语句的中的实参的个数和类型判断应该调用哪个函数。
  • 函数重载使得函数命名变得简单。

6 函数缺省参数

  • C++中,定义函数的时候可以让最右边的连续若干个参数有缺省值,那么调用函数的时候,若相应位置不写参数,参数就是缺省值。(只能最右边的连续若干个参数缺省,右边有参数但中间缺省则出错)
  • 目的是为了增强可扩展性。
posted @ 2020-01-05 20:13  天地辽阔  阅读(429)  评论(0编辑  收藏  举报