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

c++入门

  • 1.内联函数
  • 1.1 概念
    • 1.2 特性
  • 2.auto关键字(C++11)
    • 2.1 简介
    • 2.2 auto的使用
    • 2.3 auto不能推导的场景
    • 2.4 typedef取别名也能产生和auto的效果,为什么不使用?
  • 3.基于范围的for循环(C++11)
    • 3.1 9.1 范围for的语法
    • 3.2 范围for的使用条件
  • 4.指针空值nullptr(C++11)

1.内联函数

1.1 概念

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
在这里插入图片描述
如果在上述函数前增加inline关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。
在这里插入图片描述

1.2 特性

假设某个函数有100行指令,10000个位置调用
展开:10000x100
不展开:10000+100
展开后编译出来的可执行的程序变大

  1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运
    行效率。
  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略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关键字(C++11)

2.1 简介

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

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

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

2.2 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;
}
  1. 在同一行定义多个变量
    当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译
    器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
void TestAuto()
{auto a = 1, b = 2; auto c = 3, d = 4.0;  // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}

2.3 auto不能推导的场景

  1. auto不能作为函数的参数
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
  1. auto不能直接用来声明数组
void TestAuto()
{int a[] = {1,2,3};auto b[] = {456};
}
  1. 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法
  2. auto在实际中最常见的优势用法就是跟以后会讲到的C++11提供的新式for循环,还有
    lambda表达式等进行配合使用。

2.4 typedef取别名也能产生和auto的效果,为什么不使用?

使用typedef给类型取别名确实可以简化代码,但是typedef有会遇到新的难题:

typedef char* pstring;
int main()
{const pstring p1;    //编译失败,类似于-> char* const p1; const指针必须要初始化const pstring* p2;   // 编译成功return 0;
}

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

3.1 9.1 范围for的语法

在C++98中如果要遍历一个数组,可以按照以下方式进行:

void TestFor()
{int array[] = { 1, 2, 3, 4, 5 };for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)array[i] *= 2;for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)cout << *p << endl;
}

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

void TestFor()
{int array[] = { 1, 2, 3, 4, 5 };for(auto& e : array)e *= 2;for(auto e : array)cout << e << " ";return 0;
}

注意:与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。

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(C++11)

在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下方式对其进行初始化:

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,因此与程序的初衷相悖。在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。

注意

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入
    的。
  2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
  3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

在这里插入图片描述

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

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

相关文章

.DFS.

DFS 全称为Depth First Search&#xff0c;中文称为深度优先搜索。 这是一种用于遍历或搜索树或图的算法&#xff0c;其思想是: 沿着每一条可能的路径一个节点一个节点地往下搜索&#xff0c; 直到路径的终点&#xff0c;然后再回溯&#xff0c;直到所有路径搜索完为止。 DFS俗…

面向对象编程的魅力与实战:以坦克飞机大战为例

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、面向对象编程的引言 二、理解面向对象编程与面向过程编程的差异 三、创建类与对象&…

yolov8+ROS+ubuntu18.04——学习记录

参考文献 1.Ubuntu配置Yolov8环境并训练自己的数据集 ROS实时运行 2.https://juejin.cn/post/7313979467965874214 前提&#xff1a; 1.CUDA和Anaconda&#xff0c;PyTorch 2.python>3.8 一、创建激活环境&#xff0c;安装依赖 1.创建虚拟环境 conda create -n yol…

Java项目:基于SSM框架实现的企业人事管理系统单位人事管理系统【ssm+B/S架构+源码+数据库+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的企业人事管理系统单位人事管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观…

基于云开发快速搭建智能名片小程序

熏风徐来&#xff0c;麦穗摇曳&#xff1b;麦类等夏熟作物生长旺盛&#xff0c;籽粒灌浆渐趋饱满&#xff0c;但尚未完全成熟&#xff0c;故称“小满”。 今日小满&#xff0c;基于云开发快速搭建智能名片小程序&#xff0c;发文以记录输入和输出过程。 一、功能总览&#xff…

数据结构(五)队列

文章目录 一、概念二、逻辑结构&#xff1a;线性结构三、存储结构&#xff08;一&#xff09;顺序队列&#xff08;二&#xff09;循环队列1. 结构体定义2. 创建队列&#xff08;1&#xff09;函数定义&#xff08;2&#xff09;注意点&#xff08;3&#xff09;代码实现 3. 入…

学习100个Unity Shader (18) --- 几何着色器(Geometry Shader)

文章目录 概述编写格式举例应用举例&#xff08;用预制体球的每个顶点画一个立方体&#xff09;参考 概述 vertex shader --> [geometry shader] --> fragment shader。[]: 可选阶段。输入图元 —> geometry shader —> 其他图元 编写格式 [maxcertexcount(N)] …

什么是访问越界(C语言数组、指针、结构体成员访问越界)

