当前位置: 首页 > news >正文

【C++】入门(二)

在这里插入图片描述

前言:
c++基础语法(下)


文章目录

  • 五、引用
    • 5.1 引用概念
    • 5.2 引用使用规则
    • 5.3 常引用
    • 5.4 引用的使用场景
    • 5.5 引用和指针的区别
  • 六、内联函数
    • 6.1 概念
    • 6.2 内联函数的特性
  • 七、auto关键字(C++11)
    • 7.1 概念
    • 7.2 使用规则
    • 7.3 用于for循环(C++11)
  • 八、指针空值nullptr(C++11)

五、引用

5.1 引用概念

引用是C++语言中的一种机制,用于创建变量的别名。它使用一个已存在的变量来创建另一个名称,从而通过不同的名字访问相同的内存位置。

类型& 引用变量名(对象名) = 引用实体;int a = 10;
//创建引用
int& ra = a;

5.2 引用使用规则

规则如下:

  1. 引用必须在声明时进行初始化: 引用在定义的同时必须进行初始化。

    int a = 42;
    int& a1 = a; // 正确,引用被初始化
    
  2. 创建包含引用的数组: 创建一个包含引用的数组。

     int array[5] = {1, 2, 3, 4, 5};int& referencesArray[5] = {array[0], array[1], array[2], array[3], array[4]};//referencesArray 中的每个元素都是一个对应于 array 中相应索引位置的引用。上述代码创建了一个引用数组,并将每个引用与数组 array 中的元素相绑定。
    
  3. 引用不能重新赋值: 一旦引用被初始化,就不能改变其引用的对象。

    int a = 10;
    int b = 20;
    int& ref = a;
    ref = b; // 此时 a 的值变成 20,而不是修改引用的目标
    
  4. 一个变量可以有多个引用: 多个引用可以同时指向相同的变量,这样它们就共享相同的内存地址,对该变量的修改将会被所有引用所影响。

    int a = 10;
    int& b = a;//b,c都是a的别名
    int& c = a;int d = 5;
    b = d;//变量a被修改为5,同样的b = 5,c = 5
    

5.3 常引用

常引用(const reference)是指在声明引用时使用 const 关键字,以表明引用的目标对象在引用生命周期内不可通过别名修改。

#include <iostream>int main() {int a = 10;const int& b = a; // 常引用std::cout << "a: " << a << std::endl;std::cout << "b: " << b << std::endl;//a:10//b:10// 尝试修改 b 的值(这会导致编译错误)// b = 20;// 修改原始变量 a 的值a = 30;std::cout << "a: " << a << std::endl;std::cout << "b: " << b << std::endl;//a:30//b:30return 0;
}

另外,对常量的常引用时合法的,但对常量的引用不合法

//可以访问常量的值,但不能通过 a 来修改这个值
const int& b = 10;
//int& b = 10; 不合法

5.4 引用的使用场景

  1. 传递函数参数: 通过引用传递参数,可以避免传递大型对象时的复制开销,同时允许在函数内部修改传入的变量。常引用用于确保在函数内部不能修改传入的值。

    void modifyValue(int& value) {value *= 2;
    }int main() {int num = 5;modifyValue(num);// num 在此处被修改为 10return 0;
    }
    
  2. 返回引用: 函数可以返回引用,允许对函数返回值进行修改。这在实现链式调用等情况下很有用。

    int array[5] = {1, 2, 3, 4, 5};int& getElement(int index) {return array[index];
    }int main() {getElement(2) = 10;// array[2] 在此处被修改为 10return 0;
    }
    

    这里数组是全局的,因此在getElement返回值时,数组元素并没有被销毁,因此 array[2] 能被成功修改

    如果是以下的这种情况,变量c 随函数栈帧的销毁也被收回空间,那么这个时候返回c的引用就是无效的,其返回的值是随机值

    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;
    }
    

    在这里插入图片描述


