缺省和重载.引用——初识c++

news2024/11/26 2:29:38

在这里插入图片描述
在这里插入图片描述

.

个人主页:晓风飞
专栏:数据结构|Linux|C语言
路漫漫其修远兮,吾将上下而求索


文章目录

  • C++输入&输出
  • cout 和cin
    • <<
    • >>
  • 缺省参数
    • 全缺省
    • 半缺省
      • 应用场景
      • 声明和定义分离的情况
  • 函数重载
    • 1.参数的类型不同
    • 2.参数的个数不同
    • 3.参数的顺序不同(本质还是类型不同)
  • C++支持函数重载的原理--名字修饰(name Mangling)
    • Linux编译器的命名规则
  • 引用
    • 引用概念
    • 引用特性
    • 引用的作用
      • 1.作为参数(输出型参数)
      • 2. 做返回值(减少拷贝,提高效率)
      • 2.对象比较大,减少拷贝,提高效率
    • 指针和引用的区别
    • 指针和引用的区别:
    • 底层:
  • 内联函数


C++输入&输出

cout 和cin

在这里插入图片描述

<<

这里的c意思是console,把数据out到console(控制台)中去,而最后面的endl其实等价与\n,就是换行

在这里插入图片描述

>>

同样的道理cin,把数据in到console(控制台),也就是输入数据到控制台中。

在这里插入图片描述

1.使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
以及按命名空间使用方法使用std。
2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< 
iostream >头文件中。
3. <<是流插入运算符,>>是流提取运算符。
4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。
C++的输入输出可以自动识别变量类型。
5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,

缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

全缺省

#include<iostream>
using namespace::std;

void Func(int a = 10 , int b = 20 , int c =30)
{
  cout << "a:" << a << endl;
  cout << "b:" << b << endl;
  cout << "c:" << c << endl << endl;
}


int main()
{
// 没有传参时,使用参数的默认值
// 传参时,使用指定的实参
  Func(1,2,3);
  Func(1,2);
  Func(1);
  Func();
  return 0;
}

在这里插入图片描述

那么可不可以隔着一个数传参呢?答案是不能
在这里插入图片描述

半缺省

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现
#include<iostream>
using namespace::std;

//半缺省参数从右往左依次给出
//半缺省参数不是缺少一半,而是有缺少就是半缺省
void Func(int a , int b = 20 , int c =30)
{
  cout << "a:" << a << endl;
  cout << "b:" << b << endl;
  cout << "c:" << c << endl << endl;
}

int main()
{
  Func(1,2,3);
  Func(1,2);
  Func(1);

  return 0;
}

应用场景

假如我有一个栈,但是不知道要插入多少数据,目前栈的空间是固定的,怎么解决数据的容量问题?

struct stack
{
  int* a;
  int size;
  int capacity;
};

void stackInit(stack* ps)
{
  //容量固定
  ps->a = (int*)malloc(sizeof(int) * 4);
}

void StackPush(stack* ps,int x)
{
}

int main()
{
  //不知道要插入多少个数据
}

用半缺省参数就可以很好的解决这个问题
在这里插入图片描述

声明和定义分离的情况

在声明和定义分离的情况下,那么是在声明处缺省,还是在定义处缺省呢?

//stack.h头文件下的定义
void stackInit(struct stack* ps, int n = 4);

//stack.cpp下的声明
void stackInit(struct stack* ps, int n)
{
    ps->a = (int*)malloc(sizeof(int) * n);
}

应该在头文件下的定义处缺省,因为在运行时,要包含的是头文件,程序在编译的时候会展开头文件,这时候就可以进行缺省调用。而且在声明处还可以判断语法是否正确
如果在定义处缺省,那么在第3个情况下就会出现参数太少的报错情况,达不到缺省。

在这里插入图片描述

如果声名与定义位置同时出现缺省,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。出现重定义报错

在这里插入图片描述

函数重载

c语言不允许同名函数
c++可以,要求,函数名可以相同,但是参数不同,构成函数重载 ,并且会对数据类型自动匹配。

1.参数的类型不同

在这里插入图片描述

2.参数的个数不同

在这里插入图片描述

3.参数的顺序不同(本质还是类型不同)

在这里插入图片描述
c语言不支持重载,链接时,直接用函数名去找地址,有同名函数,区分不开。
那么C++是怎么支持的呢?

