
前言今天开始入门 C很多从 C 转过来的兄弟第一次看 C 代码心里估计都在嘀咕这 std:: 是啥玩意为啥两个函数名字一样还能编译过这个 符号怎么有时候是取地址有时候又好像不是不用慌咱一个一个把它们扒拉清楚。建议你边看我边敲别光眼睛看手也动起来。一、C 是什么和 C 有啥区别C是Bjarne Stroustrup在1979年于贝尔实验室写的他为什么要开创C呢就是看C语言不好用嘛C语言有他的局限性C支持c同时还开创了c没有的新功能总的来说c是c语言的进化版本不然也不叫它cplusplusplus何意味呢不就是升级版这种意味吗二、命名空间 namespace1namespace 是个啥想象一下将来上班公司给不同小组相应的代码业务A小组写了自己的代码,其中有一个函数名叫hhB小组写了自己的代码其中也有一个函数名叫hh最终项目合并起来的时候问题就出现咯你A组的hh和我B组的hh到底谁改名字难不成打一架谁赢就谁改自己的代码这不搞笑吗namespace 本质就是一个域。它把一堆名字变量名、函数名、类名装到一个包里使得 不同域可以定义同名变量。域影响的是编译时查找函数/类型/变量出处也就是声明或定义的逻辑默认都是先从局部查找再从全局除非你加了hh:这样的说明才去hh域这个命名空间找相关的定义或声明局部域和全局域除了影响查找出处逻辑还影响着这三者的生命周期而命名空间域和类域不影响生命周期。Namespace 只能定义在全局它是可以嵌套定义的项目工程中多个文件定义的同名namespace会被认为是一个namespace这不会冲突C 标准库里的所有东西都在 std 这个 namespace 里。2三种使用方式方式一每次写全名最稳妥#include iostreamint main() {std::cout hello world std::endl;return 0;}方式二using 声明偷懒但安全#include iostreamusing std::cout;using std::endl;int main() {cout hello world endl;return 0;}方式三using namespace最偷懒但不推荐在大项目里用#include iostreamusing namespace std;int main() {cout hello world endl;return 0;}⚠️ 注意自己写小练习用 using namespace std; 没问题但以后进公司写大项目千万别这么干。3自定义 namespacenamespace wg {int age 20;void hello() {std::cout 我是 wg 班的 hello std::endl;}}int main() {std::cout wg::age std::endl;wg::hello();return 0;}三、函数重载1什么是函数重载在 C 语言里同一个函数名只能出现一次。你想写一个加整数和加浮点数的函数不好意思你得叫两个名字int add_int(int a, int b);double add_double(double a, double b);这也太麻烦了吧我能不能都叫 add 啊有的兄弟有的。C 说行啊你只要保证参数列表不一样参数个数不同、或者参数类型不同、或者顺序不同函数名相同完全没问题。这就叫函数重载。编译器会根据你传进去的参数自动判断你要调用哪个版本的函数。2代码示例// 版本1加两个整数int add(int a, int b) {return a b;}// 版本2加两个浮点数double add(double a, double b) {return a b;}// 版本3加三个整数int add(int a, int b, int c) {return a b c;}编译器是怎么分辨的它不看函数名都叫 add它看你括号里塞了什么东西。塞了两个 int就去第一个塞了两个 double就去第二个。重要注意点函数重载不能靠返回值不同来实现// 下面这俩同时存在会报错int func(int a);double func(int a); // 编译器你传入一个 int我到底调哪个四、引用reference1引用是个啥C 语言里你想修改函数外面的变量得传指针void swap(int* a, int* b) {int tmp *a;*a *b;*b tmp;}每次都要解引用*a还要传地址a麻烦得很。C 说咱整点高级的给你来个引用。引用就是给变量起个外号。打个比方你大名叫王狗蛋你小名叫狗蛋。别人喊王狗蛋或者狗蛋都是在叫你本人不是叫你隔壁老王。int a 10;int b a; // b 是 a 的引用外号注意这里的 不是取地址b 20; // 修改 b就是在修改 a 本人// 输出 a 为 20引用必须初始化而且一旦绑定就不能改绑。就像你生下来爸妈给你起了狗蛋这个小名这辈子它就专属于你不能哪天突然把这个外号送给别人。2引用做函数参数最常用引用的最大用处就是用在函数参数里实现看起来像传值实际上是在操作本体void swap(int x, int y) {int tmp x; // 不需要解引用了直接用爽x y;y tmp;}int main() {int a 10, b 20;swap(a, b); // 传的时候直接传变量不用写 areturn 0;}对比 C 语言的指针写法引用写 swap 不需要 * 解引用调用的时候也不需要 取地址代码干净多了。五、缺省函数默认参数1缺省函数是个啥缺省参数是在函数声明的时候给参数赋个初始值#include iostreamusing namespace std;// 函数声明给参数 b 和 c 设置了默认值int add(int a, int b 10, int c 100);int main() {cout add(1) endl; // 只传 ab 用 10c 用 100结果 111cout add(1, 2) endl; // 传 a 和 bc 用 100结果 103cout add(1, 2, 3) endl; // 全传结果 6return 0;}// 函数定义这里不能再写默认值了int add(int a, int b, int c) {return a b c;}注意嗷默认值是在函数声明的时候给的函数定义的时候不能再写一遍了。不然编译器会骂你你这不重复定义了吗2缺省参数的规矩缺省参数有个硬性规定必须从右往左连续缺省。打个比方你排队买奶茶缺省糖度、缺省冰度、缺省加料你只能从最后面开始缺。你不能说我要正常糖、缺省冰、正常加料中间缺一个后面又冒出来一个阿姨直接给你一个大白眼。代码里就是// ✅ 对的从右往左连续缺省void func(int a, int b 2, int c 3);// ❌ 错的中间缺了一个右边又不缺void func(int a, int b 2, int c); // 编译器你搁这玩跳房子呢// ❌ 错的左边缺了右边却不缺void func(int a 1, int b, int c 3); // 编译器回家吧孩子。记住这条规则一旦某个参数有了默认值它右边的所有参数都必须有默认值。这是语法规定没有为什么背就完事了。3缺省参数和函数重载的暧昧关系千万别同时用缺省参数和重载搞事情容易让编译器懵圈void print(int a);void print(int a, int b 10);print(5); // ❌ 编译器你到底要调用哪个第一个只有一个参数第二个可以只传一个用默认值...这种情况编译器会报ambiguous call歧义调用等着汗流浃背吧。所以记住缺省参数和重载可以各自单独用但别搅在一起。总结好咱今天聊了 C 入门的三个基础概念1. namespace命名空间防止名字打架。标准库在 std 里小练习可以 using namespace std; 偷懒大项目建议写全名或者用 using std::xxx;。2. 函数重载同一个函数名参数列表不同编译器自动帮你挑版本。记住返回值不同不算重载。3. 引用变量的外号用来做函数参数最香既能修改本体又不用像指针那样写一堆 * 和 。这些都是 C 的自动挡功能多用引用少滥用指针namespace 该写全就写全。