《解锁 C++ 基础密码:输入输出、缺省参数,函数重载与引用的精髓》
一.C的输入和输出关键要点iostream 是 Input Output Stream 的缩写是标准的输⼊、输出流库定义了标准的输入、输出对象。std::cin 是 istream 类的对象它主要面向窄字符narrow characters (of type char)的标准输入流。std::cout 是 ostream 类的对象它主要面向窄字符的标准输出流。std::endl 是一个函数流插入输出时相当于插入一个换行字符加刷新缓冲区’。是流插入运算符是流提取运算符。C语言还用这两个运算符做位运算左移/右移使用C输入输出更方便不需要像printf/scanf输入输出时那样需要手动指定格式C的输入输出可以自动识别变量类型(本质是通过函数重载实现的这个以后会讲到)其实最重要的是C的流能更好的支持自定义类型对象的输入输出。IO流涉及类和对象运算符重载、继承等很多面向对象的知识这些知识我们还没有讲解所以这里我们只能简单认识⼀下C IO流的用法。cout/cin/endl等都属于C标准库C标准库都放在一个叫std(standard)的命名空间中所以要通过命名空间的使用方式去用他们。⼀般日常练习中我们可以using namespace std实际项目开发中不建议using namespace std。这里我们没有包含stdio.h也可以使用printf和scanf在包含iostream间接包含了。vs系列编译器是这样的其他编译器可能会报错。举例说明代码语言javascriptAI代码解释#includeiostream #includealgorithm using namespace std; int main() { int a, b; cin a b;//输入 cout a b \n;//输出 cout a b endl;//end line return 0; }--用\n的效率会更高除此以外cout和cin的效率其实也是不如printf和scanf的但是我们可以通过取消同步流的操作来解决这个问题代码如下代码语言javascriptAI代码解释#includeiostream using namespace std; int main() { //取消同步流 //在io需求比较高的地方比如需要大量输入的竞赛题中加上以下3行代码,可以提高效率 ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }二.缺省参数关键要点缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调用该函数时如果没有指定实参则采用该形参的缺省值否则使用指定的实参缺省参数分为全缺省和半缺省参数。有些地方把缺省参数也叫默认参数全缺省就是全部形参给缺省值半缺省就是部分形参给缺省值。C规定半缺省参数必须从右往左依次连续缺省不能间隔跳跃给缺省值。带缺省参数的函数调用C规定必须从左到右依次给实参不能跳跃给实参。函数声明和定义分离时缺省参数不能在函数声明和定义中同时出现规定必须函数声明给缺省值。--上面的这些定义在后面都会给出对应举例注意看注释举例说明--包含全缺省和半缺省需要注意的地方注释都讲的比较清楚代码语言javascriptAI代码解释#includeiostream using namespace std; void func(int a 0) { cout a \n\n; } //全缺省 void func1(int a 10,int b 20,int c 30) { cout a a \n; cout b b \n; cout c c \n\n; } //半缺省 //从右至左依次缺省才可以中间不能跳跃缺省不能出现 int a10,int b20,int c或int a10,int b,int c30等这种情况 void func2(int a , int b , int c30)//如果非要a缺省的话我们可以把a和c的位置换一下 { cout a a \n; cout b b \n; cout c c \n\n; } int main() { func(1);//1传参时使用的是指定的实参 func();//没有传参会使用缺省值 //以下4种都可以 func1(1, 2, 3); func1(1, 2); func1(1); func1(); //这种不行不能跳跃传参 /*func1(1, , 3);*/ func2(1, 2, 3); func2(1,2); return 0; }--除此以外缺省参数在改进数据结构中也使用的比较多我们这里以顺序表这个结构的几个接口来看看中间的实现我会比较省略详细的结构实现可以去看一下博主之前的博客说明一下像顺序表这个数据结构的.cpp和.h我简单省略的实现后就给大家展示下图片好了。SeqList.cppSeqList.htest.c注意看注释代码语言javascriptAI代码解释#includeiostream #includeSeqList.h using namespace std; int main() { int n; cin n; SL s; SLInit(s, n);//已经知道n的大小 //如果没有输入操作这里n就是不知道的就会使用缺省的n4 //为啥要定义这么一个n呢 //比如我要尾插1000个数据那么不用这个的话就要不停的扩容会有消耗 for (int i0;in;i) { SLPushBack(s, i); } //Find //原来的find无法实现找顺序表中所有需要找的元素(重复的只会返回第一个) //改了之后通过下述操作可以找到所有的 // 5 4 6 3 4 7 4 // // 查找出所有的4 int x SLFind(s, 4); while (x ! -1) { x SLFind(s, 4, x 1); } return 0; }三.函数重载我们知道在C语言中不支持同一作用域中出现同名函数。但是C是支持的不过要求这些同名函数的形参不同可以是参数个数不同或者类型不同。这样C函数调用就表现出了多态的行为使用更加灵活三种构成重载的一般情况1.参数类型不同代码语言javascriptAI代码解释//1.函数参数类型不同 #includeiostream using namespace std; int Add(int left, int right) { cout int Add(int left, int right) endl; return left right; } double Add(double left, double right) { cout double Add(double left, double right) endl; return left right; } int main() { cout Add(1, 2) \n; cout Add(1.1, 2.2) \n; //自动识别函数传的参数类型调用不同的函数 return 0; }2.参数个数不同代码语言javascriptAI代码解释//2.函数参数个数不同 #includeiostream using namespace std; void f1() { cout f1() \n; } void f1(int a) { cout f1(int a) \n; } int main() { f1(); f1(1); //根据传参的个数自动识别调用对应函数 return 0; }3.参数类型顺序不同代码语言javascriptAI代码解释//3.函数类型顺序不同--本质上还是对应的函数参数类型不同 #includeiostream using namespace std; void f1(double a,int b) { cout f1(double a,int b) \n; } void f1(int a,double b) { cout f1(int a,double b) \n; } int main() { f1(2.3,1); f1(1,2.3); //根据传参的顺序来调用对应函数 return 0; }两种特殊情况一个可以(但是存在一定问题)一个不行无法构成重载(函数的仅仅只是返回类型不同无法构成重载)代码语言javascriptAI代码解释//1.无法构成重载 #includeiostream using namespace std; void fork() { } int fork() { return 1; } int main() { //调用时无法确定调用那个 fork(); int x fork(); return 0; }可以构成重载但是调用时会出现歧义(缺省的情况)代码语言javascriptAI代码解释//2.可以构成重载 //但是一些情况下调用存在歧义 #includeiostream using namespace std; void f1() { cout f() endl; } void f1(int a 10) { cout f(int a) endl; } int main() { f1(1);//这个可以 f1();//这样调用就不行了不确定调用那一个 return 0; }四.引用引用的概念和定义引用并不是定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间它和它的引用变量共用同一块内存空间。类型 引用别名 引用对象在C中为了避免引入太多的运算符会复用C语言的一些符号比如前面的和以及这里的可以是取地址引用还可以是按位与运算符特别容易混淆大家需要注意区分的角度。引用的特性引用在定义时必须初始化一个变量可以有多个引用引用一旦引用⼀个实体再不能引用其他实体举例说明 (注意看注释)代码语言javascriptAI代码解释#includeiostream using namespace std; int main() { int i 1; int j i;//j是i的别名 //一个变量可以有多个别名引用。别名也可以有它的别名 int k j; k;//k的变化会影响i和j cout i \n; cout j \n; cout k \n; //打印发现地址一样 //引用时必须先初始化 //int x;//看报错 //x i; // 引用一旦引用一个实体再不能引用其他实体,引用也不能改变指向 //所以这里的操作是赋值而不是引用 int m 20; k m; return 0; }引用的使用引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被引用对象。引用传参跟指针传参功能是类似的引用传参相对更方便⼀些。引用返回值的场景相对比较复杂我们在这里后续会简单讲一下场景还有一些内容后续在类和对象的学习中会继续深入了解。引用和指针在实践中相辅相成功能有重叠性但是各有特点互相不可替代。C的引用跟其他语言的引用(如Java)是有很大的区别的除了用法最大的点C引用定义后不能改变指向Java的引用可以改变指向。⼀些主要用C代码实现版本数据结构教材中使用C引用替代指针传参目的是简化程序避开复杂的指针但是我们可能当时还没学过引用导致一头雾水。--上述的使用在后面大部分都会有举例还是需要注意看注释举例说明(注意看注释)例子1(交换值在顺序表中的应用)代码语言javascriptAI代码解释//指针引用 //大部分情况下引用都可以替代指针除了一些特殊情况比如链表的树的节点的定义只能使用指针 #includeiostream using namespace std; void swap(int* x, int* y) { int tmp *x; *x *y; *y tmp; } void swap(int x, int y) { int tmp x; x y; y tmp; } int main() { //swap函数交换值 int a 1; int b 7; cout a b \n; swap(a, b);//用指针 cout a b \n; swap(a, b);//用引用 cout a b \n; return 0; }--这里在顺序表中的使用博主就直接放图了只展示部分可以和指针对比看看具体的可以自己去实现一下。注意在实现的过程中原来使用的一般都是 psl- 现在应该使用 psl. 。例子2(交换指针在链表中的使用)代码语言javascriptAI代码解释//替代二级指针使用 #includeiostream using namespace std; void swap(int**x, int** y) { int*tmp *x; *x *y; *y tmp; } void swap(int* x, int* y) { int*tmp x; x y; y tmp; } int main() { //swap函数交换指针 int a 1; int b 7; int* pa a; int* pb b; cout *pa *pb \n; swap(pa, pb);//用指针 cout *pa *pb \n; swap(pa, pb);//用引用 cout *pa *pb \n; return 0; }--我们再来看看在链表中的使用还是省略化的展示代码语言javascriptAI代码解释//在链表中的使用 #includeiostream using namespace std; typedef struct SListNode { struct SListNode* next; int val; }SLTNode;//, //*PSLTNode; //typedef struct SListNode SLTNode; //typedef struct SListNode* PSLTNode; //以前使用二级指针的实现方法 //void SLTPushBack(SLTNode** pphead, int x) //{ // SLTNode* newnode; // malloc // // if (*pphead NULL) // { // *pphead newnode; // } // else // { // // 找到尾结点newnode链接到尾结点 // } //} //void SLTPushBack(PSLTNode phead, int x)//这个在书上有时候会用 void SLTPushBack(SLTNode* phead, int x) { SLTNode* newnode NULL; // malloc这里省掉过程 if (phead NULL) { phead newnode; } else { // 找到尾结点newnode链接到尾结点 } } int main() { //用二级指针 SLTNode* plist NULL; //SLTPushBack(plist, 1); //SLTPushBack(plist, 2); //SLTPushBack(plist, 3); //SLTPushBack(plist, 4); //用引用 //PSLTNode plist NULL; SLTNode* plist NULL; SLTPushBack(plist, 1); SLTPushBack(plist, 2); SLTPushBack(plist, 3); SLTPushBack(plist, 4); return 0; }我们来看一个可能有的教材上会出现但是很容易把我们看懵的形式(注意看图片解释)--在大部分的场景下引用都可以代替指针使用但是在链表树的节点定义位置只能使用指针引用无法替代。这是因为C的引用无法改变指向节点一定存在改变指向的场景传值返回传引用返回传值返回(主要看错误的地方)代码语言javascriptAI代码解释#includeiostream using namespace std; int fun() { int ret 0; return ret; } int main() { int x fun();//x接受的其实是ret的拷贝值在fun函数销毁时ret就没了通过临时变量带出 //fun() 1;//所以这里就无法直接修改 return 0; }这里返回接收的是ret吗--不是是ret的临时拷贝传引用返回(主要看错误的地方)代码语言javascriptAI代码解释//传引用返回 #includeiostream using namespace std; int fun() { int ret 0; return ret; } int main() { intx fun(); cout x \n;//这里可能会是随机值 return 0; }这里的x可能是0也可能是随机值为什么相当于野指针的访问比较危险--我们再来看看一个更奇怪的例子为啥x后面没有变但却是y的值依旧是看错误的地方代码语言javascriptAI代码解释#includeiostream using namespace std; int func1() { int ret 0; // ... return ret; } int func2() { int y 456; // ... return y; } int main() { int x func1(); cout x endl; func2();//明明没有修改x但x的值还是会为y这是因为fun1函数栈帧销毁后还给了操作系统但是func2又使用了这块空间 cout x endl; return 0; }为什么会出现这样的现象呢结合上一个例子可以思考一下两个小问题1.销毁了之后为什么还可以访问--因为销毁了并不代表空间没了内存空间是可以反复使用的销毁的本质是还给操作系统跟租房一样返回的别名就相当于偷偷留了把钥匙但是这样是不可取的。2.这里相当于野指针的访问为什么没报错--越界不一定报错越界写可能会报错在数组中存在越界抽查这个现象。所以我们有时候编译器不会在这里报错的传引用返回的正确使用(顺序表为例)--我们这里的实现还是简略的写一下中间使用了引用的写法大家刚好可以看看注意看注释SeqList.h代码语言javascriptAI代码解释#pragma once #includestdio.h #includestdlib.h typedef struct SeqList { int* arr; int size; int capacity; }SL; void SLInit(SL pls, int n 4); void SLPushBack(SL pls, int x); int SLFind(SL pls, int x, int i 0); int SLat(SL pls, int i);//这里使用引用就又可以读取i位置的值又可以修改了 void SLModify(SL pls, int i, int x);//这个并不好用SeqList.cpp代码语言javascriptAI代码解释#define _CRT_SECURE_NO_WARNINGS 1 #includeSeqList.h void SLInit(SL pls,int n) { pls.arr (int*)malloc(n * sizeof(int)); pls.size 0; pls.capacity n; } void SLPushBack(SL pls, int x) { //……………… pls.arr[pls.size] x; } int SLFind(SL pls, int x,int i) { while (i pls.size) { //……………… } return -1; } int SLat(SL pls, int i)//这里使用引用就又可以读取i位置的值又可以修改了 { //…… return pls.arr[i];//这里可以使用引用返回是因为它是结构体中的一个在堆的数据 } void SLModify(SL pls, int i, int x)//这个并不好用 { //…… pls.arr[i] x; }test.c代码语言javascriptAI代码解释//那我们什么时候可以使用到这个传引用返回呢 //我们拿顺序表这个数据结构为例子当然栈也可以 #includeSeqList.h #includeiostream using namespace std; int main() { SL s; SLInit(s, 10); for (size_t i 0; i 10; i) { SLPushBack(s, i); } for (size_t i 0; i 10; i) { cout SLat(s, i) ; } cout endl; // 把顺序表第i个位置的值修改为x int i 0; int x 0; cin i; cin x; //SLModify(s, i, x);//不好用 SLat(s, i) x;//用了返回引用这里就可以直接修改赋值了 for (size_t i 0; i 10; i) { cout SLat(s, i) ; } cout endl; return 0; }--这里成功使用了传引用返回所以是又可以读又可以写的--补充一个传引用返回使用的情况就是使用static大家可以看看小知识点补充--语法是表达层可以想一下老婆饼夫妻肺片底层是不一定一样的(就像老婆饼里没有老婆)代码语言javascriptAI代码解释#includeiostream using namespace std; int main() { int i 0; //语法层面上引用不开空间指针开空间 int j i; int* p i; j; (*p); //但是我们转到反汇编可以看出其实引用的底层就是指针两个指令的反汇编代码都差不多这个需要仔细观察一下 return 0; }--语法层面上引用是不开空间的指针开空间但是底层来看两者是差不多的的。--引用还有部分知识点会在下一篇博客中继续分享给大家

