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

C/C++(二)C++入门基础

这一章会介绍C++入门必须掌握的一些基础概念

一、函数重载

1、什么是函数重载?

函数重载是C++相比于C语言的一个重大改进。

C++允许在同一作用域内声明多个功能类似的同名函数,这些函数的参数类型 / 个数 / 类型顺序不同。(注:返回值不同不能构成重载,这是由后文会介绍的函数名修饰规则所决定)

2、C++如何支持函数重载的?(Linux g++编译器环境下)

在C/C++(一)中介绍了,在C / C++中,想要形成一个可执行程序,必须经历 预处理 --> 编译 --> 汇编 --> 链接 四个阶段。

在编译阶段,g++ 编译器会根据其函数名修饰规则(_Z + 函数长度 + 函数名 + 函数参数类型的首字母)(可以发现,修饰规则中没有返回值,因此返回值不同,不能构成函数重载)对函数进行修饰,根据其规则可以看出,函数参数不同,实际上在编译阶段会被修饰成不同的函数这也就是C++支持函数重载的根基。

示例代码:

#include <iostream>
using namespace std;int add(int x, int y)
{return x + y;
}
int add(int x, int y, int z)
{return x + y + z;
}
int main()
{int res1 = add(1, 2);int res2 = add(1, 2, 3);
}

3、为什么C语言不支持函数重载,C++支持? 

因为C语言的编译器的函数名修饰规则并不会修饰函数名,而是按照原先函数名。 

二、引用和指针

1、什么是引用?

引用是给已经存在的变量取别名, 编译器不会为引用开辟空间,引用和其引用的变量共用同一块内存空间

使用格式
 

类型& 引用变量名(对象名) = 引用实体

1.1  有关引用的一些注意事项

1、& 跟在类型和变量名之间,叫做引用。否则,叫做取地址。

2、引用必须在定义时就初始化。

3、一个变量可以有多个引用,引用本身也可以有引用。

4、引用一旦引用了一个实体,就不能再引用其它实体。

5、非常量应用不能绑定到常量对象 / 临时常量对象 /不同类型的对象;常量引用可以绑定到        常量对象、临时常量对象或不同类型的对象(需要显式类型转换)

1.2  常引用(常量引用 / const 引用)

常引用是引用的一种特殊形态,允许引用一个对象,可以绑定到常量对象 / 临时常量对象 / 不同类型的对象(需要显式类型转换),但是不能通过该引用修改对象的值,主要用途是提高代码的安全性和可读性。

示例代码:

void TestConstRef()
{const int a = 10;// int& ra = a;       // 该语句编译时会出错,a为常量,普通引用不能绑定常量对象const int& ra = a;    // 正确方法// int& b = 10;       // 该语句编译时会出错,10为临时常量,const int& b = 10;    // 正确方法double d = 12.34;//int& rd = d;        // 该语句编译时会出错,类型不匹配(具体原因是由于类型转换时会产生临时变 // 量,而临时变量具有常性造成无法引用)const int& rd = static_cast<int>(d);    // 正确方法1double& rd = d                          // 正确方法2
}

2、指针和引用的区别(用法 + 底层原理)

1、引用是定义一个变量的别名,与这个变量共用同一内存空间,大小也与这个变量的大小          相同;而指针存储的是变量的地址,需要额外占用一小段空间储存,大小也始终是指针          的大小。(32位下是4字节、64位下是8字节)

2、引用必须在声明的时候就进行初始化,不能为空,并且一旦初始化就不能改变引用的对          象(因为要让编译器知道,引用总是指向这个有效的对象,以便生成更高效的代码,              直接访问目标变量的内存地址,而不需要额外的解引用操作);指针由于通过解引用显          式访问变量,所以可以在声明的时候不初始化,也可以随时改变指向的对象。

3、引用++就相当于其引用的变量++;指针则是指针指向下一个内存地址。

4、引用访问绑定的实体,直接访问,由编译器来优化而指针需要解引用。

5、因为引用不能为空 + 编译器优化,引用比指针更安全。