C++支持函数重载的原理–名字修饰(name Mangling)

函数名修饰规则,名字中引入参数类型,各个编译器自己实现了一套

Linux编译器的命名规则

因为Linux的规则比较简单,我们先理解一下Linux编译器的规则
在这里插入图片描述
在这里插入图片描述
解释:如果是Add这样的前面就是_Z3,f就是_Z1,后面就都是加上函数名字和数据类型的首字母

正是用类似这样的规则给函数修饰名字,只要参数不同,修饰出来的名字就不一样,就支持了重载。这样链接的时候用这样的名字,就可以找到对应的函数地址

引用

引用概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空
间,它和它引用的变量共用同一块内存空间。
比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。

int main()
{
  int a = 0;

  //引用,b就是a的别名
  int& b = a;

  cout << &a << endl;
  cout << &b << endl;
  return 0;
}

在这里插入图片描述
注意:引用类型必须和引用实体是同种类型的

引用特性

  1. 引用在定义时必须初始化
    在这里插入图片描述
  2. 一个变量可以有多个引用
    在这里插入图片描述
  3. 引用一旦引用一个实体,再不能引用其他实体
    在这里插入图片描述
    4.引用不能改变指向
    在这里插入图片描述

引用的作用

1.作为参数(输出型参数)

//指针传参
void Swap(int* a, int* b)
{
  int tmp;
  tmp = *a;
  *a = *b;
  *b = tmp;
}

//引用传参
void Swap(int &a , int &b)
{
  int tmp;
  tmp = a;
  a = b;
  b = tmp;
}

int main()
{
  int x = 0, y = 1;
  Swap(&x, &y);
  cout << "x=" << x << endl;
  cout << "y=" << y << endl;

  Swap(x, y);
  cout << "x=" << x << endl;
  cout << "y=" << y << endl;
}

这里a相当于x的别名,y相当于b

在这里插入图片描述

typedef struct Node
{
  struct Node* next;
  struct Node* prev;
}LNode,*Pnode;

void PushBack(Pnode& phead, int x);

void PushBack(struct LNode** phead, int x);
void PushBack(struct LNode*& phead, int x);

 
int main()
{
  Pnode plist = NULL;
  return 0;
}

这里*pnode 相当于struct Node*,Node相当于struct Node

2. 做返回值(减少拷贝,提高效率)

int& func()
{
  int a = 0;
  return a;
}

int main()
{
  int ret = func();
  return 0;
}

这段代码意味着返回a别名,但是由于栈帧销毁,会造成野引用,这里的值是不确定的,取决于编译器,以及是否清内存。
在这里插入图片描述
在这里插入图片描述

可以看到这里随便调用了一个函数就导致结果变化,因为fxfunc相同,空间重复使用,所以在原来销毁的a的位置创建了b,所以导致输出来的值又a的6,变成了b的1。

小结:

返回变量出了函数作用域,生命周期就到了要销毁(局部变量),不能引用返回

那么怎么使用引用返回呢?

int& func()
{
  static int a = 6;
  return a;
}

int main()
{
  int &ret = func();
  cout << ret << endl;
  return 0;
}

这里加上一个static就可以。


int& Add(int a, int b)
{
    int c = a + b;
    return c;
}
int main()
{
    int& ret = Add(1, 2);
    Add(3, 4);
    cout << "Add(1, 2) is :"<< ret <<endl;
    return 0;
}

在这里插入图片描述

#include<iostream>
using namespace std; 
#include<assert.h>

struct SeqList
{
  //成员变量
  int* a;
  int size;
  int cacpcity;

  //成员函数
  void Init()
  {
    a = (int*)malloc(sizeof(int) * 4);
    size = 0;
    cacpcity = 4;
  }

  void PushBack(int x)
  {
    //... 扩容
    a[size++] = x;
  }
  //临时变量有常性
  //读写返回变量
  int& Get(int pos)
  {
    assert(pos >= 0);
    assert(pos < size);

    return a[pos];
  }

};

int main()
{
  SeqList s;
  s.Init();
  s.PushBack(1);
  s.PushBack(2);
  s.PushBack(3);
  s.PushBack(4);

  for (int i = 0; i < s.size; i++)
  {
    cout << s.Get(i) << "";
  }
  cout << endl;

  for (int i = 0; i < s.size; i++)
  {
    if (s.Get(i) % 2 == 0)
    {
      s.Get(i) *= 2;
    }
  }
  cout << endl;
  for (int i = 0; i < s.size; i++)
  {
    cout << s.Get(i) << "";
  }
 }