相关新闻

IF25.2!北大院士都在用的国产老牌数据库,仅三图一表发文柳叶刀子刊!

IF25.2!北大院士都在用的国产老牌数据库,仅三图一表发文柳叶刀子刊!

源自风暴统计网:一键统计分析与绘图的AI网站引言浓浓的大佬气息!北大学者创新性地围绕“独立预期寿命”展开研究,分析了男女不同的长寿路径,用的还是咱国产老牌权威数据库,顶刊毋庸置疑!ps:也想…

2026/7/3 12:41:57 阅读更多 →
Spring bean名称

Spring bean名称

1.概述 当有多个相同类型的实现时,命名一个Spring bean非常有用。这是因为 bean 没有唯一的名称,那么注入 bean 对 Spring 来说是不明确的。 通过控制 bean 的命名,可以告诉 Spring 要将哪个 bean 注入目标对象。 2.默认 Bean 命名策略 Sprin…

2026/5/17 9:32:49 阅读更多 →
小白也能看懂的OpenClaw安装保姆级教程,赶紧先收藏起来,周末实操一下吧,附带命令手册、API配置

小白也能看懂的OpenClaw安装保姆级教程,赶紧先收藏起来,周末实操一下吧,附带命令手册、API配置

OpenClaw 最近这么火,刚好趁着周末,我也安装一个试试,紧跟潮流。一、先确认你的环境(必须满足)1. 系统与硬件Windows 10 64 位内存 ≥ 4GB(推荐 8GB)磁盘可用 ≥ 5GB稳定网络2. 软件依赖&#x…

