ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

C++入门篇(一)基础精讲上篇:命名空间 | 输入输出 | 缺省参数 | 函数重载

2026/9/14 22:15:48 拓冰建站 浏览量
C++入门篇(一)基础精讲上篇:命名空间 | 输入输出 | 缺省参数 | 函数重载 目录前言一命名空间namespace1.1 为什么要有命名空间1.1.2域1.2.1定义命名空间1.2.2域访问限定符1.3namespace只能定义在全局当然namespace也可以嵌套定义1.3.1域合并1.4使用命名空间1.4.1using关键字的隐患1.5小结二.输入输出1.标准输入输出流对象1.1 endl和\n的区别1.2输出流运算符1.3输入流运算符2.输入输出细节补充三 缺省参数1.1一句话简单定义2 代码案例3.核心规则3.1默认参数必须从右往左连续指定3.2 默认参数只指定一次3.3不能使用局部变量作为默认值3.4不能引用同一函数的其他参数四.函数重载。4.1什么是函数重载4.2重载的基本规则1参数列表必须不同1.参数个数不同2.参数类型不同3.参数顺序不同。(2)返回类型不能做为重载依据仅返回类型不同不构成重载编译会报错3缺省参数不参与重载区分4数组函数指针等价五.本节全部知识点坑点总结避坑清单1.命名空间2.cin/cout 输入输出的坑3.缺省参数高频坑4.函数重载坑选择题高频坑前言C是在C语言的基础上创造出来的一种更为完善的计算机语言解决了C语言的很多漏洞与缺陷。至今仍是后端、嵌入式、游戏开发领域的核心语言。本篇从最基础的 4 块知识点入手带你打通 C 入门第一道门槛。一命名空间namespace1.1 为什么要有命名空间核心目的为了解决命名冲突。举个直观的例子C标准库stdlib.h自带rand()函数。如果我们再定义rand()函数编译器直接报错重定义。#include stdio.h #include stdlib.h int rand 10; int main() { // 编译报错error C2365: “rand”: 重定义以前的定义是“函数” printf(%d\n, rand); return 0; }全局域里面的名字不能重复命名空间就相当于给全局域名字划分了一个单独的包间包间类部名字互不干扰。C标准库都放在⼀个叫std(standard)的命名空间中1.1.2域在C中有函数局部域全局域命名空间域类域。域控制编译阶段名字查找规则实现名字隔离。局部域全局域还会影响生命周期命名空间域类域只管名字查找不影响生命周期1.2.1定义命名空间定义命名空间需要使⽤到namespace关键字定义大括号{}可以写变量/函数/类型等。如下代码所示namespace baiyang { int rand 10; int Add(int left, int right) { return left right; } }这样我们把自定义rand变量 和 库函数rand 用命名空间域隔离开来避免了报错。1.2.2域访问限定符叫做作用域限定符俩冒号。左边限定访问的域右边访问对象。如果左边不写的话便会访问全局域。如图以访问命名空间中的函数为例1.3namespace只能定义在全局当然namespace也可以嵌套定义namespace baiyang { namespace fh { int age 50000; int Add(int x, int y) { return x y; } } namespace brny { int age 8; int Add(int m, int n) { return m n; } } }此时访问其内部成员如上相同baiyangfhage1.3.1域合并同一个名字的namespace就算写在不同的文件、不同位置编译器会合并在同一个命名空间。即多个文件可以只创建一个命名空间会认为是一个命名空间。1.4使用命名空间使用命名空间需要引入一个关键字using共三种方法1.限定访问推荐工程写法baiyang::Add(1,2);完全不会污染命名大项目首选2.using 声明推荐日常写法using baiyuang::Add;只引入这一个名字。3.using namespace 指令using namespace baiyang;一次性引入全部名字建议谨慎使用。1.4.1using关键字的隐患using namespace 会把命名空间内所有名字暴露到当前作用域容易再次触发命名冲突项目越大风险越高。举个例子using namespace std; using namespace boost;两个命名空间里都有 vector 时歧义又回来了。所以不建议展开整个命名空间推荐using 声明只引入一个名字这样既保留了效率同时也减少了错误的发生。1.5小结概念要点作用避免命名冲突访问命名空间名字using声明只引入一个名字相对安全using指令引入全部容易冲突二.输入输出1.标准输入输出流对象c自带标准流对象对象类型用途默认目标cinistream标准输入键盘coutostream标准输出屏幕缓冲示例1.1 endl和\n的区别\n只但纯的换行不刷新缓冲区因此效率跟高。endl:换行强制刷新输出缓冲区频繁大量输出会变慢。主要大量循环打印时频繁endl会反复刷缓冲区所以优先\n.1.2输出流运算符如上图叫做“流插入运输符“将数据写入流中它可以链式调用std::cout板鸭 占领世界endl;1.3输入流运算符int a; double b; std::string s; std::cin a b s;从控制台读取数据存入变量自动忽略空格换行。2.输入输出细节补充1整个IO流体系看不懂不要紧IO流涉及类和对象运算符重载、继承等很多面向对象的知识这些知识我们还没有讲解所以这里我们只能简单认识一下C IO流的用法后面我会专门出一篇来细节IO流库。2精度控制小巧思C可以控制小数点但是有点麻烦需要精度控制函数调用cout这个对象——调用精度控制函数precision但是c兼容c所以我们任然可以像往常一样double a2.2222222222; printf(%.2lf,a);3提升性能小技巧在竞赛等高io需求场景cout/cin跟不上。方法1直接使用printf/scanf。方法2输入下方三行代码具体原理未来会讲大家先了解一下。int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); return 0; }三 缺省参数1.1一句话简单定义缺省参数函数声明 / 定义时给形参预先指定默认值。调用时不传这个参数自动使用默认值。2 代码案例int func(int a0) { std::coutaendl; } int main() { func();//没传参时使用参数的默认值。 func(2);//传参时使⽤指定的实参 return 0; }a就是一个带缺省值的参数如果调用者不提供实参就调用其默认值。语法形式就是返回类型 函数名参数类型 参数名默认值3.核心规则3.1默认参数必须从右往左连续指定如果一个参数有默认值那么它右边参数都必须带有默认值。void f(int a, int b 2, int c 3); // OK void f(int a 1, int b, int c 3); // 错误b 没有默认值但 a 有正确的写法应该是void f(int a, int b 2, int c 3); void f(int a1, int b 2, int c 3);这样写的原因是调用时参时从左往右匹配如果中间缺省编译器无法匹配实参是哪个参数3.2 默认参数只指定一次同一个函数在同一个作用域类默认参数只定义一次通常放在函数声明中定义中不再重复。//头文件 void fanc(int a0); //.cpp源文件 void fanc(int a)//不再写a0 { coutaencl; }3.3不能使用局部变量作为默认值默认参数是再函数外部声明的不能使用函数内的局部变量。void f() { int local 10; void g(int a local); // 错误local 是局部变量 }3.4不能引用同一函数的其他参数void f(int a, int b a); // 错误a 在默认参数中不可见四.函数重载。4.1什么是函数重载在同一个作用域多个函数同名但是参数列表不一样构成函数重载。作用功能相近的函数复用同一个函数名可读性更好。如下代码所示void print(int x) { std::cout int: x \n; } void print(double x) { std::cout double: x \n; } void print(const std::string s) { std::cout string: s \n; } print(42); // 调用 print(int) print(3.14); // 调用 print(double) print(hello); // 调用 print(const std::string)通过隐式转换三个函数名相同print参数列表不同构成重载。调用时编译器根据参数内型选择。4.2重载的基本规则1参数列表必须不同1.参数个数不同2.参数类型不同3.参数顺序不同。void f(int a, int b); void f(int a); // 个数不同 void f(double a, int b); // 类型不同 void f(int a, double b); // 顺序不同与上一条不同(2)返回类型不能做为重载依据仅返回类型不同不构成重载编译会报错int f(int); double f(int); // 错误重定义仅返回类型不同应为编译器无法根据返回值来调用函数。3缺省参数不参与重载区分缺省参数不会改变函数签名因此不能仅靠缺省参赛重载void f(int); void f(int, int 0); // 与 f(int) 冲突调用 f(1) 编译报错此时编译器无法区分f1调用哪个函数。因此不建议缺省参数和重载共同使用如果要坚持这样写建议将二者分别放在不同的命名空间此时便不构成函数重载了。原因函数重载需要在同一个域中实现。4数组函数指针等价void fanc(int*); void fanc(int[]); // 等价 void fanc(int[10]); // 等价五.本节全部知识点坑点总结避坑清单1.命名空间错误namespace定义写在函数内部main 里面定义 namespace正确namespace只能定义在全局域函数体内不能定义命名空间错误using namespace std; 在大型项目里随便全局展开正确容易出现名字冲突工程推荐std::限定写法。混淆命名空间域会改变变量生命周期纠正命名空间只控制名字查找不影响变量生命周期。2.cin/cout 输入输出的坑1大量循环输出频繁写endl问题每次 endl 强制刷新缓冲区输出速度暴跌大批量打印优先用\n。2忘记引入头文件直接写cout正确做法必须#include iostream并且 cout 属于std命名空间。3.缺省参数高频坑1.默认参数中间留空void func(int a10,int b,int c20);规则默认参数必须从右往左连续给带默认值参数右边不能无默认的参数。2.声明和定义两处同时写默认值同上文3.23.使用局部变量作为默认参数。4.函数重载坑选择题高频坑1只改返回值参数列表完全一样认为构成重载重点返回值不能单独作为重载区分条件。2缺省参数造成重载二义性void func(int a 10){} void func(){ } func(); // 调用歧义编译器不知道调用哪一个结论缺省参数不参与重载区分极易引发调用歧义。3数组、指针当成不同参数二者等价不构成重载。这期分享就到这里结束了如果感觉内容对你有帮助给个三连支持一下吧在此跪谢大家了