【C++初阶】C++入门相关知识(2):输入输出 & 缺省参数 & 函数重载

【C++初阶】C++入门相关知识(2):输入输出 & 缺省参数 & 函数重载

🎈主页传送门:良木生香

🔥个人专栏:《C语言》 《数据结构-初阶》 《程序设计》《鼠鼠的C++学习之路》

🌟人为善,福随未至,祸已远行;人为恶,祸虽未至,福已远离


上期回顾:在上一篇文章中,我们对C++进行了初步的认识,学习了C++的发展历史,第一个C++程序以及命名空间,我们知道,C++的出现就是为了改进和完善C语言的不足,使得程序更加高效,程序员编写起来更加方便快捷,那么本篇文章我们继续往下认识C++的入门相关知识

目录

一、C++的输入&输出

1.1、核心载体:头文件

1.2、核心的IO对象:cin与cout

1.2.1、std::cin 标准输入流

1.2.2、std::cout 标准输出流

1.3、流操作符: << 与 >> 的双重身份

1.4、换行与缓冲区:endl的应用

1.5、C++IO的核心优势:从手动格式到自动适配

1.5.1、自动识别类型

1.5.2、自定义类型支持

1.6、面向对象的底层支撑:IO流的设计思想

1.7、提高输入输出效率

二、C++的缺省参数

2.1、缺省参数的定义及其基本用法

2.2、全缺省与半缺省

2.2.1、全缺省

2.2.2、半缺省

三、C++的函数重载

3.1、函数重载的定义:


一、C++的输入&输出

在C语言时代,我们一依赖printf和scanf两个函数完成输入和输出,手动指定格式符、处理类型不匹配的风险是每个开发者的日常。而C++带来了全新的IO库,以类型安全、可扩展的设计重构了输入输出的体验。

1.1、核心载体:<iostream>头文件

<iostream>头文件是Input Output stream的缩写,是C++标准输入输出的核心头文件,它不仅定义了cin,cout,endl等等标准的IO对象,同时封装了底层IO操作的复杂逻辑,让开发者无需关注缓冲区管理、设备交互等等细节

在这里有一个值得注意的小细节,在VS的编译器中(也就是微软公司的编译器),<iostream>头文件是会间接包含<stdio.h>这个头文件的,因此在微软的编译器中,我们可以混着使用cin与scanf.但是这只适用于微软的编译器,对于跨平台的兼容性不并不是很好,所以在编写代码的时候尽量不要混用

1.2、核心的IO对象:cin与cout

1.2.1、std::cin 标准输入流

std::cinistream类的对象,主要是面向窄字符(char类型)的标准输入流.它从键盘或者其他的输入设备获取数据,通过流提取运算符 >> 完成数据的读取,可参考以下代码:

#include <iostream> int main() { int age; std::cout << "请输入你的年龄:"; std::cin >> age; // 从标准输入读取整数 std::cout << "你的年龄是:" << age << "岁" << std::endl; return 0; }

1.2.2、std::cout 标准输出流

std::coutostream类的对象,同样是面对窄字符的标准输出流.它通过流插入运算符 <<向屏幕或者其他输出设备写入数据,支持链式调用,具体使用可参考以下代码:

#include <iostream> int main() { std::cout << "Hello, C++ IO Stream!" << std::endl; return 0; }

1.3、流操作符: << 与 >> 的双重身份

在C语言中,<< >>这两个符号分别代表的是左移/右移运算符.而在C++中,通过重载函数的技术,这两个运算符被赋予了新的角色:

  • << : 流插入运算符,用于向输出流写入数据
  • >> : 流提取运算符,用于从输入流提取数据

这种重载实现了 “语法糖” 效果,让 IO 操作更符合直觉。同时,运算符的返回值是流对象本身,支持链式调用:

std::cout << "姓名:" << "张三" << ",年龄:" << 25 << std::endl;

链式调用的底层原理是:每次<<操作返回ostream&,使得后续操作可以直接作用于同一个流对象。

1.4、换行与缓冲区:endl的应用

在我们刚刚开始学习C++语言的时候,老师经常会告诉我们,这个是换行符,其实不然,它的作用远不止于此:

表面功能:相当于插入换行符 \n,实现文本换行深层功能:强制舒心输出缓冲区,将缓冲区的数据立即写入输出设备

这与直接使用\n有着显著的区别:

// 仅换行,不刷新缓冲区,性能更优 std::cout << "Hello\n"; // 换行+刷新缓冲区,适用于需要立即输出的场景(如调试日志) std::cout << "Hello" << std::endl;

频繁使用endl会导致缓冲区频繁刷新,降低IO的性能,在性能高敏感的场景中,应当优先使用 \n,仅需要在立即输出的时候使用endl.

1.5、C++IO的核心优势:从手动格式到自动适配

1.5.1、自动识别类型

在C语言中,我们使用printf()需要手动指定格式符,如%s %d %f等等,一旦格式符与变量类型不相同,就会导致未定义行为,所以这也是C++针对C语言做的优化之一.C++IO流则是通过函数重载实现了自动类型识别:

int num = 42; double pi = 3.14; std::string name = "C++"; std::cout << num << " " << pi << " " << name << std::endl; // 自动识别类型,输出:42 3.14 C++

这种设计不仅简化了代码,还从根本上避免了格式不匹配的问题。

1.5.2、自定义类型支持

C++ IO 流的最大优势之一是支持自定义类型的输入输出。通过重载 << 和 >>运算符,我们可以让自定义类/结构体像内置类型一样直接参与 IO 操作:

#include <iostream> struct Point { int x, y; }; // 重载<<运算符,实现Point类型的输出 std::ostream& operator<<(std::ostream& os, const Point& p) { return os << "(" << p.x << ", " << p.y << ")"; } int main() { Point p{10, 20}; std::cout << "点的坐标:" << p << std::endl; // 输出:点的坐标:(10, 20) return 0; }

这种可扩展性让 C++ IO 流成为面向对象编程的理想选择。

1.6、面向对象的底层支撑:IO流的设计思想

C++IO流的设计深度融合了面向对象的核心思想:

  • 继承体系:istream和ostream作为基类,派生出文件流(fsteam)、字符串流(sstream)等子类,实现了IO操作的统一接口
  • 多态与重载:通过运算符重载和虚函数,实现了不同类型数据的IO适配
  • 封装性:底层缓冲区管理、设备交互等细节被封装在流内部,开发者只需要关注高层接口

这些设计使得IO流库即灵活又易于拓展,但是也意味着需要掌握更多面向对象只是才能深入理解其底层应用原理

1.7、提高输入输出效率

在需要输入输出性能的地方,C++在这方面是比不过C语言的,想要让C++的输入和输出像C语言一样,那就要在代码前面加上这段代码:

ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);

总之:C++ IO 流不仅是输入输出的工具,更是面向对象设计思想的典型实践。掌握其核心原理与最佳实践,将为你构建更健壮、可扩展的 C++ 应用打下坚实基础。

二、C++的缺省参数

2.1、缺省参数的定义及其基本用法

缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时,如果没有指定实参则采⽤该形参的缺省值,否则使⽤指定的实参,像下面这样:

#include<iostream> //这里定义一个函数 void Func(int a = 10) { std::cout << a; } int main() { int a = 20; //这里将参数a传入函数中 Func(a); return 0; }

运行结果如下:

但是这时候我们不将a的值传进去,我们看看结果是什么:

#include<iostream> //这里定义一个函数 void Func(int a = 10) { std::cout << a; } int main() { int a = 20; //这里不传a的值进去 Func(); return 0; }

运行结果为:

总结:我们在定义一个函数时,如果给里面的参数进行了初始化,那么在主函数调用时,如果给函数传进了参数,那就使用传进来的参数,如果没有传参数,那就使用在函数定义时所设定的初始值

2.2、全缺省与半缺省

2.2.1、全缺省

全缺省顾名思义就是函数中全部参数给缺省值,例子如下:

#include<iostream> //这里函数用三个参数做例子,可以更直观地看出全缺省的作用 void Func(int a = 10, int b = 20, int c = 30) { std::cout << a << " " << b << " " << c << std::endl; } int main() { int a = 1, b = 2, c = 3; Func(a,b,c); return 0; }