5.5 引用和指针的区别

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。

    • 引用提供了一种直观的别名机制,不需要显式解引用。
    • 指针存储变量地址,需要通过解引用操作符 * 才能访问目标对象。
  2. 引用在定义时必须初始化,指针没有要求。

    • 引用在创建时必须初始化,并且一旦与某个对象关联,就不能再引用其他对象。
    • 指针可以在声明后进行初始化,也可以在后续重新指向其他对象。
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体。

    • 引用在创建后与某个实体绑定,无法再引用其他实体。
    • 指针可以在运行时指向不同的对象。
  4. 没有NULL引用,但有NULL指针。

    • 引用不能为NULL,必须在初始化时指向一个有效的对象。
    • 指针可以为空,即指向 nullptrNULL
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)。

    • sizeof 运算符对引用返回引用类型的大小。
    • sizeof 运算符对指针返回指针所占的字节大小,通常与地址空间的大小相关。
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小。

    • 引用自增是对引用的实体进行加法操作。
    • 指针自增是将指针指向的地址向后移动一个类型的大小。
  7. 有多级指针,但是没有多级引用。

    • C++ 支持多级指针,可以有 int**int*** 等形式。
    • 没有多级引用的概念,引用通常是单层的。
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理。

    • 引用在使用时无需显式解引用,直接使用引用即可。
    • 指针需要通过解引用操作符 * 显式访问目标对象。
  9. 引用比指针使用起来相对更安全。

    • 引用在使用时更为直观,编译器会在一定程度上确保引用的合法性。
    • 指针可能引发空指针、野指针等问题,需要小心管理。

六、内联函数

6.1 概念

内联函数是C++中的一种编译器优化手段,它通过将函数的定义嵌入到调用该函数的地方,而不是通过传统的函数调用机制,以提高程序的执行效率。

使用关键字 inline 来告诉编译器希望将函数内联展开。在函数定义或声明前加上 inline 关键字即可。

inline int add(int a, int b) {return a + b;
}int main() {int a = 0;int b = 1;cout << "a+b=" << add(a, b) << endl;return 0;
}

6.2 内联函数的特性

  1. 适用于短小的函数: 内联函数适用于函数体较短小的情况,因为内联的目的是减少函数调用的开销,而将大型函数内联可能会导致代码膨胀(函数被内联展开,那么在每个调用点都会生成一份该函数的代码,增加代码的体积,可能导致更大的可执行文件)。

  2. 编译器决定内联: 使用 inline 关键字只是向编译器发出一个建议,最终是否内联取决于编译器的决策。通常,编译器会根据函数的复杂性和调用频率等因素来判断是否进行内联。
    一般来说,将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰

  3. 头文件中定义内联函数: 通常,内联函数的定义会放在头文件中,以便在多个源文件中进行内联展开。

    // header.h
    inline int add(int a, int b) {return a + b;
    }
    
    // main.cpp
    #include "header.h"int main() {int result = add(3, 4);  // 内联展开return 0;
    }
    

七、auto关键字(C++11)

7.1 概念

auto 是C++11引入的关键字,用于在声明变量时由编译器自动推导变量的类型。使用 auto 可以简化代码,特别是在涉及复杂的类型或使用模板时。以下是关于 auto 的一些关键点:

  1. 自动类型推导: auto 关键字可以用于声明变量,让编译器自动推导变量的类型。编译器在编译时会根据变量的初始化表达式推断其类型。

    auto x = 10;         // x 的类型将被推断为 int
    auto y = 3.14;       // y 的类型将被推断为 double
    auto z = "Hello";    // z 的类型将被推断为 const char[6]
    
  2. 适用于各种类型: auto 可以用于推导各种类型,包括基本数据类型、复合类型、指针、引用等。

    auto i = 42;               // int
    auto f = 3.14f;            // float
    auto ptr = new int(5);     // int*
    auto& ref = i;             // int&
    

7.2 使用规则

  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. 在同一行定义多个变量: 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

    auto a = 1, b = 2; 
    auto c = 3, d = 4.0;  // 该行代码会编译失败,因为c和d的初始化表达式类型不同
    
  3. 不能作为函数的参数类型: 函数参数的类型必须在编译时确定,而 auto 是用来进行类型推导的,无法在函数参数中使用。在函数参数中,必须显式指定参数的类型。

    void myFunction(auto x) {  // 错误,auto 不能用作函数参数类型// 函数体
    }
    
  4. 不能直接用来声明数组: 在数组声明中,编译器需要知道数组的元素类型和大小,而 auto 无法提供这些信息。因此,直接使用 auto 来声明数组是不允许的。

    auto myArray[] = {1, 2, 3};  // 错误,auto 不能直接用于数组声明
    

7.3 用于for循环(C++11)

auto 用于范围-based for 循环时,它会自动推导迭代变量的类型,并且可以遍历容器中的元素,使代码更加简洁。以下是使用 auto 的范围-based for 循环的示例:

auto 自动推导出 num 的类型,而 for 循环会遍历 numbers 容器中的每个元素,并将元素的值赋给 num

#include <iostream>
#include <vector>int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 使用 auto 和范围-based for 循环遍历容器中的元素for (auto num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

在这里插入图片描述


八、指针空值nullptr(C++11)

nullptr 是 C++11 引入的空指针常量,用于代替传统的空指针值 NULL。nullptr 具有更强的类型安全性。

