< C++ >lesson2.C++入门下

news2024/12/22 20:38:13

在这里插入图片描述

文章目录

  • 1. 内联函数❤️
    • 1.1 内联函数的定义
    • 1.2 特性
  • 2. auto关键字🤍
    • 2.1 auto简介
    • 2.2 auto使用细则
    • 2.3 auto不能进行推导的场景
  • 3. 基于范围的for循环🧡
    • 3.2 范围for的条件
  • 4. nullptr指针💚

1. 内联函数❤️

在C语言中有宏函数的概念,宏函数是宏的一种,可以实现和函数一样的功能
宏函数相比函数的优点有:

  1. 运行速度更快,不需要开辟栈帧
  2. 宏不需要指定参数类型

缺点:
3. 没有函数安全,不会进行类型检查
4. 无法调试
5. 可读性不高

C++中引入了内联函数保留了函数的优点又继承了宏的优点

1.1 内联函数的定义

inline修饰的函数叫做内联函数,编译阶段时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率

下面代码说明了内联函数可以直接展开

//内联函数
inline void fun1()
{
	int a = 1;
	int b = 2;
	int c = a + b;
}
int main()
{
fun1();
return 0;
}

汇编代码
在这里插入图片描述
程序执行fun1函数时,汇编指令并没有call指令,说明了fun1函数是直接被展开的

想要观察内联函数的汇编指令需要按如下方式设置(下面给出vs2022的方式):
首先打开 项目->属性
在这里插入图片描述
在这里插入图片描述

1.2 特性

  • inline是使用空间换时间的一种做法,如果函数体太大,用函数体替换函数调用后会使目标文件变大。

  • inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建
    议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不
    是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性

    在这里插入图片描述

  • inline不建议声明和定义分开,分开会导致链接错误。因为调用内联函数时会将该函数展开,但是声明和定义是分开的,所以在调用的文件中找不到内联函数的函数体,会发生链接错误.声明时用extern关键字可以将内联函数定义和声明分开
    在这里插入图片描述
    在这里插入图片描述


2. auto关键字🤍

在编程时,常常需要把表达式的值赋值给变量,这就要求在声明变量的时候清楚地知道表达式的
类型。然而有时候要做到这点并非那么容易,因此C++11给auto赋予了新的含义。

2.1 auto简介

早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的
是一直没有人去使用它
C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一
个新的类型指示符来指示编译器
,auto声明的变量必须由编译器在
编译时期
推导而得。

int TestAuto()
{
	return 10;
}
struct Student
{
	string name;
	int age;
	char sex;
};
int main()
{
	int a = 10;
	auto b = a;
	auto c = 'a';
	auto d = TestAuto();
	auto f = 1.2;
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;
	cout << typeid(f).name() << endl;
	struct Student s1 = { "sy", 18, 'M' };
	auto s = s1;
	cout << typeid(s).name() << endl;
	//auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
	return 0;
}

在这里插入图片描述

2.2 auto使用细则

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

    int main()
    {
    	int a = 10;
    	int b = 20;
    int c = 30;
    auto pa = &a;
    auto* pb = &b;
    auto ppa = &pa;
    auto* ppb = &pb;
    auto& rc = c;
    cout << typeid(pa).name() << endl;
    cout << typeid(pb).name() << endl;
    cout << typeid(ppb).name() << endl;
    cout << typeid(ppb).name() << endl;
    cout << typeid(rc).name() << endl;
    return 0;
    }
    
    
  2. 在同一行定义多个变量当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量
    在这里插入图片描述

2.3 auto不能进行推导的场景

  1. auto不能作为函数的参数

    // 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
    void TestAuto(auto a)
    {}
    
  2. auto不能直接用来声明数组

    //auto不能使用的场景
    int main()
    {
    	int a[] = { 1, 2, 3, 4 };
    	auto b[] = {1, 2, 3, 4};
    	cout << typeid(b).name() << endl;
    	return 0;
    }
    
    
  3. 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法

  4. auto在实际中最常见的优势用法就是跟以后会讲到的C++11提供的新式for循环,还有lambda表达式等进行配合使用。


3. 基于范围的for循环🧡

在C++11之前想要遍历一个数组必须将数组元素的个数求出来

int main()
{
	int arr[] = { 1, 2, 3, 4, 5 };
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
		cout << arr[i] << " ";
	return 0;
}

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还容易出错,因此C++11引入了基于范围的for循环。for循环由:前后的两部分组成,:前面的是在范围内迭代的变量,:后面的是迭代的范围

int main()
{
	int arr[] = { 1, 2 ,3 ,4 };
	for (auto e : arr)//e是迭代变量,arr是一个数组,在这个数组中进行迭代
		cout << e << " ";
	cout << endl;
	for (auto& e : arr)
		e *= 2;
	for (auto e : arr)
		cout << e << " ";
	return 0;
}