运行结果如下:

既然是全缺省,那是不是可以所有参数都不传进去?确实可以,想下面这样:

//这里为了方便,只展示主函数,其余的与上面的代码保持相同 int main() { int a = 1, b = 2, c = 3; Func(); return 0; }

运行结果如下:

这时候又有老铁要问了,能不能值传部分参数的值进去?我不想传完,行不行?答案是可以的,像这样:

int main() { int a = 1, b = 2, c = 3; Func(a); Func(a, b); return 0; }

我们可以传只传第一个参数的值进去,也可以只传前两个参数进去,但是如果我们想只传第一个和第三个的参数进去呢?写成这样可以吗?

Func(a, ,c);

很显然是不行的,为什么?因为在制定语法的时候这是不被允许的,但是我们如果真的只想传第一个和第三个的值呢?我们可以怎么做?简单,只用调换一下位置就行了:

#include<iostream> //像这样子调换一下b和c的位置即可 void Func(int a = 10, int c = 30 int b = 20) { std::cout << a << " " << b << " " << c << std::endl; } int main() { int a = 1, b = 2, c = 3; //只传入a和c的值 Func(a, c); return 0; }

运行结果如下:

这样一来,只有a和c的值被修改了

小贴士:在传入值的时候,只能从左向右依次传值,不能跨越地,间隔跳跃地传值

2.2.2、半缺省

与全缺省相反,半缺省就是对函数中部分变量进行初始化,其中规定只能从右往左依次缺省,不能间隔跳跃缺省:

#include<iostream> //只缺省最后一个参数 void Func(int a , int b, int c=10) { std::cout << a << " " << b << " " << c << std::endl; } int main() { int a = 1, b = 2, c = 50; //这时候就要将前两个参数全部传进去 Func(a, b); return 0; }

运行结果如下:

如果想要让两个参数缺省,那就这样子写:

#include<iostream> //void Func(int a = 10,int b,int c = 20) 这种格式是错误的 void Func(int a , int b =20, int c=10) { std::cout << a << " " << b << " " << c << std::endl; } int main() { int a = 1, b = 2, c = 50; Func(a); return 0; }

运行结果如下:

小贴士:带缺省参数的函数调用,C++规定必须是从左到右依次给实参,不能跳跃给实参函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,这时候规定必须是函数声明时给缺省值.

三、C++的函数重载

在C语言中,我们经常会碰到这样问题:写很多个功能相同的函数但是命名却不能相同,这样就导致了程序员在编写代码时的效率大幅度降低,而C++的函数重载就是为了解决这个问题的

3.1、函数重载的定义:

C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者类型不同。这样C++函数调⽤就表现出了多态⾏为,使⽤更灵活。C语⾔是不⽀持同⼀作⽤中出现同名函数的。

 #include<iostream> //这是参数类型不相同 int add(int a, int b) { std::cout << "int (a+b) " << a + b << std::endl; return a + b; } double add(double a, double b) { std::cout << "double (a + b) " << a + b << std::endl; return a + b; } //这是参数个数不相同 int add2(int a, int b, int c) { std::cout <<"int (a + b + c) " <<a + b + c << std::endl; return a + b + c; } int add2(int a, int b, int c, int d) { std::cout << "int (a + b + c + d) " << a + b + c + d << std::endl; return a + b + c + d; } //这是参数类型顺序不同 void add3(int a, double b) { std::cout << "int a,int b" << std::endl; } void add3(double b, int a) { std::cout << "int b,int a " << std::endl; } int main() { int a = 10, b = 20, c = 30, d = 40; double a2 = 1.2, b2 = 2.2; add(a, b); add(a2, b2); add2(a, b, c); add2(a, b, c, d); return 0; }

运行结果如下:

小贴士:返回值的不同不能作为重载条件,因为如果是同名函数的话,编译器不能区分调用哪个:

#include<iostream> int fxx() { std::cout << "int fxx()" << std::endl; } void fxx() { std::cout << "void fxx()" << std::endl; } int main(){ fxx(); return 0; }

但是也要小心缺省函数带来的类似返回值不同的效果:

