【C++】基础入门(详解)

🌟 Hello,我是egoist2023!

🌍 种一棵树最好是十年前,其次是现在!

目录

输入&输出

缺省参数(默认参数)

函数重载

引用

概念及定义

特性及使用

const引用

与指针的关系

内联inline和nullptr

inline

nullptr


输入&输出

前文了解到本贾尼认为C语言是有缺陷的,想弥补其缺陷,最后搞出自己的一套C++体系。其实,C语言的scanf和printf函数是有缺陷且过于冗杂(每次都需要手动指定格式),是否能通过一种方式使输入输出更简便呢?针对此问题在C++中引入了输入&输出流

  • <iostream> (全称: Input Output Stream )是标准的输入、输出流库,定义了标准的输入、输出对象。
  • std::cin 是 istream 类的对象,它主要面向窄字符的标准输入。(C++标准库都封在std的命名空间中)
  • std::cout 是 ostream 类的对象,它主要面向窄字符的标准输出流
  • std::endl 是⼀个函数,流插入输出时,相当于插入一个换行字符加刷新缓冲区(简单看成C语言中的\n)。
  • <<是流插入运算符,>>是流提取运算符。(在C语言还充当左移/右移位运算符)。
  • 输入输出可以自动识别变量类型(本质是通过函数重载实现的),最重要的是 C++的流能更好的支持自定义类型对象的输入输出。
#include<iostream>
#include<stdio.h>int main()
{int a = 1;std::cout << a;printf("%d", a);return 0;
}
  • IO流涉及类和对象,运算符重载、继承等很多面向对象的知识,因此在此章节只介绍IO流的用法。
  • 在vs编译器中<iostream>间接包含了<stdio.h>,因此可以使用printf。
#include<iostream>int main()
{int a = 1;std::cout << a;printf("%d", a);return 0;
}

缺省参数(默认参数)

  • 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参采用该形参的缺省值

  • 缺省参数分为全缺省(全部形参给缺省值)和半缺省参数(部分形参给缺省值)。
  • C++规定半缺省参数必须从左往右依次连续缺省,不能间隔给缺省值。(同理依次给实参)
  • 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。(这样做的目的是避免冲突,因为编译器在链接时会合成制表符,此时,声明和定义都有缺省值就会产生冲突)

  • 缺省参数的意义远不止如此,在之前的栈和队列章节中,栈的初始化中capacity默认开始为0。若一开始明确插入1000个数据时,初始化时直接开好,避免多次扩容损失效率。(没有传参时会采用缺省参数的值。)

函数重载

在C语言中若要实现Add函数(需要支持整形、浮点型相加)时,需要保证Add函数名字不冲突,为了解决这一困扰。在C++中,添加了函数重载这个概念,其要求这些同名函数的形参不同,可以是参数个数不同或者类型不同(不支持返回类型不同),呈现多态行为,使用更加方便。函数支持三种类型的重载。

函数重载是C++中实现多态性的一种重要方式,具有重要意义(增强了代码的可读性,函数的通用性和复用性),同时为之后的模板(函数重载的支持)、运算符重载做了铺垫。

参数类型不同

int Add(int x, int y)
{cout << "int Add(int x, int y)" << endl;return x + y;
}double Add(double x, double y)
{cout << "double Add(double x, double y)" << endl;return x + y;
}

参数个数不同

void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}

参数顺序不同

void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}

引用

概念及定义

引用是给已存在变量取一个别名,语法层面上编译器不会为其开辟内存空间, 它和引用的变量共用同一块内存空间。(实际底层实现上开辟了空间,是用一个指针指向其引用的变量)
通过调试可以知道:别名和引用的变量指向 共同占用一块空间
反汇编观察 底层:a和b各自开了一块空间,b通过指针ptr指向了变量a

特性及使用

引用在定义时 必须初始化
支持多次引用
引用一个实体,其别名再不能引用其他实体
  • 实践中,引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被引用对象。
  • 使用C++引用替代指针传参,目的是简化程序,避开复杂的指针。
  • 引用传参和引用作返回值在实践中经常用到,达到了减少拷贝提高效率(指针也可以减少拷贝)和改变引用对象的目的。(针对自定义类型更为明显)

在指针章节中要求交换两个变量,涉及到传址调用(形参改变实参)。同样,使用引用也可以达到此目的。

const引用

变量也有被const修饰的情况,此时对其进行引用会报错(权限被放大了),因此需要引入 const引用。

权限要点  -- >  权限可以平移或者缩小,但一定不能放大。

  • 引用一个const对象,必须用const引用。const引用也可以引用普通对象,因为对象的访问权限可以缩小,不能放大。

  • 需要注意的是 int& rb = a*3; double d = 12.34; int& rd = d 这种场景下需要使用const引用

这里涉及到类型转换,将double转换为int&为何需要使用const引用呢?

在类型转换中,会产生临时对象(也称未命名对象),这个对象具有常性,此时rb和rd都是引用这个临时变量,权限被放大了,因此会出现报错

  •  临时对象是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象。

与指针的关系

