C++入门(2)

目录

  • 1. 内联函数
    • 1.1概念
    • 1.2特性
  • 2. auto关键字
    • 2.1 为什么要有auto
    • 2.2 auto 简介
    • 2.3 auto的使用细则
  • 3.基于范围的for循环(C++11)
    • 3.1 范围for的语法
    • 3.2 范围for的使用条件
  • 4.指针空值nullptr(C++11)
    • 4.1 C++98中的指针空值
    • 4.2 用nullptr表示指针空值

在这里插入图片描述

1. 内联函数

在这里插入图片描述

1.1概念

用inline修饰的函数叫作内联函数,C++编译器在编译时会在内联函数出展开,没有建立栈帧的开销,从而实现程序运行效率的提升

1.2特性

(1)内联函数是一种以空间换时间的作法,它在编译阶段,会用函数体替换函调用
故它的优点是减少调用开销,提升程序运行效率。缺点是可能会使目标文件变大

(2)inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,如果函数规模较大,递归,或者函数并没有被频繁调用,不建议使用inline修饰,否则编译器会忽略inline特性,下图为《C++prime》第五版关于inline的建议:
在这里插入图片描述
利用这点特性我们可以用内联函数来代替一些短小的宏函数

(3) inline不建议声明和定义分离,分离会导致链接错误。就算在各个文件内函数都是正确的,也是一样。因为inline被展开,就没有函数地址了,链接就会找不到

//F.h
#include <iostream>
using namespace std;
inline void f(int i);
// F.cpp
#include "F.h"
void f(int i)
{
 cout << i << endl;
}
// main.cpp
#include "F.h"
int main()
{
 f(10);
 return 0;
}
// 链接错误:main.obj : error LNK2019: 无法解析的外部符号 "void __cdecl 
f(int)" (?f@@YAXH@Z),该符号在函数 _main 中被引用

2. auto关键字

2.1 为什么要有auto

随着我们深入的学习,写的程序越来越复杂,程序中用到的类型也越来越复杂,我们在写代码的时候会发现某些类型难以拼写,而且容易写错,因此auto诞生了,它可以让我们写代码更简单。
这时候又有个问题,我们之前学过typedef也可以通过改名来简化代码,那么为什么不用typedef呢?
因为在编程时,常常需要把表达式的值赋值给变量,这就要求在声明变量的时候清楚地知道表达式的类型。这一点typedef是做不到的。

typedef char* abcdefg;
int main()
{
 const abcdefg p1;    // 编译成功还是失败?
 const abcdefg* p2;   // 编译成功还是失败?
 return 0;
}

2.2 auto 简介

在C++11中,标准委员会赋予了auto的含义为:auto作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

这意味着我们使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。

int main()
{
    int a = 10;
    auto b = a;
    auto c = 'a';
    cout << typeid(b).name() << endl;
    cout << typeid(c).name() << endl;
    //auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
    return 0;
}

2.3 auto的使用细则

(1)auto与指针和引用结合起来使用时
用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

int main()
{
    int x = 10;
    auto a = &x;
    auto* b = &x;
    auto& c = x;
    
    cout << typeid(a).name() << endl;
    cout << typeid(b).name() << endl;
    cout << typeid(c).name() << endl;

    *a = 20;
    *b = 30;
     c = 40;
     
     return 0;
}

(2)在同一行定义变量时这些变量必须为同一个类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

void Auto1()
{
    auto a = 1, b = 2; 
    auto c = 3, d = 4.0; 
  //上面这行代码会编译失败,因为c和d的初始化表达式类型不同
}

(3)auto不能用来当作函数形参和声明数组

3.基于范围的for循环(C++11)

3.1 范围for的语法

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围

void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
//表示自动遍历数组,并赋值给e
for(auto& e : array)//声明引用对象auto后必须加&
     e *= 2;
for(auto e : array)
     cout << e << " ";
return 0;
}

3.2 范围for的使用条件

(1) for循环迭代的范围必须是确定的。对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。
(2)迭代的对象要实现++和==的操作。

4.指针空值nullptr(C++11)

4.1 C++98中的指针空值

对于一个指针,我们通常是这样初始化的:

void TestPtr()
{
    int* p1 = NULL;
    int* p2 = 0;
    // ……
}

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

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