3、引用的两大使用场景 

三、宏的替代方案

宏作为从C语言继承而来的概念(C / C++(一)中有详细介绍),其有着一定的优点(代码复用性强;可以提高性能),但是其缺点更多(由于预编译阶段进行了替换,宏不方便调试;代码的可读性较差,可维护性也不好,还容易误用;也没有类型安全的检查)

所以C++提供了三种用来替代宏的方案

替代宏定义标识符:const变量 / enum枚举

替代宏函数:inline内联函数

1、const变量替代宏定义标识符

// 宏定义标识符
#define PI 3.14159// const变量定义
const double PI = 3.14159;

优点:

1、类型安全const 变量具有明确的类型,编译器可以进行类型检查,避免类型错误。

2、调试友好const 变量在调试器中可以显示其值和类型,便于调试。

3、作用域控制const 变量可以有局部作用域,而宏定义在整个文件范围内有效,容易引起                             命名冲突。

2、enum枚举替代宏定义标识符

// 宏定义标识符
#define RED 0
#define GREEN 1
#define BLUE 2// 枚举定义标识符
enum Color 
{RED,GREEN,BLUE
};

优点:

1、类型安全enum 类型的变量只能取枚举值,方便编译器进行类型检查。

2、语义清晰enum 明确表示一组相关的常量,代码更具可读性。

3、范围限制:枚举值在编译时有固定的范围,避免了非法值的赋值。

3、inline 内联函数替代宏函数

3.1  什么是内联函数?

以 inline 关键字修饰的函数叫做内联函数,

特性:在编译的时候,C++编译器会在调用内联函数的地方直接用函数体替换,没有调用普             通函数需要建立栈帧的额外开销,可以提升程序运行的效率

缺点:以空间换时间,可能会导致目标文件变大。(因此,内联 inline 关键字实际上只是向             编译器发出的一个内联请求,编译器会自己决定是否把这个函数设置为内联函数,如            果函数过长,编译器将忽略内联请求)

使用建议:

1、函数规模较小、不是递归,调用不频繁的函数,可以采用 inline 内联修饰;其它                      的不建议;

2、同时也不建议内联函数的声明与定义分离,因为分离了,每个cpp文件里都会有内联函数        的内联展开,链接器会发现不同的对象文件中都有这个内联函数的定义。无法确定应该          使用哪个定义,导致多重定义错误。(如果一定要使用,内联函数的声明和定义必须放           在同一个地方,通常是头文件中,确保每个编译单元都能看到完整的内联函数定义)

3.2  以内联函数替代宏函数

#define MAX(a, b) ((a) > (b) ? (a) : (b))

// #define 定义宏
#define MAX(a, b) ((a) > (b) ? (a) : (b))// inline内联函数代替宏函数
inline int max(int a, int b) 
{return (a > b) ? a : b;
}

优点:

1、类型安全inline 函数具有明确的参数类型和返回类型,编译器可以进行类型检查。

2、副作用避免:宏定义在参数计算上有潜在的副作用,而 inline 函数没有这个问题。

3、调试友好inline 函数在调试器中可以显示调用栈和局部变量,而宏定义则不行。

4、代码可读性inline 函数的代码更具可读性和可维护性。

四、新的空指针表示方式:nullptr

nullptr是C++11引入的一种新的空指针表示方式在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。

在传统的C语言 / C++98标准中,空指针的表示方式一般是NULL,而NULL的定义存在缺陷

NULL的缺陷

NULL在在 C++ 中,通常定义为 0 或 (void*)0,这可能导致一些意外的行为

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。

nullptr的优势

1、类型安全nullptr 是一个类型,避免了与整数类型的隐式转换。

2、更好的可读性nullptr 明确表示这是一个空指针,且不需要包含其它头文件。

3、兼容性更好nullptr 可以更好地与模板一起使用。

4、避免宏定义的问题nullptr 是一个关键字,不会受到宏定义的影响。

5、支持 nullptr 类型的检查:可以使用 std::nullptr_t 类型进行类型检查。