在这里插入图片描述

3.2 范围for的条件

  1. for循环迭代的范围必须是确定
    对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供
    begin和end的方法,begin和end就是for循环迭代的范围。
    注意:以下代码就有问题,因为for的范围不确定
void TestFor(int array[])
{
    for(auto& e : array)
        cout<< e <<endl;
}
  1. 迭代的对象要实现++和==的操作。(关于迭代器这个问题,以后会讲,现在提一下,没办法
    讲清楚,现在大家了解一下就可以了)

4. nullptr指针💚

NULL的定义如下
在这里插入图片描述

C语言中的NULL指针定义为#define NULL ((void*)0)
C++中的NULL指针定义为#define NULL 0
如果在C++中像使用NULL指针,因为它被字面量0替换,所以在某些情况下会出现问题
在这里插入图片描述
NULL指针并没有发挥出指针的功能,如果像让NULL在C++中发挥出空指针的效果,那么需要强制类型转换为void*,C++11为了解决这个问题,引入了关键字nullptr
在这里插入图片描述


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

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

相关文章

【嵌入式】Modbus实践

前言 最近接了一个项目&#xff0c;需要使用Modbus协议&#xff0c;虽然之前有所耳闻&#xff0c;但一直没有实操过&#xff0c;但实践之后发现其实还是很简单的&#xff0c;我认为它本质上就是对串口传输进行“二次封装”。 建议的入门顺序 大神带你秒懂Modbus通信协议——理…

【zotero】从知网万方维普WOS等数据库上导出格式引文-引文格式到zotero中

一、问题背景 最近新中特课要交课程论文作业了&#xff0c;老师说要有参考文献引注。 于是我找了很多参考文献&#xff0c;但是不打算放在我的zotero文献库中&#xff0c;因为我不想我的zotero文献库中包括与我专业学习不相关的东西。 鉴于导入文献后识别成引注后续导出打包…

iOS开发之Masonry框架源码深度解析

Masonry是iOS在控件布局中经常使用的一个轻量级框架&#xff0c;Masonry让NSLayoutConstraint使用起来更为简洁。Masonry简化了NSLayoutConstraint的使用方式&#xff0c;让我们可以以链式的方式为我们的控件指定约束。本篇博客的主题不是教你如何去使用Masonry框架的&#xff…

1992-2022年31省人均gdp/各省人均地区生产总值

1992-2022年31省人均gdp/各省人均地区生产总值 1、时间&#xff1a;1992-2022年 2、来源&#xff1a;国家统计J、各省NJ 3、范围&#xff1a;包括31省 4、缺失情况说明&#xff1a;无缺失 5、指标包括&#xff1a;各省人均GDP/省人均地区生产总值 6、指标解释&#xff1a…

sql注入(二)盲注,二次注入

目录 一、布尔盲注 1.判断库名的长度 2.判断数据库名 2.1判断数据库名首字符 2.2 判断数据库名的其余字符 二、时间盲注&#xff1a; 1.判断库名的长度 2.判断库名&#xff1a; 3.判断表名payload&#xff1a; 4.爆出列名 5.爆数据 三、二次注入 1.原理&#xff1a; …

Linux 常用操作技巧

Linux 操作技巧大全 Linux是一种强大的操作系统&#xff0c;掌握各种操作技巧可以帮助我们惬意地使用它。在这篇博客中&#xff0c;我们将分享一些实用的Linux技巧&#xff0c;希望能对您有所帮助&#xff01; 1. 使用Tab进行自动补全 在输入命令时&#xff0c;按下Tab键可…

漫谈大数据 - 数据湖认知篇

导语&#xff1a;数据湖是目前比较热的一个概念&#xff0c;许多企业都在构建或者准备构建自己的数据湖。但是在计划构建数据湖之前&#xff0c;搞清楚什么是数据湖&#xff0c;明确一个数据湖项目的基本组成&#xff0c;进而设计数据湖的基本架构&#xff0c;对于数据湖的构建…

Embarcadero Delphi 11 和 C++Builder 11 免费社区版发布!

Embarcadero为Delphi和CBuilder的最新11.3版本提供了社区版许可证。这是Delphi或CBuilder的免费版本&#xff0c;适用于学生&#xff0c;业余爱好者和初创公司&#xff08;因为许可证仅对于收入有限的公司或个人&#xff09;。 什么是CE社区版&#xff1f; Delphi 和 CBuilde…

【Git 入门教程】第七节、Git 远程仓库(Github)