2026/7/4 23:27:19 阅读更多 →

最新新闻

5大核心技术揭秘:Topit如何实现macOS窗口置顶的魔法效果

5大核心技术揭秘:Topit如何实现macOS窗口置顶的魔法效果

5大核心技术揭秘:Topit如何实现macOS窗口置顶的魔法效果 【免费下载链接】Topit Pin any window to the top of your screen / 在Mac上将你的任何窗口强制置顶 项目地址: https://gitcode.com/gh_mirrors/to/Topit 你是否曾遇到过这样的困扰:在编…

2026/7/6 1:53:42 阅读更多 →
华为RH2288H V3 Windows Server 2008安装:3个驱动安装难点与解决方案

华为RH2288H V3 Windows Server 2008安装:3个驱动安装难点与解决方案

华为RH2288H V3服务器Windows Server 2008驱动安装全攻略:从RAID卡到芯片组的实战解决方案 在数字化转型的浪潮中,企业级服务器作为IT基础设施的核心,其稳定性和性能直接关系到业务连续性。华为RH2288H V3作为一款经典的2U机架式服务器&…

2026/7/6 1:53:42 阅读更多 →
中小教培机构到底该怎么选管理系统?一个12年运营顾问掏心窝建议

中小教培机构到底该怎么选管理系统?一个12年运营顾问掏心窝建议