由上文可以发现引用与指针的部分功能是类似的,那为什么本贾尼还引入了引用这个语法呢?

引⽤和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。如:C++引⽤定义后不能改变指向,相反地指针可以改变指向(链表章节中指针定义的结构是不能用引用替代的)。

引用与指针的关系
引用指针
语法上不开空间要开空间存储变量地址
必须初始化非必须初始化
不能改变指向可以改变指向
可以直接访问指向对象需要借助*访问指向对象
引用结果为引用类型大小看32位/64位平台
\野指针和空指针问题

内联inline和nullptr

inline

inline修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就需要建立栈帧了,就可以提高效率。
这个功能是和C语言中的define是类似的,inline又有什么优势呢?
宏函数实现很复杂很容易出错的,且不方调试,C++设计了inline目的就是替代C的宏函数。

#define Add(x,y) ((x)+(y))

inline int Add(const int& x, const int& y)
{
    return x + y;
}

在实现Add函数中使用define宏定义时需要考虑各种因素,而使用inline则无需顾虑很多,让编译器决定是否展开此函数。

  • inline对于编译器是一个建议(选择性展开),适用频繁调用的短小函数,对于递归函数,代码相对多一些的函数,加上inline也会被编译器忽略。
  • inline不建议声明和定义分离到两个文件 ,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错(不能合成制表符)。
  • vs编译器 debug版本下面默认是不展开inline的,因此需要设置下。

nullptr

引入nullptr实际是为了替代C语言的NULL(有缺陷)。

NULL实际是一个宏,在头文件(stddef.h)中。

#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif
C++中NULL可能被定义为 常量0 ,或者C中被定义为 无类型指针(void*) 的常量。但都不可避免的会遇到一些麻烦。
nullptr(关键字)是⼀种特殊类型的字面量,它可以转换成任意其他类型的指针类型。使用 nullptr定义空指针可以避免类型转换 的问题。(nullptr只能被隐式地转换为指针类型,而不能被转换为整数类型)
在此代码中,本想通过f(NULL)调用函数f(int x),但运行后发现调用的f(int x)函数,与设计此程序是相违反的。

若NULL为无类型指针(void*)呢?运行后会报错,这是因为2个函数重载中没有一个能转换所有参数类型。
#include<iostream>
using namespace std;void f(int x)
{cout << "f(int x)" << endl;
}void f(int* ptr)
{cout << "f(int* ptr)" << endl;
}int main()
{f(NULL);//调用f(int x)f(nullptr);//调用f(int* ptr)f((void*)0);//errreturn 0;
}

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

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

相关文章

【2025最新版】软件测试面试题总结(150道题含答案解析)

接口测试面试题 1&#xff1a;你平常做接口测试的过程中发现过哪些 bug? 2&#xff1a;平常你是怎么测试接口的&#xff1f; 3&#xff1a;平常用什么工具测接口? 4: webService 接口是如何测试的? 5&#xff1a;没有接口文档&#xff0c;如何做接口测试&#xff1f; 6&…

使用EVE-NE-锐捷实现NAT+ACL服务限制

一、项目拓扑 二、项目实现 1.NET配置 点击左侧的NetWorks,设置与图相同的配置&#xff0c;实现实验环境桥接到物理网络 2.GW配置 进入特权模式 enable进入全局模式 configure terminal 更改名称为GW hostname GW进入g0/0接口 interface g0/0将g0/0接口IP地址配置为192.168.…

nginx 实战配置

一、配置一个默认80端口的&#xff0c;静态页面&#xff0c;路径是path1。 http://192.168.0.111/path1 &#xff0c; /path1路径指向linux的/data/index1.html vi /data/nginx-1.24.0/conf/nginx.conf 文件添加以下配置 location /path1 { alias /data/…

kubekey一键部署k8s高可用与kubesphere

kubekey一键安装k8s与kubesphere还是蛮方便的&#xff0c;kubesphere官网上面也提到了高可用安装的一些事宜&#xff0c;但是没有涉及到kubesphere资深的redis的系统的部署问题&#xff0c;本文简单给出对应配置&#xff0c;其实这个配置在kubephere的cluster-configuration.ya…

怎么使用服务器运行pySCENIC

前言 我们注意到在其他的一些论坛&#xff0c;有一些用户反馈&#xff0c;在服务器上面运行pyscenic不太顺畅。本文我们整理了在服务器上运行pyscenic的三个方法供大家参考&#xff0c;分别是conda安装pyscenic运行、arboreto_with_multiprocessing运行、容器化运行。总的来说&…

QEMU 搭建arm linux开发环境

Qemu 作为一款强大的开源虚拟化软件&#xff0c;为我们提供了一个便捷且经济实惠的方式来模拟各种硬件环境&#xff0c;从而在上面安装和学习 Linux 系统。本文将详细介绍如何使用 Qemu 搭建 Linux 学习环境&#xff0c; 环境准备 操作系统&#xff1a;建议使用 Ubuntu 20.04…

坐井说天阔---DeepSeek-R1

