当前位置: 首页 > news >正文

初始c++:入门基础(完结)

打字不易,留个赞再走吧~~~

目录

  • 一函数重载
  • 二引用
  • 1 引⽤的概念和定义
  • 2引⽤的特性
  • 3引⽤的使⽤
  • 三inline
  • 四nullptr

一函数重载

C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者
类型不同。这样C++函数调⽤就表现出了多态⾏为,使⽤更灵活。C语⾔是不⽀持同⼀作⽤域中出现同
名函数的。

下面三种情况
1、参数类型不同
2、参数个数不同
3、参数类型顺序不同
这些条件都可以作为函数重载的条件,不影响结果,而且输入的参数还可以自动识别类型。

#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}

有两种情况不能进行函数重载
1 返回值不同不能作为重载条件,因为调⽤时也⽆法区分
2缺省参数和无参的函数不能 同时定义

// 下⾯两个函数构成重载
// f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
void f1()
{
cout << "f()" << endl;
}
void f1(int a = 10)
{
cout << "f(int a)" << endl;
}
int main()
{
Add(10, 20);
Add(10.1, 20.2);
f();
f(10);
f(10, 'a');
f('a', 10);
return 0;
}

二引用

1 引⽤的概念和定义

引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间,
它和它引⽤的变量共⽤同⼀块内存空间。

具体表示为:类型& 引⽤别名 = 引⽤对象;

C++中为了避免引⼊太多的运算符,会复⽤C语⾔的⼀些符号,⽐如前⾯的<< 和 >>,这⾥引⽤也和取
地址使⽤了同⼀个符号&,⼤家注意使⽤⽅法⻆度区分就可以。

#include<iostream>
using namespace std;
int main()
{
int a = 0;
// 引⽤:b和c是a的别名
int& b = a;
int& c = a;
// 也可以给别名b取别名,d相当于还是a的别名
int& d = b;
++d;
// 这⾥取地址我们看到是⼀样的
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
return 0;
}

在这里插入图片描述

这里看到他们的空间都是一块地方有就是全部a,b,c,d都指向一块空间
在这里插入图片描述

2引⽤的特性

引用有三个特性

• 引⽤在定义时必须初始化
• ⼀个变量可以有多个引⽤
• 引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体

引⽤在定义时必须初始化

在指针定义时候我们可以int *p;
然后给p赋值。
但是在引用我们必须给引用的值给予一个被引用对象
即int &a=b
给b取别名为a,他们指向同一块空间

⼀个变量可以有多个引⽤

当然我们可以给b取多个别名,即引用
int &a=b;
int &c=b;
int &d=b;

引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体

我们上面吧b引用给a了
那么a就不能引用其他值了

3引⽤的使⽤

•引⽤在实践中主要是于引⽤传参和引⽤做返回值中减少拷⻉提⾼效率和改变引⽤对象时同时改变被
引⽤对象。
• 引⽤传参跟指针传参功能是类似的,引⽤传参相对更⽅便⼀些。
• 引⽤返回值的场景相对⽐较复杂,我们在这⾥简单讲了⼀下场景,还有⼀些内容后续类和对象章节
中会继续深⼊讲解。
• 引⽤和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引⽤跟其他
语⾔的引⽤(如Java)是有很⼤的区别的,除了⽤法,最⼤的点,C++引⽤定义后不能改变指向,
Java的引⽤可以改变指向。
• ⼀些主要⽤C代码实现版本数据结构教材中,使⽤C++引⽤替代指针传参,⽬的是简化程序,避开
复杂的指针,但是很多同学没学过引⽤,导致⼀头雾⽔。

例如下面的代码我们要写swap函数,我们用指针也能完成,但是我们把实参写成引用的形式,看似形参能改变实参了,其实是其引用的值改变实参的。而且这样跟指针相比少开辟了空间,减少了消耗。

void Swap(int& rx, int& ry)
{
int tmp = rx;
rx = ry;
ry = tmp;
}
int main()
{
int x = 0, y = 1;
cout << x <<" " << y << endl;
Swap(x, y);
cout << x << " " << y << endl;
return 0;
}

三inline

