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

发布时间:2026/7/30 8:26:21

【C++初阶】C++入门相关知识(2):输入输出  缺省参数  函数重载 主页传送门:良木生香个人专栏:《C语言》 《数据结构-初阶》 《程序设计》《鼠鼠的C学习之路》人为善,福随未至,祸已远行;人为恶,祸虽未至,福已远离上期回顾:在上一篇文章中,我们对C进行了初步的认识,学习了C的发展历史,第一个C程序以及命名空间,我们知道,C的出现就是为了改进和完善C语言的不足,使得程序更加高效,程序员编写起来更加方便快捷,那么本篇文章我们继续往下认识C的入门相关知识目录一、C的输入输出1.1、核心载体头文件1.2、核心的IO对象:cin与cout1.2.1、std::cin 标准输入流1.2.2、std::cout 标准输出流1.3、流操作符 与 的双重身份1.4、换行与缓冲区endl的应用1.5、CIO的核心优势:从手动格式到自动适配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与cout1.2.1、std::cin 标准输入流std::cin是istream类的对象,主要是面向窄字符(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::cout是ostream类的对象,同样是面对窄字符的标准输出流.它通过流插入运算符 向屏幕或者其他输出设备写入数据,支持链式调用,具体使用可参考以下代码:#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、CIO的核心优势:从手动格式到自动适配1.5.1、自动识别类型在C语言中我们使用printf()需要手动指定格式符,如%s %d %f等等,一旦格式符与变量类型不相同,就会导致未定义行为,所以这也是C针对C语言做的优化之一.CIO流则是通过函数重载实现了自动类型识别: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流的设计思想CIO流的设计深度融合了面向对象的核心思想:继承体系: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、缺省参数的定义及其基本用法缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时如果没有指定实参则采⽤该形参的缺省值否则使⽤指定的实参像下面这样#includeiostream //这里定义一个函数 void Func(int a 10) { std::cout a; } int main() { int a 20; //这里将参数a传入函数中 Func(a); return 0; }运行结果如下:但是这时候我们不将a的值传进去,我们看看结果是什么:#includeiostream //这里定义一个函数 void Func(int a 10) { std::cout a; } int main() { int a 20; //这里不传a的值进去 Func(); return 0; }运行结果为:总结:我们在定义一个函数时,如果给里面的参数进行了初始化,那么在主函数调用时,如果给函数传进了参数,那就使用传进来的参数,如果没有传参数,那就使用在函数定义时所设定的初始值2.2、全缺省与半缺省2.2.1、全缺省全缺省顾名思义就是函数中全部参数给缺省值例子如下#includeiostream //这里函数用三个参数做例子,可以更直观地看出全缺省的作用 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);很显然是不行的,为什么?因为在制定语法的时候这是不被允许的,但是我们如果真的只想传第一个和第三个的值呢?我们可以怎么做?简单,只用调换一下位置就行了:#includeiostream //像这样子调换一下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、半缺省与全缺省相反,半缺省就是对函数中部分变量进行初始化,其中规定只能从右往左依次缺省,不能间隔跳跃缺省:#includeiostream //只缺省最后一个参数 void Func(int a , int b, int c10) { std::cout a b c std::endl; } int main() { int a 1, b 2, c 50; //这时候就要将前两个参数全部传进去 Func(a, b); return 0; }运行结果如下:如果想要让两个参数缺省,那就这样子写:#includeiostream //void Func(int a 10,int b,int c 20) 这种格式是错误的 void Func(int a , int b 20, int c10) { 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语⾔是不⽀持同⼀作⽤中出现同名函数的。#includeiostream //这是参数类型不相同 int add(int a, int b) { std::cout int (ab) 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; }运行结果如下小贴士返回值的不同不能作为重载条件因为如果是同名函数的话编译器不能区分调用哪个#includeiostream int fxx() { std::cout int fxx() std::endl; } void fxx() { std::cout void fxx() std::endl; } int main(){ fxx(); return 0; }但是也要小心缺省函数带来的类似返回值不同的效果:#includeiostream void fxx(int a){ std:::cout fxx(int a) std::endl; } void fxx(){ std::cout fxx() std::endl; } int main(){ //这就是缺省参数带来的类似返回值不同的效果 fxx(); return 0; }那么以上就是本次所有的内容了文章是自己写的哈有什么描述不对的、不恰当的地方恳请大佬指正看到后会第一时间修改感谢您的阅读~

相关新闻