【C++】C++入门(下)

news/2024/4/26 3:54:46/文章来源:https://blog.csdn.net/qq_47658735/article/details/129207714

引用

  1. 什么是引用?
      引用是给一个已经存在的变量取一个别名,在语法上并不会给这个别名开一个空间,它和她引用的变量共用一个空间。但是实际上引用也是开了一块空间的,用来存放引用名。引用是按照指针的方式来实现的。
  2. 引用语法:
      类型& 引用变量名(对象名/别称) = 引用实体;注意引用类型必须和被引用类型相同。
int main()
{int a = 10;int& b = a;printf("%p\n", &a);printf("%p\n", &b);return 0;
}

在这里插入图片描述

  1. 引用特性:
      引用在定义时必须初始化,引用必然是有被引用对象的,不可能说先取个别名,但是不知道这个别名是谁;
      一个变量可以有多个引用,相当于一个人可以有很多个外号一样;
      引用一旦引用一个实体,就不能再引用其他实体了。
int main()
{int a = 10;//int& b;这个会直接报错int& c = a;int& d = a;int e = 20;c = e;printf("%p\n%p\n%p\n%p\n", &a, &c, &d, &e);return 0;
}

在这里插入图片描述

  如果被引用对象是一个常数,则需要添加const修饰。

int main()
{const int a = 10;const int& b = a;const int& c = 20;return 0;
}
  1. 使用场景:
      做参数
void swap(int* a, int* b)
{int x = *a;*a = *b;*b = x;
}
void swap(int& a, int& b)
{int x = a;a = b;b = x;
}
int main()
{int a = 1;int b = 2;swap(&a, &b);cout << a << " " << b << endl;swap(a, b);cout << a << " " << b << endl;return 0;
}

在这里插入图片描述

  做返回值,可以减少拷贝;调用者可以修改返回值。
  需要提前知道一个点,一个函数的返回值实际上是这个值的拷贝,而不是这个值本身。
  如果函数返回时,出了函数作用域,如果返回对象还没有还给系统,则可以使用引用返回,如果已经还给系统了,则不能使用引用返回,如果使用结果是返回值是未定义的。

int& Count()
{static int n = 0;n++;return n;
}
int main()
{int ret = Count();return 0;
}

在这里插入图片描述

  1. 权限问题:
      指针和引用可以进行权限平移和缩小,但是不能进行权限放大。
int main()
{int a = 1;const int b = 2;//权限平移int& ra = a;const int& rb = b;//权限缩小const int& c = a;//权限放大int& d = b;return 0;
}

在这里插入图片描述

  1. 与指针的区别
      引用在概念上是一个变量的别名,指针存储一个变量地址;
      引用必须初始化,指针没有规定;
      引用在初始化后就不能改变了,指针可以在任何时候改变指向;
      在sizeof中含义不同,引用的结果是引用类型的大小,但是指针始终是地址空间所占用的字节个数;
      引用自加是被引用的实体加一,指针自加是指针向后偏移一个类型的大小;
      指针可以有多级,但引用没有;
      访问实体时,指针需要显式的解引用,引用是编译器自己处理;
      引用比指针更加安全。

内联函数:

概念:
  用inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,这样就没有 函数调用建立栈帧的开销,内联函数可以提升程序运行的效率。

int Add(int left, int right)
{return left + right;
}
inline int Sub(int left, int right)
{return left - right;
}
int main()
{int ret = 0;ret = Add(1, 2);int tmp = 0;tmp = Sub(4, 3);return 0;
}

  有call说明进行了跳转,是开辟了栈帧空间的。
在这里插入图片描述

  我们默认的调试模式是在Debug模式,Debug是不会进行代码优化的,如果我们想要看到内联函数的展开就需要修改一些配置。Release又对代码优化的太厉害了,我们不太容易看懂。
在这里插入图片描述

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

特性:
  内联函数是一种空间换时间的做法,如果编译器将函数当做内联函数处理,在编译阶段,会用函数体替换函数调用。这是就会出现一个问题,如果内联函数太大,就会使目标文件变大,所以内联函数常被用来写一些短小的函数。实际上,如果内联函数过长,编译器也会忽视这个内联,把它当做普通函数处理;
  内联函数对于编译器只是一个建议,不同的编译器关于内联函数的实现机制可能存在不同。在《C++ prime》中明确指出,内联说明只是想编译器发出一个请求,编译器可以选择忽略这个请求;
  内联函数的声明和定义一般情况下是不分离的,因为分离之后可能会导致链接错误,内联函数是会被展开的,展开之后就不存在函数地址了,那这个时候去链接地址就会找不到。
  
使用场景:
  内联函数常被用来替代宏函数。这时候就有个问题,既然有宏函数,为什么又要搞出内联函数这个东西?因为宏是较大缺陷的。
  宏的优缺点:
    优点:增强代码的复用性;提高性能。
    缺点:不方便调试(因为在预编译阶段就进行了宏替换);导致代码可读性差,可维护性差,容易误用;没有类型安全检查。
    所以在C++中,常使用const enum代替宏的常量定义,用内联函数代替宏函数。