⽤inline修饰的函数叫做内联函数,编译时C++编译器会在调⽤的地⽅展开内联函数,这样调⽤内联
函数就不需要建⽴栈帧了,就可以提⾼效率。
• inline对于编译器⽽⾔只是⼀个建议,也就是说,你加了inline编译器也可以选择在调⽤的地⽅不展
开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适⽤于频繁
调⽤的短⼩函数,对于递归函数,代码相对多⼀些的函数,加上inline也会被编译器忽略。

在定义函数返回值前我们加上inline的函数被称为内联函数,我们可以理解为在代码执行的时候会生成.exe可执行文件,里面有着我们写的指令,如果是内联函数我们在函数调调用时候会展开函数具体方法,不用使用函数开辟的栈帧。

但是如果函数语句过多,比如是个循环或者是递归语句,我们每次展开的空间过大,编译器会自动不展开,开辟函数栈帧,然后调用。

默认编译器在debug版本是不会展开的,要在编译器设置,而且就算设置了,语句过长,也会不展开,算是编译器的保护机制,防止程序员写出代码不好,占用空间太大。

四nullptr

NULL实际是⼀个宏,在传统的C头⽂件(stddef.h)中,可以看到如下代码:

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

• C++中NULL可能被定义为字⾯常量0,或者C中被定义为⽆类型指针(void*)的常量。不论采取何种
定义,在使⽤空值的指针时,都不可避免的会遇到⼀些⿇烦,本想通过f(NULL)调⽤指针版本的
f(int*)函数,但是由于NULL被定义成0,调⽤了f(int x),因此与程序的初衷相悖。f((void*)NULL);
调⽤会报错。

可以看出在c++中null就是0,c语言中则是强制转换为void* 的0.

#include<iostream>
using namespace std;
void f(int x)
{
cout << "f(int x)" << endl;
}
void f(int* ptr)
{
cout << "f(int* ptr)" << endl;
}
int main()
{
f(0);f(NULL);
f((int*)NULL);f(nullptr);return 0;
}

在这里插入图片描述

可以看出如果引入nullptr,它不仅可以起到空指针的效果,它还可以自动识别类型,不然每次根据函数方法强转很麻烦。

• C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换
成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被
隐式地转换为指针类型,⽽不能被转换为整数类型。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Mac】系统环境配置
  • 【算法】栈与模拟
  • Vue.js 与后端配合:打造强大的现代 Web 应用
  • 视频格式转为mp4(使用ffmpeg)
  • PCIe扫盲(10)
  • 【vue3】vue3.5
  • Linux vi常用命令
  • Android Tools | 如何使用Draw.io助力Android开发:从UI设计到流程优化
  • 前端项目代码开发规范及工具配置
  • Leetcode 416. 分割等和子集(Medium)
  • 鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
  • 人工智能安全治理新篇章:《2024人工智能安全治理框架1.0版》深度解读@附20页PDF文件下载
  • MATLAB统计和机器学习工具箱:数据分析与建模的利器
  • PyQGIS开发 2 Qt开发入门
  • Dirsearch在linux安装与运行
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • Angularjs之国际化
  • Elasticsearch 参考指南(升级前重新索引)
  • HTTP--网络协议分层,http历史(二)
  • input的行数自动增减
  • log4j2输出到kafka
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • python_bomb----数据类型总结
  • Python学习笔记 字符串拼接
  • SAP云平台里Global Account和Sub Account的关系
  • Vue.js源码(2):初探List Rendering
  • 后端_ThinkPHP5
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 简析gRPC client 连接管理
  • 如何利用MongoDB打造TOP榜小程序
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 跳前端坑前,先看看这个!!
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 我看到的前端
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 云大使推广中的常见热门问题
  • AI算硅基生命吗,为什么?
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • Mac 上flink的安装与启动
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • 数据库巡检项
  • ‌移动管家手机智能控制汽车系统
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • (30)数组元素和与数字和的绝对差
  • (Java)【深基9.例1】选举学生会
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (附源码)php新闻发布平台 毕业设计 141646
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (四)模仿学习-完成后台管理页面查询
  • (译)计算距离、方位和更多经纬度之间的点
  • (转)平衡树
  • *p++,*(p++),*++p,(*p)++区别?