在传统的C头文件(stddef.h)中,可以看到如下代码:
NULL 实际上是一个宏,通常被定义为 0 或 (void*)0。

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

示例:

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

在这里插入图片描述

程序本意是想通过f(NULL)调用指针版本的f(int* a)函数,但是由于NULL被定义成0,因此与程序的
初衷相悖。
在C++98中,编译器默认情况下将其NULL看成是一个整形常量0。当我们使用NULL调用f(int* a)时必须强转类型 (int*)NULL。而nullptr 明确表示空指针


在这里插入图片描述
如果你喜欢这篇文章,点赞👍+评论+关注⭐️哦!
欢迎大家提出疑问,以及不同的见解。

相关文章:

【C++】入门(二)

前言&#xff1a; c基础语法&#xff08;下&#xff09; 文章目录 五、引用5.1 引用概念5.2 引用使用规则5.3 常引用5.4 引用的使用场景5.5 引用和指针的区别 六、内联函数6.1 概念6.2 内联函数的特性 七、auto关键字&#xff08;C11&#xff09;7.1 概念7.2 使用规则7.3 用于f…...

Nginx 代理服务路径带/和不带/的问题

nginx初始配置如下 server {listen 6087;location / {#网站主页路径。此路径仅供参考&#xff0c;具体请您按照实际目录操作。#例如&#xff0c;您的网站运行目录在/etc/www下&#xff0c;则填写/etc/www。#允许跨域请求的域&#xff0c;* 代表所有add_header Access-Control-…...

C# CefSharp 输入内容,点击按钮,并且滑动。

前言 帮别人敲了个Demo,抱试一试心态&#xff0c;居然成功了&#xff0c;可以用。给小伙伴们看看效果。 遇到问题 1&#xff0c;input输入value失败&#xff0c;里面要套了个事件&#xff0c;再变换输入value。后来用浏览器开发工具&#xff0c;研究js代码&#xff0c;太难了&a…...

历经15年,比特币以强势姿态进军华尔街!270亿美元投资狂潮引发市场震荡!

本月&#xff0c;比特币庆祝了它的15岁生日&#xff0c;并以强势的姿态进军华尔街。最近美国交易所开始交易的比特币交易所交易基金&#xff08;ETF&#xff09;&#xff0c;已经获得了投资者的广泛接受。这一进展标志着比特币作为一种年轻资产迈向成熟的重要里程碑。 根据Glas…...

GBASE南大通用的接口程序GBase ADO.NET

GBase ADO.NET 是一个提供.NET 应用程序与 GBase 数据库之间方便、高效、 安全交互的接口程序&#xff0c;使用 100%纯 C#编写&#xff0c;并继承了 Microsoft ADO.NET 类。 开发人员可以使用任何一种.NET 开发语言&#xff08;C#、VB.NET、F#&#xff09;通过 GBase ADO.NET 操…...

算法训练营Day57(回文子串--总结DP)

647. 回文子串 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int countSubstrings(String s) {int len s.length();//i到j这个子串是否是回文的boolean [][] dp new boolean[len][len];int res 0;for(int i len-1;i>0;i--){for(int …...

使用OpenCV从一个矩阵提取子矩阵

介绍opencv的两个函数&#xff1a;Range()和Rect() Range()是用于表示一个范围的类。它的构造函数有两个整数参数&#xff0c;分别表示范围的起始和终止索引。这个范围包括起始索引但不包括终止索引。 cv::Range(int start, int end); /* 在OpenCV中&#xff0c;cv::Range() …...

微信云托管:基本使用指南

微信云托管 &#x1f6a8;推荐&#xff1a;微信云托管&#xff1a;基本使用指南 确实是个好平台&#xff0c;部署个项目很简易&#xff0c;免去了很多运维上的事情。 一、微信云托管 github 流水线配置 和 端口号 首先&#xff0c;这里的主体(宿主机)&#xff0c;指的就是你的…...

WEB前端IDE的使用以及CSS的应用

IDE的使用 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, i…...

python中排序函数sorted的简单运用

# 假设a里面的()分别对应的x,y,w,h 即 (x,y,w,h) a [(2,3,1,2),(4,1,2,2),(1,6,2,1)] # a:传入的列表 # key 排序的数据 keylambda x:x[n] 是固定写法,里面的n代表你按照()中第几个数据的值排序 # eg&#xff1a;我们这里是x:x[0]表示我们按x排序, 如果改成x:x[1]则按y排序 # …...

k8s的helm

1、在没有helm之前&#xff0c;部署deployment、service、ingress等等 2、helm的作用&#xff1a;通过打包的方式&#xff0c;deployment、service、ingress这些打包在一块&#xff0c;一键部署服务、类似于yum功能 3、helm&#xff1a;官方提供的一种类似于仓库的功能&#…...

[MySQL]基础的增删改查

目录 1.前置介绍 2.数据库操作 2.1显示当前数据库 2.2创建数据库 2.3 使用数据库 2.4 删除数据库 3.常用数据类型 3.1整型和浮点型 3.2字符串类型 4.表的操作 4.1查看表结构 4.2创建表 4.3删除表 5.重点 5.1操作数据库 5.2常用数据类型 5.3操作表 1.前置介绍 …...

简易播放器 以及触发的异常

jl 1.0.jar 架包导入步骤&#xff1a; 1.读取到MP3音频文件 2.创建播放器对象,传入音频文件 3.开始播放 package com.ztt.Demo01;import java.io.FileInputStream; import java.io.FileNotFoundException;import javazoom.jl.decoder.JavaLayerException; import javazoom.jl.…...

【Flutter跨平台插件开发】如何实现kotlin跟C++的相互调用

【Flutter跨平台插件开发】如何实现kotlin跟C的相互调用 kotlin 调 c 在 Kotlin 中&#xff0c;可以使用 JNI (Java Native Interface) 来调用 C 代码 调用步骤: 创建 C 文件并实现函数。 // example.cpp #include <jni.h>extern "C" JNIEXPORT jstring J…...

Apache SeaTunnel社区荣获“2023快速成长开源项目”奖项

在这个开源理念推动技术创新和全球协同发展的时代&#xff0c;SeaTunnel社区在开放原子开源基金会举办的2023年开源项目评选中脱颖而出&#xff0c;荣获“2023快速成长开源项目”殊荣。 这个奖项不仅仅是对Apache SeaTunnel社区过去一年发展速度和质量的认可&#xff0c;更是对…...

Unity 桥接模式(实例详解)

文章目录 示例1&#xff1a;角色与装备系统示例2&#xff1a;UI控件库示例3&#xff1a;渲染引擎模块示例4&#xff1a;AI决策树算法示例5&#xff1a;物理模拟引擎 在Unity游戏开发中&#xff0c;桥接模式&#xff08;Bridge Pattern&#xff09;是一种设计模式&#xff0c;它…...

Xftp连接不上Linux虚拟机的原因解决方法

前言&#xff1a; 在当今数字化时代&#xff0c;远程连接到Linux虚拟机是许多开发者和系统管理员日常工作的一部分。然而&#xff0c;有时候&#xff0c;面对Xftp连接不上Linux虚拟机的问题&#xff0c;我们可能感到困惑和无措。这个看似小问题可能导致工作中断&#xff0c;因…...

代码随想录刷题笔记 DAY12 | 二叉树的理论基础 | 二叉树的三种递归遍历 | 二叉树的非递归遍历 | 二叉树的广度优先搜索

Day 12 01. 二叉树的理论基础 1.1 二叉树的种类 满二叉树&#xff1a;除了叶子节点以外&#xff0c;每个节点都有两个子节点&#xff0c;整个树是被完全填满的完全二叉树&#xff1a;除了底层以外&#xff0c;其他部分是满的&#xff0c;底部可以不是满的但是必须是从左到右连…...

Linux问题 apt-get install时 无法解析域名“cn.archive.ubuntu.com”

问题描述: 在安装程序时会出现无法解析域名的错误 解决办法: 1、编辑文件 sudo vim /etc/resolv.conf 2、在最后加上(按键 i 进入编辑模式) nameserver 8.8.8.8 3、保存退出(:wq)...

蓝桥--鸡哥的购物挑战OJ(4169)

题目&#xff1a; 思路&#xff1a; 暴力&#xff1a; 直接枚举所有得偶数区间&#xff0c;找最大值&#xff0c;n2超时 优化&#xff1a; 分类讨论&#xff0c;只要醉倒不重不漏得分类不出意外就能AC了 图中的选择方式很简单了&#xff0c;不做解释了。 AC代码(我的代码可…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里

写一个shell脚本&#xff0c;把局域网内&#xff0c;把能ping通的IP和不能ping通的IP分类&#xff0c;并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...

动态规划-1035.不相交的线-力扣(LeetCode)

一、题目解析 光看题目要求和例图&#xff0c;感觉这题好麻烦&#xff0c;直线不能相交啊&#xff0c;每个数字只属于一条连线啊等等&#xff0c;但我们结合题目所给的信息和例图的内容&#xff0c;这不就是最长公共子序列吗&#xff1f;&#xff0c;我们把最长公共子序列连线起…...