auto关键字(C++11):

  在写代码的时候,可能会遇到一个类型名非常长的情况,这种类型名写一两个还行,但是如果多了就非常容易写错。有些人会用typedef来解决这一问题,但是typedef有一个缺陷。
在这里插入图片描述

  早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但是并没有人使用它。之后在C++11中,auto就具有新的含义了,auto不再是一个存储类型的指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
  auto定义变量时必须初始化,auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器编译时会将auto替换为变量实际的类型。
  用autto声明指针类型时,用auto和auto*没有任何区别,但是用auto声明引用类型时必须要加&。

int main()
{int x = 10;auto a = &x;auto* b = &x;auto& c = x;auto d = x;//typeid().name()可以返回变量的类型名cout << typeid(a).name() << endl;cout << typeid(b).name() << endl;printf("%p\n", &x);printf("%p\n", &c);printf("%p\n", &d);return 0;
}

在这里插入图片描述

  当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
在这里插入图片描述

  auto不能作为函数参数;
  auto不能直接用来声明数组;
  为了避免与C++98中的auto发生混淆,C++11值保留了auto作为类型指示符的用法;

基于范围的for循环(C++):

  C++11中引入了基于范围的for循环。for循环后的括号由冒号":"分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。

int main()
{int a[] = { 1,2,3,4,5 };//自动依次取数组中的数据赋值给e(e只是个名字,可以改变),自动判断结束for (auto e : a)e *= 2;for (auto e : a)cout << e << " ";cout << endl;//这里相当于e是a[0]、a[1]等的别名,就可以达到改变数组的效果for (auto& e : a)e *= 2;for (auto e : a)cout << e << " ";cout << endl;return 0;
}

在这里插入图片描述

  与普通循环类似,也可以使用continue和break;
  范围for的循环范围必须是确定的;

指针空值nullptr(C++11):

  NULL实际是一个宏定义的,NULL可能被定义为字面常量0,或者被定义为无类型指针(void *)的常量。也不知道出于什么原因被定义成了字面常量0,这样在程序中就会造成一些不可预料的问题。
在这里插入图片描述

  于是C++11就打了一个补丁,引入nullptr作为关键字,代表指针空值。在C++11中,sizeof(nullptr)与sizeof((void*)0)所占用的字节数相同。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《分布式技术原理与算法解析》学习笔记Day23

分布式数据复制 我们在进行分布式数据存储设计时&#xff0c;通常会考虑对数据进行备份&#xff0c;以提高数据的可用性和可靠性&#xff0c;“数据复制技术”就是实现数据备份的关键技术。 什么是数据复制技术&#xff1f; 在分布式数据库系统中&#xff0c;通常会设置主备…

华为OD机试用Python实现 -【统一限载货物数最小值】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲统一限载货物数最小值题目描述输入描述输出描述说明示例一输入输出说明示例二输入输出说明Python 代码实现算法逻辑华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查…

python爬虫常见错误

python爬虫常见错误前言python常见错误1. AttributeError: WebDriver object has no attribute find_element_by_id1. 问题描述2. 解决办法2. selenium&#xff1a;DeprecationWarning: executable_path has been deprecated, please pass in1. 问题描述2. 解决办法3. 下载了包…

k8s-资源限制-探针检查

文章目录一、资源限制1、资源限制的使用2、reuqest资源&#xff08;请求&#xff09;和limit资源&#xff08;约束&#xff09;3、Pod和容器的资源请求和限制4、官方文档示例5、资源限制实操5.1 编写yaml资源配置清单5.2 释放内存&#xff08;node节点&#xff0c;以node01为例…

《程序员思维修炼》速读笔记

文章目录书籍信息概览绪论从新手到专家的历程认识大脑利用右脑调试大脑主动学习积累经验控制注意力超越专家图解书籍信息 书名&#xff1a;《程序员思维修炼&#xff08;修订版&#xff09;》 作者&#xff1a;[美] Andy Hunt 概览 绪论 再提“实用”关注情境所有人都关注这…

Flutter3引用原生播放器-IOS(Swift)篇

前言由于Flutter项目中需要使用到播放器功能&#xff0c;因此对flutter中各种播放器解决方案进行了一番研究和比对&#xff0c;最后决定还是自己通过Plugin的方法去引用原生播放器符合自己的需求&#xff0c;本篇文章会对各种解决方案做一个简单的比较&#xff0c;以及讲解一下…

线材-电子线载流能力

今天来讲的是关于电子线的一个小知识&#xff0c;可能只做板子的工程师遇到此方面的问题会比较少&#xff0c;做整机的工程师则必然会遇到此方面问题&#xff0c;那就是线材问题。 下面主要说下电子线的过电流能力。&#xff08;文末有工具下载&#xff09;电子线&#xff08;h…

[11]云计算|简答题|案例分析|云交付|云部署|负载均衡器|时间戳