因此为了提高代码的健壮性,在后续表示指针空值时建议最好使用 nullptr。

相关文章:

C/C++(二)C++入门基础

这一章会介绍C入门必须掌握的一些基础概念。 一、函数重载 1、什么是函数重载&#xff1f; 函数重载是C相比于C语言的一个重大改进。 即C允许在同一作用域内声明多个功能类似的同名函数&#xff0c;这些函数的参数类型 / 个数 / 类型顺序不同。&#xff08;注&#xff1a;返回…...

人工智能发展:一场从“被教导”到“自我成长”的奇妙冒险

说到人工智能&#xff08;AI&#xff09;&#xff0c;大家的第一反应往往是机器人、无人驾驶、或者那个让人害怕的AI会不会取代人类。其实&#xff0c;AI的进化过程简直像一部精彩的电影&#xff0c;有起伏、有高潮、有让人摸不着头脑的时刻。今天&#xff0c;我们就一起来“吃…...

企业级 RAG 全链路优化关键技术

本文根据2024云栖大会实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a; 邢少敏 | 阿里云智能集团高级技术专家 活动&#xff1a; 2024 云栖大会 - AI 搜索企业级 RAG 全链路优化关键技术 在2024云栖大会上&#xff0c;阿里云 AI 搜索研发负责人之一的…...

学习文档(5)

Redis应用 目录 Redis应用 Redis 除了做缓存&#xff0c;还能做什么&#xff1f; Redis 可以做消息队列么&#xff1f; Redis 可以做搜索引擎么&#xff1f; 如何基于 Redis 实现延时任务&#xff1f; Redis 除了做缓存&#xff0c;还能做什么&#xff1f; 分布式锁&…...

node.js下载安装以及环境配置超详细教程【Windows版本】

node安装以及环境变量配置 Step1&#xff1a;选择版本进行安装Step2&#xff1a;安装Node.jsStep3&#xff1a;环境配置Step4&#xff1a;检查node.js是否成功安装Step5&#xff1a;npm修改下载镜像 Step1&#xff1a;选择版本进行安装 Node.js 安装包及源码下载地址为 Node.…...

08_实现 reactive

目录 编写 reactive 的函数签名处理对象的其他行为拦截 in 操作符拦截 for...in 循环delete 操作符 处理边界新旧值发生变化时才触发依赖的情况处理从原型上继承属性的情况处理一个对象已经是代理对象的情况处理一个原始对象已经被代理过一次之后的情况 浅响应与深响应代理数组…...

finereport 中台 帆软 编码解码

帆软用的 post 方式编码不是用的 dict&#xff0c;而是二次 url 编码&#xff0c;需要二次解析 import time import urllib.parse import json# 原始字符串 encoded_string data "__parameters__%7B%22MANUFACTURER%22%3A%22%22%2C%22CATEGORY%22%3A%22%22%2C%22HHPN_L…...

Day15-数据库服务全面优化与PT工具应用

Day15-数据库服务全面优化与PT工具应用 1、数据库服务优化讲解1.2 数据库服务系统层面的优化1.3 数据库服务软件版本选择1.4 数据库服务结构参数优化1.4.1 数据库连接层优化1.4.2 数据库服务层优化1.4.3 数据库引擎层优化1.4.4 数据库复制相关优化1.4.5 数据库其他相关优化 1.5…...

开源限流组件分析(二):uber-go/ratelimit

文章目录 本系列漏桶限流算法uber的漏桶算法使用mutex版本数据结构获取令牌松弛量 atomic版本数据结构获取令牌测试漏桶的松弛量 总结 本系列 开源限流组件分析&#xff08;一&#xff09;&#xff1a;juju/ratelimit开源限流组件分析&#xff08;二&#xff09;&#xff1a;u…...

探索 SVG 创作新维度:svgwrite 库揭秘

文章目录 **探索 SVG 创作新维度&#xff1a;svgwrite 库揭秘**背景介绍库简介安装指南基础函数使用实战场景常见问题与解决方案总结 探索 SVG 创作新维度&#xff1a;svgwrite 库揭秘 背景介绍 在数字艺术和网页设计领域&#xff0c;SVG&#xff08;Scalable Vector Graphic…...