#include<iostream> void fxx(int a){ std:::cout << "fxx(int a)" << std::endl; } void fxx(){ std::cout << "fxx()" << std::endl; } int main(){ //这就是缺省参数带来的类似返回值不同的效果 fxx(); return 0; }

那么以上就是本次所有的内容了文章是自己写的哈,有什么描述不对的、不恰当的地方,恳请大佬指正,看到后会第一时间修改,感谢您的阅读~

Read more

【Java 开发日记】设计一个支持万人同时抢购商品的秒杀系统?

【Java 开发日记】设计一个支持万人同时抢购商品的秒杀系统?

目录 一、系统架构设计 1. 分层架构 2. 具体组件 二、核心问题解决方案 1. 超卖问题 解决方案一:Redis原子操作 解决方案二:数据库乐观锁 解决方案三:预扣库存 2. 高并发请求处理 2.1 流量削峰 2.2 分层过滤 3. 系统性能优化 3.1 缓存策略 3.2 读多写少优化 4. 详细实现方案 4.1 秒杀流程 4.2 库存同步方案 三、高可用保障 1. 限流降级策略 2. 熔断降级 四、监控与告警 1.

By Ne0inhk

Java最新面试题库——精选100道(含精简答案),收藏这篇就够了

JavaEE面试题整理 * 一、Java基础篇 * 二、JVM篇 * 三、Tomcat篇 * 四、MyBatis篇 * 五、Spring篇 * 六、SpringMVC面试题整理 * 七、Redis篇 * 八、Mongodb篇 * 九、MQ篇 * 十、Shiro篇 * 十一、搜索引擎篇 * 十二、Nginx篇 * 十三、SpringBoot篇 * 十四、Dubbo篇 一、Java基础篇 1、JAVA中的几种基本数据类型是什么,各自占用多少字节? 浮点类型:float(4字节)、double(8个字) 整数类型:byte(1字节)、short(2字节)、int(4字节)、long(8字节) 字符类型:char(

By Ne0inhk
JavaScript模式——策略模式:告别if-else地狱,2个案例让你“策略”在握

JavaScript模式——策略模式:告别if-else地狱,2个案例让你“策略”在握

1. 策略模式是什么鬼? 简单说,策略模式就是帮你把一堆“算法”或者“规则”分别打包,让它们可以随时互换。就像你去旅行,可以选择飞机、火车、自驾,目的地一样,但方式随便换。这种模式的核心思想就是把“做什么”和“怎么做”分开。 比如,你要计算年终奖,绩效S和绩效A的算法不一样,但它们都是“计算奖金”这件事。策略模式就让你把这些算法一个个封装好,想用哪个就用哪个。 2. 策略模式长啥样? 策略模式通常有两部分: * 策略对象:负责具体干活,比如不同的奖金算法、不同的动画缓动公式。 * 环境对象:负责接收命令,然后把活派给某个策略。 听起来抽象?没关系,下面两个例子保你一看就懂。 3. 案例一:年终奖怎么算? 3.1 新手写法:if-else堆成山 刚入行的程序员可能会这么写: var

By Ne0inhk
Java 大视界 -- Java 大数据机器学习模型在金融衍生品市场波动特征挖掘与交易策略创新中的应用(363)

Java 大视界 -- Java 大数据机器学习模型在金融衍生品市场波动特征挖掘与交易策略创新中的应用(363)

Java 大视界 -- Java 大数据机器学习模型在金融衍生品市场波动特征挖掘与交易策略创新中的应用(363) * 引言: * 正文: * 一、Java 构建的金融数据处理架构 * 1.1 多源异构数据实时融合 * 1.2 新闻舆情与市场冲击建模 * 二、Java 驱动的波动特征挖掘与预测 * 2.1 多模型融合的波动率预测 * 2.2 极端行情预警与止损优化 * 三、基于波动特征的交易策略创新 * 3.1 跨市场套利策略 * 3.2 动态对冲策略 * 四、实战案例:从 “被动止损” 到 “主动盈利” * 4.1 股指期货量化基金:从 38% 回撤到 12% * 4.2 外汇期权交易:

By Ne0inhk