当前位置: 首页 > 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;企业对高效、灵活且可扩展的网络架构需求愈发迫切。随着数据流量的…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...