升级学校云系统我们学校要根据目前学生互联网在线学习、教师教学资源电子化、教学评价过程化精细化的需求&#xff0c;计划升级为云教学系统。请同学们根据学校发展实际考虑云交付模型包含哪些&#xff1f;云部署采用什么模型最合适&#xff1f;请具体说明。9月3日买电脑还是租…

@Value注解的使用(可用于配置文件)

基本概念Value&#xff1a;注入配置文件中的内容。只要是spring的注解类&#xff08;service,compotent, dao等&#xff09;中都可以。Component&#xff1a;泛指组件&#xff0c;当组件不好归类的时候&#xff0c;可以使用这个注解进行标注。AutoWired&#xff1a;自动导入依赖…

Jinja2----------模板渲染、模板访问对象属性

目录 1.Jinja2 1.简介 2.Jinja2模板 2.模板渲染 app.py templates/index.html templates/blog_detail.html 效果 3.模板访问对象属性 app.py templates/index.html 效果 1.Jinja2 1.简介 Jinja2是Python下一个被广泛应用的模版引擎&#xff0c;他的设计思想来…

二叉树的前序遍历-java两种方式-力扣144

一、题目描述给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。示例 1&#xff1a;输入&#xff1a;root [1,null,2,3]输出&#xff1a;[1,2,3]示例 2&#xff1a;输入&#xff1a;root []输出&#xff1a;[]示例 3&#xff1a;输入&#xff1a;root [1]输出…

【Linux驱动开发100问】什么是模块?如何编写和使用模块?

&#x1f947;今日学习目标&#xff1a;什么是Linux内核&#xff1f; &#x1f935;‍♂️ 创作者&#xff1a;JamesBin ⏰预计时间&#xff1a;10分钟 &#x1f389;个人主页&#xff1a;嵌入式悦翔园个人主页 &#x1f341;专栏介绍&#xff1a;Linux驱动开发100问 什么是模块…

分布式之PBFT算法

写在前面 在分布式之拜占庭问题 一文中我们分析了拜占庭问题&#xff0c;并一起看了支持拜占庭容错的口信消息性和签名消息性算法&#xff0c;但是这两种算法都有一个非常严重的问题&#xff0c;就是消息数量太多&#xff0c;通信的成本太大&#xff0c;消息数量复杂度为O(n ^…

HMM(隐马尔科夫模型)-理论补充2

目录 一.大数定理 二.监督学习方法 1.初始概率 2.转移概率 3.观测概率 三.Baum-Welch算法 1.EM算法整体框架 2. Baum-Welch算法 3.EM过程 4.极大化 5.初始状态概率 6.转移概率和观测概率 四.预测算法 1.预测的近似算法 2.Viterbi算法 1.定义 2. 递推&#xff1…

2023安装archlinux笔记

本文只是个笔记&#xff0c;不是详细教程&#xff0c;仅供参考。 安装过程基本与 《2021年vmware安装archlinux》 https://blog.csdn.net/lxyoucan/article/details/115226297 差不多。 无U盘安装 不想格式化U盘了&#xff0c;直接从硬盘安装。参考一下文章。 《没有U盘纯硬…

Laravel框架02:路由与控制器

Laravel框架02&#xff1a;路由与控制器一、路由配置文件二、路由参数三、路由别名四、路由群组五、控制器概述六、控制器路由七、接收用户输入一、路由配置文件 以web网页路由文件为例&#xff1a; 默认根路由 路由定义格式Route::请求方式(请求的URL, 匿名函数或控制响应的方…

CV学习笔记-MobileNet

MobileNet 文章目录MobileNet1. MobileNet概述2. 深度可分离卷积&#xff08;depthwise separable convolution&#xff09;2.1 深度可分离卷积通俗理解2.2 深度可分离卷积对于参数的优化3. MobileNet网络结构4. 代码实现4.1 卷积块4.2 深度可分离卷积块4.3 MobileNet定义4.4 完…

一步步教你电脑变成服务器,tomcat的花生壳设置(原创)

1&#xff0c;首先你去https://console.oray.com/这网站注册个帐号&#xff0c;如果注册成功它会送你一个免费域名&#xff0c;当然不记得也没关系&#xff0c;你记住你注册的 帐号跟密码&#xff0c;然后下载它的软件&#xff08;花生壳动态域名6.0正式版&#xff09;有xp跟li…

java基础系列(六) sleep()和wait() 区别

一.前言 关于并发编程这块, 线程的一些基础知识我们得搞明白, 本篇文章来说一下这两个方法的区别,对Android中的HandlerThread机制原理可以有更深的理解, HandlerThread源码理解,请查看笔者的这篇博客: HandlerThread源码理解_handlerthread 源码_broadview_java的博客-CSDN博…

安装kibana 报错/访问不了

安装kibana 报错1&#xff0c;elasticsearch.yaml 和kibana.yaml 配置问题2&#xff0c;elasticsearch 和kibana版本不一致3&#xff0c;索引问题1&#xff0c;elasticsearch.yaml 和kibana.yaml 配置问题 我的RPM安装的&#xff0c;配置文件都在/etc/ vim /etc/elasticsearc…