前言 DeepSeek-R1这么火&#xff0c;虽然网上很多介绍和解读&#xff0c;但听人家的总不如自己去看看原论文。于是花了大概一周的时间&#xff0c;下班后有进入了研究生的状态---读论文。 DeepSeek这次的目标是探索在没有任何监督数据的情况下训练具有推理能力的大模型&#…

EasyExcel 复杂填充

EasyExcel ​Excel表格中用{}或者{.} 来表示包裹要填充的变量&#xff0c;如果单元格文本中本来就有{、}左右大括号&#xff0c;需要在括号前面使用斜杠转义\{ 、\}。 ​代码中被填充数据的实体对象的成员变量名或被填充map集合的key需要和Excel中被{}包裹的变量名称一致。 …

华为防火墙pppoe拨号接入互联网配置案例

目录 1.pppoe拨号背景2.网络拓扑3.网络需求4.网络配置4.1 网络基础配置4.2 pppoe配置4.2.1 pppoe服务端配置(现网环境可忽略)4.2.2 pppoe客户端配置4.2.3 结果验证 5.小结 1.pppoe拨号背景 PPPoE&#xff08;Point-to-Point Protocol Over Ethernet&#xff09;拨号产生的背景…

认识vue-admin

认识vue-admin **核心交付:** 为什么要基于现成架子二次开发 什么是二次开发&#xff1a;基于已有的代码&#xff08;项目工程&#xff0c;脚手架&#xff09;开进行新功能的开发 所以看懂已有的框架中的既有代码&#xff0c;变得很重要了 1. 背景知识 后台管理系统是一种最…

【16】思科AireOS:创建使用 LWA 认证的 WLAN

1. 概述 LWA(Local Web Authentication)是一种基于 Web 认证的方式,允许无线客户端在连接 WLAN 后,使用 Web 认证页面进行身份验证。该方法适用于访客网络或需要身份认证的场景。 本指南详细介绍如何在 Cisco AireOS 无线控制器(WLC)上配置 LWA 认证的 WLAN,并确保认证…

电解电容的参数指标

容量 这个值通常是室温25℃&#xff0c;在一定频率和幅度的交流信号下测得的容量。容量会随着温度、直流电压、交流电压值的变化而改变。 额定电压 施加在电容上的最大直流电压&#xff0c;通常要求降额使用。 例如额定电压是4V&#xff0c;降额到70%使用&#xff0c;最高施…

【C++】IO流

目录 一、C语言的输入与输出二、流是什么三、CIO流3.1 C标准IO流3.2 C文件IO流3.2.1 二进制读写3.2.2 文本读写 四、stringstream的简单介绍结尾 一、C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键盘)读取数据…

软件开发 | GitHub企业版常见问题解读

什么是GitHub企业版&#xff1f; GitHub企业版是一个企业级软件开发平台&#xff0c;专为现代化开发的复杂工作流程而设计。 作为可扩展的平台解决方案&#xff0c;GitHub企业版使组织能够无缝集成其他工具和功能&#xff0c;并根据特定需求定制开发环境&#xff0c;提高整体…

红黑树:高效平衡二叉树的奥秘

&#x1f31f; 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。&#x1f31f; 引言 在数据结构的奇妙世界里&#x1f9d0;&#xff0c;二叉搜索树就像一把神奇的钥匙&#xff0c;能高效地查找数据。但这把钥匙也…

[免费]SpringBoot公益众筹爱心捐赠系统【论文+源码+SQL脚本】

大家好&#xff0c;我是老师&#xff0c;看到一个不错的SpringBoot公益众筹爱心捐赠系统&#xff0c;分享下哈。 项目介绍 公益捐助平台的发展背景可以追溯到几十年前&#xff0c;当时人们已经开始通过各种渠道进行公益捐助。随着互联网的普及&#xff0c;本文旨在探讨公益事业…

【设计模式】03-理解常见设计模式-行为型模式(专栏完结)

前言 前面我们介绍完创建型模式和创建型模式&#xff0c;这篇介绍最后的行为型模式&#xff0c;也是【设计模式】专栏的最后一篇。 一、概述 行为型模式主要用于处理对象之间的交互和职责分配&#xff0c;以实现更灵活的行为和更好的协作。 二、常见的行为型模式 1、观察者模…

DeepSeek 助力 Vue 开发:打造丝滑的卡片(Card)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

基于单片机的开关电源设计(论文+源码)

本次基于单片机的开关电源节能控制系统的设计中&#xff0c;在功能上设计如下&#xff1a; &#xff08;1&#xff09;系统输入220V&#xff1b; &#xff08;2&#xff09;系统.输出0-12V可调&#xff0c;步进0.1V; &#xff08;3&#xff09;LCD液晶显示实时电压&#xff…

SpringBoot(7)-Swagger

目录 一、是什么 二、SpringBoot集成Swagger 三、配置Swagger 3.1 配置文档信息 3.2 配置扫描接口 3.3 配置Swagger开关 3.4 配置API分组 3.5 实体配置 四、常用注解 五、总结 一、是什么 是一款API框架&#xff0c;API文档和API定义同步更新&#xff0c;可以在线测…