C++入门基础-2

简介: C++入门基础

C++入门基础-1

https://developer.aliyun.com/article/1504242


5.2 引用的作用

5.2.1 引用作为函数的参数

我们以下面这段代码为例:


我们知道在C语言中,我们必须传指针才可以交换两个变量之间的值,因为形参只是实参的拷贝!而在C++中,我们利用引用作为参数,作为实参的别名,指向的是同一块内存空间,所以就可以顺利的交换变量之间的值了!


5.2.2 引用作为函数的返回值

我们先来看这样一段代码

int& ADD(int x,int y)
{
  int tmp = x + y;
  return tmp;
}


int main()
{
  int& ret = ADD(1,2);
  cout << ret << endl;
  return 0;
}

你认为ret打印出来是多少呢?如果你认为是3,那么恭喜你,成功的答错了这道题!正确的答案其实应该是随机值:

注:对于函数开辟空间的问题,具体可以参考这篇文章:函数的栈帧

我们在看这段代码:

int& Count(int x,int y)
{
  static int n = x + y;
  return n;
}
int main()
{
  int& ret = Count(1, 2);
  cout << ret << endl;
  int& ret1 = Count(2, 3);
  cout << ret1 << endl;
  return 0;
}

你觉得ret和ret1打印出来各是多少呢?如果你以为是随机值!!!那么恭喜你又成功的答错了,因为此时的n是静态变量,它所在的位置不是位于函数中,而是在一个叫做静态区的位置,所以此时ret是一个确定的值,而由于对于变量,只可以初始化一次,所以ret1是等于ret的值的!!!

所以我们在使用引用作为返回值时,我们需要特别注意引用的地方内存是否会被清除!以下面这个例子为例,说明一下引用的用法,后续还会进一步的反复学习!!!

int& arraypos(SL* ps,int pos)
{
  return ps->a[pos];
}

int main()
{
  SL a;
  for (int i = 0; i < a.size; i++)
  {
    //让顺序表中的值都加1
    arraypos(&a, i)++;
  }
}

5.3 常引用

举几个例子来理解一下常引用:

接下来我们在理解一下这个代码:

这里需要说明一点的就是,当类型不一样时,是会发生类型转换的,而不管是强制类型转化还是隐性类型转化,其实都是会中途产生一个临时变量,而这个临时变量具有不可改变的性质也就是常性(也可以理解为是一个确定的数字,是一个常数),所以加了const才不会报错

图解:


4ebf00015e5b279e50fc80c03bf2082e_753946fd26894fe48f44280f1809a325.png


5.4 总结引用与指针的区别

1 指针是可以不初始化的,而引用必须初始化
2 引用是不可以更改实体的指向,而指针是可以的
3 引用是变量的别名,而指针是存储变量的地址
4 引用不可以为NULL,而指针可以为NULL
5 不存在多级引用,存在多级指针
6 引用自增是实体加1,而指针加1是偏移一个类型的大小
7 访问实体方式不同,引用编译器自己会进行处理,而指针需要显式的解引用
8 在sizeof中的含义不同,引用表示类型的大小,而指正是固定的4个字节(32位平台下)或8(64位平台下)个字节
9 总体而言,引用相比较于指针更加安全!

6 内联函数(inline关键字)

内联函数的概念:用inline关键字修饰的函数叫做内联函数,并且编译时会在调用内联函数的地方展开!这样就会没有函数栈帧的开销,提高了程序运行的效率!

6.1 配置

修改以下两个地方:


内联函数其实主要解决C语言中宏的缺点

我们可以先来看一段宏定义的代码:

宏的缺点:
1 宏是不方便进行调试的,因为在预编译阶段就进行了替换
2 代码的可读性比较差,难以理解
3 没有类型安全检查机制
优点:
1 可以不用开辟栈帧,提高代码的运行效率
2 增强代码的复用性


C++中就利用内联函数(兼容了宏的优点也克服了它的缺点)代替宏,常量定义用const enum来代替

7.2 内联函数的特性


1 inline对于C++编译器来说只是一个建议,适合于规模较小且使用频率高的函数,但不可以是递归!否则规模较大或者是递归,即使你使用了inline关键字去修饰函数,那么C++编译器会无视!!!

2 内联函数的定义和声明是不可以分开的!这是因为inline被展开,就会没有函数地址,这样链接的时候就找不到了!!!


7 auto关键字

可以自动识别类型,后续我们如果遇到很长的类型是,可以使用auto关键字,所以这就要求使用auto时,必须进行初始化!!!


我们从以上可以看出,使用auto关键字时,auto与auto*没有任何区别,并且引用类型必须要用&来声明!!!

1 auto不可以作为函数的参数

2 auto不能用来声明数组


8 nullptr关键字

我们先来看以下这段代码:

void func(int a)
{
  cout << "int a" << endl;
}

void func(int* a)
{
  cout << "int* a" << endl;
}

int main()
{
  //func(1)
  func(NULL);
  return 0;
}


你认为运行的结果是什么呢?其实答案是int a并不是int* a,为什么会这样呢?那是因为编译器默认情况下会将NULL认为字面常量为0,如果要成为指针空值,那么必须强制转化(void*)0。所以就会调用第一个func,所以在C++中就引入nullptr关键字作为指针空值


总结:

本篇文章主要学习了C++入门的一些基础知识,后续我们将继续深入的学习C++中的语法知识!

目录
相关文章
|
3月前
|
存储 安全 编译器
c++入门
c++作为面向对象的语言与c的简单区别:c语言作为面向过程的语言还是跟c++有很大的区别的,比如说一个简单的五子棋的实现对于c语言面向过程的设计思路是首先分析解决这个问题的步骤:(1)开始游戏(2)黑子先走(3)绘制画面(4)判断输赢(5)轮到白子(6)绘制画面(7)判断输赢(8)返回步骤(2) (9)输出最后结果。但对于c++就不一样了,在下五子棋的例子中,用面向对象的方法来解决的话,首先将整个五子棋游戏分为三个对象:(1)黑白双方,这两方的行为是一样的。(2)棋盘系统,负责绘制画面。
43 0
|
7月前
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
6月前
|
存储 分布式计算 编译器
C++入门基础2
本内容主要讲解C++中的引用、inline函数和nullptr。引用是变量的别名,与原变量共享内存,定义时需初始化且不可更改指向对象,适用于传参和返回值以提高效率;const引用可增强代码灵活性。Inline函数通过展开提高效率,但是否展开由编译器决定,不建议分离声明与定义。Nullptr用于指针赋空,取代C语言中的NULL。最后鼓励持续学习,精进技能,提升竞争力。
|
11月前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
121 2
C++入门12——详解多态1
|
11月前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
160 1
|
11月前
|
存储 C++ 容器
C++入门9——list的使用
C++入门9——list的使用
88 1
|
11月前
|
C语言 C++ 容器
C++入门7——string类的使用-1
C++入门7——string类的使用-1
78 0
|
11月前
|
程序员 C语言 C++
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
200 1
|
11月前
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
171 0
C++入门6——模板(泛型编程、函数模板、类模板)