GitHub是一个基于Git的代码托管平台&#xff0c;它是全球最大的开源软件社区之一。GitHub允许开发者在上面创建和托管他们的Git仓库&#xff0c;并与其他开发者进行协作。 GitHub是一个非常流行的Git工具&#xff0c;它是开源社区的重要组成部分&#xff0c;并支持许多著名的开…

【MySQL】交叉连接、自然连接和内连接查询

一、引入 实际开发中往往需要针对两张甚至更多张数据表进行操作&#xff0c;而这多张表之间需要使用主键和外键关联在一起&#xff0c;然后使用连接查询来查询多张表中满足要求的数据记录。一条SQL语句查询多个表&#xff0c;得到一个结果&#xff0c;包含多个表的数据。效率高…

测试人员的启蒙指南

文章目录 一. 了解测试1. 生活中的测试场景2. 什么是软件测试3. 实战练习 二. 软件测试和软件开发的区别三. 软件测试和软件调试的区别四. 软件测试的发展五. 软件测试的岗位六. 一个优秀的软件测试人员具备的素质 本篇中介绍测试人员是干什么的, 起到启蒙和了解的作用, 重点是…

A 股指数分时行情数据 API 数据接口

A 股指数分时行情数据 API 数据接口 多维度分时指标&#xff0c;指数分时&#xff0c;多时间区间查询参数。 1. 产品功能 支持所有指数数据查询&#xff1b;支持指数分时数据查询&#xff1b;多时间维度分时数据&#xff1b;多维度的统计时间以及数据结果&#xff1b;秒级查询…

linux系统应用中select函数与poll函数详解

目录 第一&#xff1a;poll()函数详解 第二&#xff1a;select()函数详解 第一&#xff1a;poll()函数详解 1 poll函数概述 select() 和 poll() 系统调用的本质一样&#xff0c;poll() 的机制与 select() 类似&#xff0c;与 select() 在本质上没有多大差别&#xff0c;管理多…

外设驱动库开发笔记53:MAX31856热偶变送器驱动

在我们的产品中经常有需要温度检测的地方&#xff0c;而热电偶温度检测电路是我们常用的。热电偶温度检测的方法很多&#xff0c;有时出于简单方便的考虑我们会选择热偶温度变送器来实现&#xff0c;这一篇我们就来讨论使用MAX31856热电偶温度变送器实现温度的检测。 1、功能概…

【PCL】—— 点云配准ICP(Iterative Closest Point)算法

文章目录 数学原理问题定义计算平移计算旋转 案例实现参考 ​     由于三维扫描仪设备受到测量方式和被测物体形状的条件限制&#xff0c;一次扫描往往只能获取到局部的点云信息&#xff0c;进而需要进行多次扫描&#xff0c;然后每次扫描时得到的点云都有独立的坐标系&…

第十六章 预制件prefab(上)

本章节我们介绍一下“预制件”&#xff0c;也有人叫“预制体”&#xff0c;也就是Prefab。在游戏世界中&#xff0c;那些自然环境的游戏对象&#xff0c;我们可以提前创建在场景中&#xff0c;这个大家能够理解。但是&#xff0c;有些游戏对象&#xff0c;需要根据游戏逻辑来通…

20230430 ICFD学习笔记 管道流动

三个边界: (1) 速度入口 (2) 压力出口 (3) 非滑移边界 一、先利用workbench进行网格的划分,导出K文件。 二、利用Ultraeidt进行K文件的修改 (或者是在lspp中直接删除也行) K文件开头是*Keyword Part *Define coordinate system后面到*Database binary D3prop全部删除 &…

Dubbo总结

目录 什么是分布式系统 单机架构、集群架构、分布式架构 Dubbo的概念 Dubbo的核心组件 Dubbo的常用注解 Dubbo的高级特性&#xff1a; 序列化特性安全 地址缓存 超时机制 重试机制 多版本灰度发布 负载均衡 集群容错 服务降级 服务限流 结果缓存 Dubbo实战&#xff1a;…

40.java-Set集合(HashSet,LinkedHashSet,TreeSet)

Set集合 1.Set集合特点2.Set集合实现类3. HashSet3.1 底层原理3.1.1 哈希表组成3.1.2 哈希值3.1.3 对象的哈希值特点 3.2 数据添加元素的过程3.3 HashSet的三个问题3.4 实例&#xff1a;去除重复元素 4. LinkedHashSet5. TreeSet5.1 特点5.2 集合默认规则5.3 例子5.4 两种比较规…

JavaScript 知识总结上篇(更新版)

1. 为什么 JS 是单线程的&#xff1f; 因为JS里面有可视的Dom&#xff0c;如果是多线程&#xff0c;这个线程正在删除DOM节点&#xff0c;另一个线程正在编辑Dom节点&#xff0c;导致浏览器不知道该听谁的 2.如何理解同步和异步&#xff1f; 同步&#xff1a;按照代码书写顺…