【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

Flutter 三方库 http_cache_hive_store 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、工业级的 HTTP 二级缓存与 Hive 数据库持久化联动引擎

Flutter 三方库 http_cache_hive_store 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、工业级的 HTTP 二级缓存与 Hive 数据库持久化联动引擎

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 http_cache_hive_store 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、工业级的 HTTP 二级缓存与 Hive 数据库持久化联动引擎 在鸿蒙(OpenHarmony)系统的端云一体化网络架构、针对高频 API 的请求压实(Debounce)或者是需要实现“秒开离线”的网络应用场景中,如何让 http 或 dio 库自动具备缓存能力,并将缓存物理落地到极速的 Hive 非关系型数据库中?http_cache_hive_store 为开发者提供了一套工业级的、基于 Hive 的网络响应持久化缓存方案。本文将深入实战其在鸿蒙端网络响应加速中的应用。 前言 什么是 HTTP

By Ne0inhk
Flutter 三方库 flutter_adaptive_scaffold 的鸿蒙化适配指南 - 掌握一套代码适配全场景终端的自适应架构技术、助力鸿蒙应用构建从手机到平板及折叠屏的极致无缝交互体系

Flutter 三方库 flutter_adaptive_scaffold 的鸿蒙化适配指南 - 掌握一套代码适配全场景终端的自适应架构技术、助力鸿蒙应用构建从手机到平板及折叠屏的极致无缝交互体系

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 flutter_adaptive_scaffold 的鸿蒙化适配指南 - 掌握一套代码适配全场景终端的自适应架构技术、助力鸿蒙应用构建从手机到平板及折叠屏的极致无缝交互体系 前言 在 OpenHarmony 鸿蒙应用追求“万物互联、全场景覆盖”的伟大进程中,屏幕尺寸的多样性(从 6 英寸手机到 12 英寸平板,再到 2D/3D 模式切换的折叠屏)是每一位 UI 开发者必须正面迎接的挑战。如何在不为每种设备重写 UI 的前提下,实现导航栏自动从“底部”平滑流转到“侧边”?如何在宽屏模式下自动开启“双栏(Master-Detail)”布局?flutter_adaptive_scaffold 作为一个由 Flutter

By Ne0inhk
AIGC | Midjourney使用指南,直接拿捏~

AIGC | Midjourney使用指南,直接拿捏~

目录 前言:第一篇ZEEKLOG博客,还请各位大佬多多指教!! 一、认识Midjourney 二、Midjourney算法原理 三、Midjourney基本操作指南 1、安装 2、使用演示及基本分区讲解 3、命令解析 4、后缀解析 总结:     前言:第一篇ZEEKLOG博客,还请各位大佬多多指教!!   一、认识Midjourney   Midjourney是由David Holz 2022年3月推出的一款AI制图工具。处于聊天软件discord中,主要功能涵盖图像生成、风格化、变体生成、图生图等,且提供高级工具精细控制生成过程。 使用上需创建账户、获邀请后通过Discord频道输入文字提示来操作。相比于SD(stable diffusion) MJ随机性更大,细节处理精度不够。 二、Midjourney算法原理   MJ基于深度学习中的生成对抗网络(GAN)和扩散模型等技术。 * 生成对抗网络(GAN):由生成器和判别器组成。生成器的任务是根据输入的随机噪声和文本描述等信息,生成尽可能逼真的图像;

By Ne0inhk
Flutter 三方库 objectbox_generator — 自动化构建鸿蒙极速 NoSQL 数据库映射(适配鸿蒙 HarmonyOS Next ohos)

Flutter 三方库 objectbox_generator — 自动化构建鸿蒙极速 NoSQL 数据库映射(适配鸿蒙 HarmonyOS Next ohos)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net。 Flutter 三方库 objectbox_generator — 自动化构建鸿蒙极速 NoSQL 数据库映射(适配鸿蒙 HarmonyOS Next ohos) 在高性能移动应用开发中,本地数据的持久化存储效率往往是决定用户感知流畅度的木桶短板。传统的 SQLite 虽然结构化程度高,但在处理大规模对象关系映射(ORM)时,复杂的 SQL 拼接和反射解析往往会成为性能瓶颈。 ObjectBox 作为一个专为移动设备打造的、跨平台的超高速 NoSQL 数据库,已经成为了许多追求极致体验开发者的首选。而在 Flutter for OpenHarmony 开发中,配合 objectbox_generator,我们可以通过注解驱动的自动化流程,掌握这套高性能数据库的核心用法。 ⚠️ 鸿蒙适配现状提示:截至本文撰写时,ObjectBox 的 Dart 插件尚未提供官方的 OpenHarmony

By Ne0inhk