教培机构为什么总是管不好账、留不住人? 做了12年校区运营咨询,我见过太多中小机构死在"管理"两个字上。不是课上得不好,是排课冲突、续费提醒漏发、课时算不清、家长投诉没人接——这些琐碎的事,一点点把校长的精力吃…

2026/7/6 1:49:40 阅读更多 →
线结构光标定精度对比:棋盘格法 vs 平面法向量法,3种中心线提取算法实测

线结构光标定精度对比:棋盘格法 vs 平面法向量法,3种中心线提取算法实测

线结构光标定精度对比:棋盘格法 vs 平面法向量法,3种中心线提取算法实测在工业检测、逆向工程和机器人引导等领域,高精度三维测量技术发挥着关键作用。线结构光技术因其非接触、高效率和高精度的特点,成为三维测量的重要手段。然而…

2026/7/6 1:47:40 阅读更多 →
温州大学机器学习课程开源项目全解析:从环境搭建到算法实战的保姆级学习指南

温州大学机器学习课程开源项目全解析:从环境搭建到算法实战的保姆级学习指南

温州大学机器学习课程开源项目全解析:从环境搭建到算法实战的保姆级学习指南 在人工智能技术日新月异的今天,机器学习已成为计算机科学领域最热门的方向之一。对于初学者而言,面对浩如烟海的算法理论和复杂的数学推导,往往感到无从…

2026/7/6 1:45:39 阅读更多 →
Java设计模式——结构型

Java设计模式——结构型

设计模式:结构型模式结构型模式关注的是:类和对象之间如何组合,如何让系统结构更灵活、更容易扩展。 创建型模式解决“对象怎么创建”,结构型模式解决“对象怎么组装”。一、结构型模式总览结构型模式主要解决以下问题&#xff1a…

2026/7/6 1:45:39 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