2.对象比较大,减少拷贝,提高效率

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。这些效果指针也可以,但是引用效率更高

#include<iostream>
using namespace std;
#include <time.h>
struct A{ int a[10000]; };
void TestFunc1(A a){}
void TestFunc2(A& a){}
void main()
{
 A a;
 // 以值作为函数参数
 size_t begin1 = clock();
 for (size_t i = 0; i < 10000; ++i)
 TestFunc1(a);
 size_t end1 = clock();
 // 以引用作为函数参数
 size_t begin2 = clock();
 for (size_t i = 0; i < 10000; ++i)
 TestFunc2(a);
 size_t end2 = clock();
// 分别计算两个函数运行结束后的时间
 cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
 cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}

在这里插入图片描述

指针和引用的区别

在这里插入图片描述

指针和引用的区别:

1.引用是别名,不需要开空间
语法:
2.引用必须初始化,指针可以初始化也可以不初始化
3,引用不能改变指向,指针可以
4.引用相对更安全,没有空引用,但是有空指针,容易出现野指针,但是不容易出现野引用
5.

底层:

1.引用底层是用指针实现的
2.语法含义和底层实现是背离

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
    一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
    位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

从汇编层面上,没有引用,都是指针,引用编译后也转换成指针了。
在这里插入图片描述

内联函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1554446.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

速成软件书是神器还是焦虑?

一、背景 "速成软件书"通常是指那些宣称能帮助读者在短时间内掌握某种软件操作或编程技能的书籍。这类书籍往往以其高效、快捷的学习路径吸引读者&#xff0c;尤其适合有一定基础或者急需短期内提升特定技能的人群。 然而&#xff0c;“神器”之称则带有主观性和一…

Python:执行py命令,提示: Can‘t find a default Python.

1.Python运行环境罢工 今天&#xff0c;要运行一个前年用python编写的爬虫程序&#xff0c;先检测python运行环境是否正常&#xff1a; D:\Python38-32\works>c:\windows\py.exe Cant find a default Python. 再试&#xff1a; D:\Python38-32\works>py --list Installe…

电子版各大主流报纸查看方法

2024-03-22 更新到V1.1.01.修复科技日报下载后都是第1页的bug2.增加“中国旅游报”“中国文物报”两个报种3.设置自动保存勾选结果若干说明&#xff1a; 1.本工具是提供提供数字报阅读的报种的下载&#xff0c;一般来说只有能看&#xff0c;才有所谓的下载2.如果朋友们有什么好…

python3将exe 转支持库错误 AssertionError: None does not smell like code

exe -> pyc包(*.exe_extracted) 安装反编译工具 exe反编译工具&#xff1a;pyinstxtractor.py下载&#xff1a;https://sourceforge.net/projects/pyinstallerextractor/ python pyinstxtractor.py hello.exe包反编译 懒的写&#xff01;&#xff01;&#xff01; 这有详…

【项目技术介绍篇】若依开源项目RuoYi-Cloud后端技术介绍

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

Matlab|电动汽车充放电V2G模型

目录 1 主要内容 1.1 模型背景 1.2 目标函数 1.3 约束条件 2 部分代码 3 效果图 4 下载链接 1 主要内容 本程序主要建立电动汽车充放电V2G模型&#xff0c;采用粒子群算法&#xff0c;在保证电动汽车用户出行需求的前提下&#xff0c;为了使工作区域电动汽车尽可能多的消…

跳跃游戏-java

题目描述: 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 解题思想: …

【MySQL】事务日志

事务的隔离性由锁机制实现&#xff0c;事务的原子性、一致性和持久性由redo日志和undo日志实现。 一、redo日志 1.1、为什么需要redo日志 一方面&#xff0c;由于数据从内存写回磁盘需要一定的时间&#xff0c;假如在事务提交后&#xff0c;还没有写回磁盘&#xff0c;数据库…

中小型集群部署,Docker Swarm(集群)使用及部署应用介绍