为什么要做PFAS测试?PFAS检测项目详细介绍

PFAS测试之所以重要&#xff0c;主要归因于PFAS&#xff08;全氟和多氟化合物&#xff09;的广泛存在、持久性、生物累积性和潜在的毒性。这些特性使得PFAS在环境和人体中可能长期存在&#xff0c;并对生态系统和人类健康构成威胁。以下是对PFAS检测项目的详细介绍以及进行PFAS…...

稀土阻燃协效剂的应用

稀土阻燃协效剂是一类利用稀土元素&#xff08;如铈、镧、钕、铕等&#xff09;具有的独特性质&#xff0c;来增强材料阻燃性能的化学物质。在聚合物材料燃烧时可催化酯花成碳&#xff0c;迅速在高分子表面形成致密连续的碳层&#xff0c;隔绝聚合物材料内部的可燃性气体与氮气…...

Java的异常处理

常见异常 ① 运行时异常 a、ClassNotFoundException b、FileNotFoundException c、IOException ② 编译时异常 a、ArrayIndexOutOfBoundsException b、NullPointerException c、ClassCastException d、InputFormatException e、InputMismatchException f、ArithmeticException …...

免费域名邮箱申请和使用教程:有哪些步骤?

免费域名邮箱设置指南&#xff1f;如何免费注册烽火域名邮箱&#xff1f; 对于个人和企业而言&#xff0c;拥有一个专属的域名邮箱不仅能提升专业形象&#xff0c;还能增强品牌识别度。烽火将详细介绍如何申请和使用免费域名邮箱&#xff0c;帮助您轻松拥有一个专属的电子邮件…...

Linux之实战命令45:swapon应用实例(七十九)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…...

提升数据处理效率:TDengine S3 的最佳实践与应用

在当今数据驱动的时代&#xff0c;如何高效地存储与处理海量数据成为了企业面临的一大挑战。为了解决这一问题&#xff0c;我们在 TDengine 3.2.2.0 首次发布了企业级功能 S3 存储。这一功能经历多个版本的迭代与完善后&#xff0c;逐渐发展成为一个全面和高效的解决方案。 S3…...

高级算法设计与分析 学习笔记13 线性规划

注意是线性规划不是动态规划哦 好家伙&#xff0c;这不是凸优化吗&#xff1f; 凸优化标准形式&#xff1a; 先改成统一最大化&#xff08;凸优化那边怎么是统一最小化&#xff1f;&#xff09; 原来的x2正负无所谓&#xff0c;但我希望每个x都是有限制的&#xff0c;所以把它改…...

2024年11月软考中项应试技巧与机考注意事项!

软考中项的备考技巧 重点来了&#xff01;这部分是我辛苦总结出来的备考技巧&#xff0c;都是我当年备考时逐渐整合出来的&#xff0c;绝对够用&#xff0c;赶紧跟我一起掌握吧&#xff01; 1.基础知识 在学习时建议大家先跟着班课老师结合教材过一遍基础知识。强调跟着班课…...

网络编程中容易踩的坑罗列,谨记!

1、TCP没考虑粘包分包 TCP是面向连接的可靠协议&#xff0c;TCP是流式协议&#xff0c;创建TCP套接字的类型为SOCK_STREAM int sockfd socket(AF_INET, SOCK_STREAM, 0);很多同学面试时对书上的话背诵如流&#xff0c;在实际TCP编程中却没有处理粘包和分包的代码&#xff0c;以…...

SD-WAN:推动企业网络优化与发展

近年来&#xff0c;软件定义广域网&#xff08;SD-WAN&#xff09;逐渐成为众多企业的首选网络解决方案。这背后的原因是什么&#xff1f;接下来我们将深入探讨这一趋势。 在快速发展的通信技术领域&#xff0c;企业对高效、灵活且可扩展的网络架构需求愈发迫切。随着数据流量的…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

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

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

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...