在C语言中&#xff0c;访问越界&#xff08;Access Violation 或 Out-of-Bounds Access&#xff09;是指程序试图访问的内存位置超出了其合法或已分配的范围。这通常发生在数组、指针或其他内存结构的使用中。 案例&#xff1a; #include <stdio.h>//数组 //Visiting b…

基于Django的美团药品数据分析与可视化系统,有多用户功能,可增删改查数据

背景 随着电子商务和健康产业的迅速发展&#xff0c;药品行业数据的分析和可视化变得愈发重要。基于Django的美团药品数据分析与可视化系统的研究背景凸显了对药品数据的深入挖掘和分析的需求。该系统不仅具备多用户功能&#xff0c;允许不同角色的用户进行数据管理和分析&…

python列表生成式的妙用:区间内奇数求和

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、案例背景 三、实现步骤 四、案例验证 五、总结 一、引言 在Python编程中&a…

Java三种方法实现多线程,继承Thread类,实现Runnable接口,实现Callable接口

目录 线程&#xff1a; 继承Thread类&#xff1a; 实现Runnable类&#xff1a; 实现Callable接口&#xff1a; 验证多线程&#xff1a; 线程&#xff1a; 定义&#xff1a;进程可以同时执行多个任务&#xff0c;每个任务就是线程。举个例子&#xff1a;一个Java程序&#…

力扣刷题--LCR 075. 数组的相对排序【简单】

题目描述 给定两个数组&#xff0c;arr1 和 arr2&#xff0c; arr2 中的元素各不相同 arr2 中的每个元素都出现在 arr1 中 对 arr1 中的元素进行排序&#xff0c;使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。 …

实现UI显示在最上面的功能

同学们肯定遇到过UI被遮挡的情况&#xff0c;那如何让UI显示在最前面呢&#xff0c;先看效果 原理:UI的排序方式是和unityHierarchy窗口的层级顺序有关的&#xff0c;排序在下就越后显示&#xff0c;所以按照这个理论&#xff0c;当我们鼠标指到UI的时候把层级设置到最下层就好…

nacos(一) 安装

一 nacos 1.4.7安装 安装 nacos-server nacos官方下载 说明&#xff1a; 下载1.4.7和2.3.2版本,本专栏后续以1.4.7为例进行讲解补充&#xff1a; nacos-server服务端和nacos-client客户端附加&#xff1a; spring 版本、nacos-server、nacos-client版本要适配思考&#xf…

【Redis】Widows 和 Linux 下使用 Redis

Redis 简述 1.缓存 缓存就是将数据存放在距离计算最近的位置以加快处理速度。缓存是改善软件性能的第一手段,现代 CPU 越来越快的一个重要因素就是使用了更多的缓存,在复杂的软件设计中,缓存几乎无处不在。大型网站架构设计在很多方面都使用了缓存设计。 2.Redis Redis …

同元软控专业模型库系列—电气篇

一、引言 电气作为研究电能产生、传输、分配、使用和控制的专业领域&#xff0c;在航空航天、能源电力、船舶推进、轨道交通等众多行业中占据着举足轻重的地位&#xff0c;应用范围涉及电力工程、电子通信、自动化控制等&#xff0c;如电池充电管理芯片设计、航天器伺服系统、…

GitHub Copilot如何订阅使用

1.Copilot是什么 Copilot是由Github和OpenAI联合开发的一个基于人工智能大模型的代码写作工具。 我们都知道Github是世界上拥有开源项目及代码最多的一个平台&#xff0c;有了这么一个得天独厚的资源&#xff0c;Github联合OpenAI喂出了Copilot。经过不断地更新迭代&#xff…

Word整理论文参考文献

1.安装Zotero软件 2.安装Zotero的Chrome网站插件&#xff0c;并将插件固定到浏览器 3.安装Word的Zotero插件 4.在DBLP网站https://dblp.org/search 搜索需要添加的参考文献->点击BibTex->点击网页右上角的Zotero符号&#xff08;即第二步所指的符号&#xff09;->至…

红队攻防渗透技术实战流程:红队目标上线之webshell工具魔改

红队攻防免杀实战 1. 红队目标上线-Webshell免杀-源码魔改1.2 Webshell-代码混淆&流量绕过&工具原理1.2 通过对冰蝎的数据包分析:1.2魔改冰蝎-JAR反编译打包构建1.2魔改冰蝎-防识别-打乱特征指纹1.2魔改冰蝎-防查杀-新增加密协议1. 红队目标上线-Webshell免杀-源码魔改…

[转载]同一台电脑同时使用GitHub和GitLab

原文地址&#xff1a;https://developer.aliyun.com/article/893801 简介&#xff1a; 工作中我们有时可能会在同一台电脑上使用多个git账号&#xff0c;例如&#xff1a;公司的gitLab账号&#xff0c;个人的gitHub账号。怎样才能在使用gitlab与github时&#xff0c;切换成对应…