1、Docker Swarm简介 说到集群&#xff0c;第一个想到的就是k8s&#xff0c;但docker官方也提供了集群和编排解决方案&#xff0c;它允许你将多个 Docker 主机连接在一起&#xff0c;形成一个“群集”&#xff08;Swarm&#xff09;&#xff0c;并可以在这个 Swarm 上运行和管…

unity3d for web

时光噶然 一晃好多年过去了&#xff08;干了5年的u3d游戏&#xff09;&#xff0c;记得最后一次使用的版本好像是 unity 2017。 那个是 unity3d for webgl 还需要装个插件。用起来很蛋疼。 最近做一个小项目 在选择是用 Layabox 还是 cocosCreate 的时候 我想起了老战友 Uni…

你管这破玩意叫网络

你是一台电脑&#xff0c;你的名字叫 A 很久很久之前&#xff0c;你不与任何其他电脑相连接&#xff0c;孤苦伶仃。 直到有一天&#xff0c;你希望与另一台电脑 B 建立通信&#xff0c;于是你们各开了一个网口&#xff0c;用一根网线连接了起来。 用一根网线连接起来怎么就能…

开始时间大于结束时间

1.dom中代码&#xff0c;监听所选日期值的变化&#xff0c;并把需要比较的时间字段作为参数传到监听方法中&#xff0c; <el-form-item label"起始日期" prop"startTime"><el-date-picker clearable size"small":disabled"isDisa…

如何使用Docker搭建WBO在线协作工具并实现无公网IP远程编辑本地白板

文章目录 前言1. 部署WBO白板2. 本地访问WBO白板3. Linux 安装cpolar4. 配置WBO公网访问地址5. 公网远程访问WBO白板6. 固定WBO白板公网地址 前言 WBO在线协作白板是一个自由和开源的在线协作白板&#xff0c;允许多个用户同时在一个虚拟的大型白板上画图。该白板对所有线上用…

写作类AI推荐(一)

本章要介绍的写作AI如下&#xff1a; paperpal 特点&#xff1a; 面向科研人员的AI写作工具。可以选择自己的专业&#xff0c;如本科生/教授。 链接&#xff1a;Paperpal-专业AI论文润色与论文检测平台 笔灵 特点&#xff1a; 面向专业写作领域的AI写作工具。可以选择要写的文章…

Apache Kafka + 矢量数据库 + LLM = 实时 GenAI

公众号&#xff1a;Halo咯咯 生成式人工智能 (GenAI) 支持先进的人工智能用例和创新&#xff0c;但也改变了企业架构的外观。大型语言模型 (LLM)、向量数据库和检索增强生成 (RAG) 需要新的数据集成模式和数据工程最佳实践。 Apache Kafka 和 Apache Flink 的数据流在大规模实时…

人体检测web应用

本文是一个深度学习模型web页面部署的一个demo&#xff1b;具体是利用yolox人体检测模型通过flask接口接收前端请求&#xff0c;利用简单的html页面展示检测结果。 文章目录 1、代码结构2、封装YOLOX检测类3、定义flask接口 代码地址&#xff1a; https://github.com/lishanl…

数字乡村战略实施:科技引领农村经济社会全面发展

随着信息技术的快速发展&#xff0c;数字化已经成为推动经济社会发展的重要力量。在乡村振兴战略的大背景下&#xff0c;数字乡村战略的实施成为了引领农村经济社会全面发展的关键。本文将从数字乡村战略的内涵、实施现状、面临挑战及未来展望等方面&#xff0c;探讨科技如何引…

快排(六大排序)

快速排序 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右子序列中所…

C语言例4-35:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一。百钱买百鸡、问鸡翁、鸡母和鸡雏各几何?

方法一&#xff1a; 代码如下&#xff1a; //鸡翁一&#xff0c;值钱五&#xff1b;鸡母一&#xff0c;值钱三&#xff1b;鸡雏三&#xff0c;值钱一。百钱买百鸡、问鸡翁、鸡母和鸡雏各几何&#xff1f; //方法一&#xff1a; #include<stdio.h> int main(void) {int x…

面向对象-接口

面向对象-接口 1. 接口的概念 ​ 接口就是规范\规则&#xff0c;我们可以使用接口来定义一些规则&#xff08;比如要求某个方法的方法名必须叫什么&#xff0c;方法的参数列表必须是什么&#xff0c;方法的返回值类型必须是什么&#xff09; ​ 现实生活中的规范 2. 接口的…