可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void)的常量。 这样会导致我们使用空值的指针时会遇到麻烦。

void f(int)
{
     cout<<"f(int)"<<endl;
}
void f(int*)
{
     cout<<"f(int*)"<<endl;
}
int main()
{
     f(0);
     f(NULL);
     f((int*)NULL);
     return 0;
}

程序本来是想通过f(NULL)调用指针版本的f(int*)函数,但是因为NULL被定义成0,这样就矛盾了。

4.2 用nullptr表示指针空值

(1)用nullptr表示指针空值,可以规避NULL被定义成0而导致的错误,我们在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
(2)在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
(3)为了保持代码的健康,在后续表示指针空值时建议最好使用nullptr。在这里插入图片描述

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

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

相关文章

【单链表】无头单项不循环(1)

目录 单链表 主函数test.c test1 test2 test3 test4 头文件&函数声明SList.h 函数实现SList.c 打印SLPrint 创建节点CreateNode 尾插SLPushBack 头插SLPushFront 头删SLPopBck 尾删SLPopFront 易错点 本篇开始链表学习。今天主要是单链表&OJ题目。 单链…

23个优秀开源免费BI仪表盘

BI也称为商业智能&#xff0c;是收集、分析和展示数据以支持决策者做出明智的业务决策的过程。BI帮助组织将其原始的生产数据转化为有意义的见解或者知识&#xff0c;以推动其业务战略。BI能够为组织改善决策、提高效率和提升资源利用率。 BI仪表盘是BI系统的重要组成部分&…

Websocket @ServerEndpoint不能注入@Autowired

在websocket中使用ServerEndpoint无法注入Autowired、Value 问题分析 Spring管理采用单例模式&#xff08;singleton&#xff09;&#xff0c;而 WebSocket 是多对象的&#xff0c;即每个客户端对应后台的一个 WebSocket 对象&#xff0c;也可以理解成 new 了一个 WebSocket&…

安全操作(安卓推流)程序

★ 安全操作项目 项目描述&#xff1a;安全操作项目旨在提高医疗设备的安全性&#xff0c;特别是在医生离开操作屏幕时&#xff0c;以减少非授权人员的误操作风险。为实现这一目标&#xff0c;我们采用多层次的保护措施&#xff0c;包括人脸识别、姿势检测以及二维码识别等技术…

Web逆向-某网络学院学习的”偷懒“思路分析

接到求助&#xff0c;帮朋友完成20课时的网络学习。 我想都没想就接下了&#xff0c;寻思找个接口直接把学习时间提交上去&#xff0c;易如反掌。 最不济最不济&#xff0c;咱还能16x播放&#xff0c;也简单的很 然鹅&#xff0c;当我登陆的时候&#xff0c;发现自己还是太天真…

边缘计算助力低速无人驾驶驶入多场景落地快车道

自动驾驶刮起的风&#xff0c;如今正吹向低速无人驾驶赛道。近期不完全统计显示&#xff0c;当前A股及港股正在排队IPO的自动驾驶相关企业共有12家&#xff0c;其中实现盈利的企业仅两家&#xff0c;而且实现盈利的两家企业最主要的收入并不完全源于自动驾驶领域。 相比之下&am…

mysql数据库的备份和恢复

目录 一、备份和恢复 1、备份&#xff1a; 2、备份的方法&#xff1a; 2.1物理备份&#xff1a; 2.2、逻辑备份 2.3增量备份&#xff1a; 一、备份和恢复 1、备份&#xff1a; 先备份再恢复 备份&#xff1a;完全备份&#xff0c;增量备份 完全备份&#xff1a;将整个…

JAVA中类和对象的认识

1、面向对象的初步认知 1.1 什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面 向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。用面向对象的…

Java的JDBC编程

文章目录 一、数据库编程的必备条件二、Java的数据库编程&#xff1a;JDBC三、JDBC的工作原理四、JDBC的使用4.1 JDBC 开发案例4.2 JDBC 使用步骤总结 五、JDBC常用的接口和类5.1 JDBC API5.2 数据库连接 Connection5.3 Statement 对象5.4 ResultSet 对象 七、内容总结 一、数据…

【调度算法】并行机调度问题遗传算法

