必看!C++入门第三讲(最后一讲)


前言

本篇,我们将对C++的入门知识做一个收尾。讲解的知识点有:1.const引用 2.inline内联函数 3.nullptr指针4.函数重载


提示:以下是本篇文章正文内容,下面案例可供参考

一、const引用

在我们之前的学习过程中,const一般用来修饰那些无法被改变的常量,但是一些我们不想被改变的变量也可以用const修饰,所以,这也就涉及到了权限的缩小。

我们举几个例子,方便大家理解

1.权限的缩小

int main()
{
   int x = 5;
   const int&r1 = x;
   return 0;
}

从上面,我们可以看出,r1是x的别名,但是r1被const修饰了,也就是说r1无法被修改。x的改变影响不到r1的改变。可以把r1看成是x一个有限制的别名。

2.权限的平移

int main()
{
   int x = 5;
   int & x2 = x;
   ///////
   const int a = 5;
   const int &b = a;
   return 0;
}

从上面的代码我们可以看出,x是int型,x2是x的int型别名,所以它们两个的权限应当是相同的;同样的例子再看下面,a是const int型,b是a的别名,也是const int 型,都是无法被修改,所以它们两个也是权限的平移

3.权限能不能放大?

int main()
{
    const int a = 5;
    int & b = a;
    return 0;
}

那么,这里的代码涉及到权限的放大,具体是const int–>int。那么,这样的代码是不正确的,因为原先我们的a被const修饰,相当于无法被修改,而现在b是a的别名,况且b还是int型可以被修改的,这不就相当于放大了a的权限了吗?使得a可以被修改,这就违背了规律。

假设你就是一个普通的员工,你也干不了总经理的活啊,你说对吧?

4.一些零碎的例子

1.在我们的类型转换当中,中途是会产生临时变量的,上一章节我们就见过临时变量具有常性,无法被修改。

int main()
{
   double d = 1.1;
   int r5 = d;
   const int & x = d;
   return 0;
}

在这里插入图片描述
2.另一些例子
10是常量,无法被修改,所以我们也可以用const 来修饰

int main()
{
   const int & x = 10;
}

像“x * 10”这样是表达式,其计算后的结果也是存在于临时对象中,具有常性,也无法被修改

int main()
{
   const int & x = x*10;
}

二、inline内联函数

inline内联函数是C++祖师爷发现了C语言中的宏存在一些不足之处,而推出的又一个关键字,用来代替宏。其优点是:无需建立函数栈帧,从而提高效率。

1.宏

我们先来看几段代码,感受一下C语言中的宏的一些不足之处。

例如我们想求两个数字相加,代码如下(示例):

#define ADD(a,b) a + b
int main()
{
   int ret = ADD(1,2);
   cout << ret << endl;
   return 0;
}

宏在预处理阶段会进行替换,例如上代码,在预处理阶段ADD(1,2)就会被替换成1 + 2,所以ret的值就为3。

那要是我们想求两个数相乘呢?是不是简单的#define multiply(a,b) a*b呢?
那么接下来,请跟着我的脚步

#define multiply(a,b) a*b
int main()
{
    int ret1 = multiply(1,5);
    cout << ret1 << endl;
    int ret2 = multiply(1+5,1+5);
    cout << ret2 << endl;
    return 0;
}

解析:在ret1中multiply(1,5)被替换成了 1乘以5,也就是ret1等于5;在ret2中multiply(1+5,1+5)被替换成了1+5乘以1+5,我们都知道,乘法的优先级比加法高,就会先算5乘以5,那么就会跟我们想要的结果有出入,所以宏需要修改为#define multiply(a,b) (a)*(b)。

总结:
宏有优点以及也有缺点,优点可以不用建立函数栈帧,本质就是替换,是一种提效;缺点及时复杂,容易出错。

2.inline内联函数

相比C语言中的宏,inline关键字就不会出现像宏需要严谨的定义了。

我们都知道,调用一个函数需要建立相应的函数栈帧,那么要是不建立栈帧,是不是程序运行的效率就会增加,所以inline就是干这个活的,它会让函数直接展开,这样调用内联函数就无需展开了,就可以提升效率。

代码示例如下:

inline ADD(int x,int y)
{
   return x + y;
}
int main()
{
   int ret = ADD(1,2);
   cout << ret << endl;
   return 0;
}

所以inline使用方法就是直接在函数前面加inline关键字即可。
还有几个小知识点,需要大家注意一下:

  1. inline对于编译器只是一个建议而言,也就是说,你加了inline编译器野可以选择在调用的地方不展开。所以inline只适用于频繁调用的短小函数,对于递归函数,代码相对多一点的函数,加上inline也会被编译器忽略
  2. C语言中的宏很容易出错,所以C++中的inline就是来代替宏的
  3. inline不建议声明的定义分离到两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时就会报错。所以inline需要声明的定义分开,也就是说一个文件写上inline,其余则不需要。

三、nullptr

这方面的知识点比较简单,大家记住就行了
大家先看传统的空指针NULL的定义

#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void*)0)
    #endif
#endif
void f(int x)
{
   cout << "f(int x)"<<endl;
}
void f(int * ptr)
{
   cout<< "f(int * ptr)"<<endl;
}
int main()
{
   f(NULL);
   return 0;
}

可以看出NULL在c++中被定义为字面常量0,或者C中被定义为无类型指针(void *)的常量,在使用空值的指针时,都不可避免的会遇到一些麻烦,本想通过f(NULL)调用指针版本的f(int *)但是由于NULL被定义成了0,所以调用了f(int x),因此与程序的初衷相悖。

所以在C++中引入了nullptr,它就解决了类型转换的问题,因为nulllptr只能被隐式地转换为指针类型,而不能转换成整数类型,这就解决了原先的空指针NULL在c++中被转换成整型0的问题了。

四、函数重载(重点)

函数重载就是可以允许有两个函数名是相同的,它们调用的类型或者顺序或者数量得是不同的,才知道是调用哪一个函数

举个例子,你很快就能明白,例如我们重载Swap交换函数,利用它实现交换整型也可以交换浮点型

void Swap(int *x,int *y)
{
   int tmp = *x;
   *x = *y
   *y = tmp;
}
void Swap(double * x,double *y)
{
    double tmp = *x;
    *x = *y;
    *y = tmp;
}
int main()
{
    int a = 5,b = 6;
    double x = 5.5,y = 6.6;
    Swap(a,b);
    Swap(x,y);
    return 0;
}

以上的代码实现了对ab整型的交换以及xy浮点型的交换,怎么区分它们调用了不同的Swap函数呢,靠的就是传参的不同,上面传的为整型变量,下面传的是浮点型变量,编译器就会分辨出究竟调用哪一个Swap函数。

所以,函数重载需要函数可以是传递的参数类型不同,也可以是顺序不同,也可以是数量不同。总之,就是要让编译器区分你要调用的是哪一类的Swap函数。

总结

这里对文章进行总结:
以上就是今天要讲的内容,本文介绍了const在引用的使用,inline内联函数,nullptr关键字以及函数重载,自此从,C++入门到这里就告一段落了,还有更困难的类和对象在等待着我们。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值