问题描述 m台相同的机器&#xff0c;n个工件&#xff0c;每个工件有1道工序&#xff0c;可按照任意的工序为每个工件分配一台机器进行加工 工件ABCDEFGHI工件编号012345678加工时间4765835510到达时间324532186交货期101530241413201810 设备数目&#xff1a;3 目标函数 最…

0X03

红包题第二弹 看到源码里面的提示 ?cmdphpinfo(); 看到源码 kk 关键点就是有两个正则表达式 第一个 preg_match("/[A-Za-oq-z0-9$]/",$cmd) 第二个 preg_match("/\~|\!|\|\#|\%|\^|\&|\*|\(|\)|\&#xff08;|\&#xff09;|\-|\_|\{|\}|\[|\]|\|\&q…

Redis 的缓存击穿,穿透,雪崩及其解决方案

1 缓存穿透 什么是缓存穿透&#xff1f; 大量请求的 key 是不合理的&#xff0c;根本不存在于缓存中&#xff0c;也不存在于数据库中 。导致这些请求直接到了数据库上&#xff0c;根本没有经过缓存这一层&#xff0c;对数据库造成了巨大的压力&#xff0c;可能直接就被这么多…

QT 实现解密m3u8文件

文章目录 概要如何解密M3U8文件呢实现思路和代码序列图网络请求解密 结论 概要 视频文件很多已M3U8文件格式来提供&#xff0c;先复习下什么是M3U8文件&#xff01;用QT的 mutimedia框架来播放视频时&#xff0c;有的视频加载慢&#xff0c;有的视频加载快&#xff0c;为啥&am…

深入了解Jedis:Java操作Redis的常见类型数据存储

目录 前言 一、Jedis介绍 1.Jedis在各方面的功能 2.特点 二、Java连接Redis 1.导入pom依赖 2.建立连接 三、Java操作Redis的常见类型数据存储 1.字符串 2.哈希表 3.列表 4.集合 5.有序集合 四、Redis的实际应用场景实例 1.会议信息实体 2.自定义注解 3.创建切面…

mermaid学习第一天/更改主题颜色和边框颜色/《需求解释流程图》

mermaid 在线官网&#xff1a; https://mermaid-js.github.io/ 在线学习文件&#xff1a; https://mermaid.js.org/syntax/quadrantChart.html 1、今天主要是想做需求解释的流程图&#xff0c;又不想自己画&#xff0c;就用了&#xff0c;框框不能直接进行全局配置&#xff0…

Mac电脑录屏软件 Screen Recorder by Omi 中文最新

Screen Recorder by Omi是一款屏幕录制软件&#xff0c;它可以帮助用户轻松地录制屏幕活动&#xff0c;并将其保存为高质量的视频文件。 该软件提供了多种录制选项&#xff0c;包括全屏录制、选择区域录制和单窗口录制等&#xff0c;同时提供了丰富的设置选项&#xff0c;如视…

[动态规划] (十) 路径问题 LeetCode 174.地下城游戏

[动态规划] (十) 路径问题: LeetCode 174.地下城游戏 文章目录 [动态规划] (十) 路径问题: LeetCode 174.地下城游戏题目解析解题思路状态表示状态转移方程初始化和填表顺序返回值 代码实现总结 174. 地下城游戏 题目解析 先明白下题题再来看。 [动态规划] (四) LeetCode 91.…

Apache Doris (五十一): Doris数据缓存

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录 1.

【教3妹学编程-算法题】2924. 找到冠军 II

3妹&#xff1a;2哥快看&#xff0c;我黑龙江的闺蜜给我发了一个她在打雪仗的视频&#xff0c;好大的雪啊&#xff0c;好欢乐。 2哥&#xff1a;什么&#xff0c;东北不是暴雪吗&#xff0c; 还可以打雪仗。 3妹 :是啊&#xff0c;可是雪停了就可以打雪仗了啊。 2哥&#xff1a…

竞赛选题 深度学习手势识别算法实现 - opencv python

文章目录 1 前言2 项目背景3 任务描述4 环境搭配5 项目实现5.1 准备数据5.2 构建网络5.3 开始训练5.4 模型评估 6 识别效果7 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习手势识别算法实现 - opencv python 该项目较为新颖…