📌 相关专栏
- 【Linux专栏】
- 【C语言专栏】
- 【测试专栏】
- 【MySQL专栏】
- 【C++ 专栏】
📌 相关文章推荐
- 【测试】软件测试入门必看:需求、开发模型、测试模型全解析
- 【Linux】硬件架构+系统软件:冯诺依曼与操作系统深度剖析
- 【Linux 】 网络基础必备常识1,零基础快速吃透
- 【Linux】玩转Socket,快速掌握UDP数据传输
很高兴你点开这篇文章✨
这里会持续更新我喜欢的内容,关注我,一起慢慢变好呀
👍 点赞 ⭐ 收藏 💬 评论
文章目录
- 前言
- 一、C++的第一个程序
- 二、从一个“冲突”问题开始
- 三、域:我们可以理解为C++ 的“隔离墙”
- 四、namespace:给名字一个“家”
- 五、命名空间可以嵌套
- 六、using namespace std 到底在干嘛?他能够自动识别类型!
- 七、`C++` vs` C` :输入输出
- 八、本文全部代码
前言
C++ 命名空间与输入输出:从“名字冲突”到“域隔离”
- 你写的第一个 C++ 程序可能和我一样:cout << “hello world” << endl;
- 但为什么需要 using namespace std?
- namespace 到底解决了什么问题?
🐾 这篇文章带你用代码理解 C++ 的域与命名空间。
🐶 🐾 ✨ 🐾 🐶
一、C++的第一个程序
C++兼容C语言绝大多数的语法,所以C语言实现的 hello world 依旧可以运行,C++中需要把定义文件代码后缀改为.cpp,vs编译器看到是.cpp就会调用C++编译器编译,linux下要用g++编译,不再是gcc
🐾 C :
//test.cpp#include<stdio.h>intmain(){printf("hello world\n");return0;}当然C++有⼀套⾃⼰的输⼊输出,严格说C++版本的hello world应该是这样写的。
🐾 C++ :
//test.cpp#include<iostream>usingnamespacestd;intmain(){cout<<"hello world"<<endl;return0;}🐶 🐾 ✨ 🐾 🐶
二、从一个“冲突”问题开始
C++ 允许我们定义变量、函数、结构体。
但项目一大,很容易出现同名冲突。
比如:
#include<stdlib.h>intrand=10;// 编译错误:rand 已经是函数名- 因为 stdlib.h 里已经有一个 rand() 函数。
- C++ 中,全局空间是共用的,同名就会冲突。
三、域:我们可以理解为C++ 的“隔离墙”
🐾 C++ 中的域分为四类:
| 域类型 | 作用 | 影响生命周期 |
|---|---|---|
| 局部域 | { } 内 | 是 |
| 全局域 | 所有函数外部 | 是 |
| 命名空间域 | namespace 定义 | 否 |
| 类域 | class / struct 内部 | 否 |
🐾 域的核心作用:
告诉编译器“去哪里找这个名字”。
编译器默认查找规则(不指定域时):
- 先局部域,全局域
inta=11;// 全局intmain(){inta=1;// 局部printf("%d\n",a);// 1(局部优先)printf("%d\n",::a);// 11(:: 强制全局)return0;}::叫做 域作用限定符
- 有这个操作符的情况下,系统的搜索逻辑就是访问全局优先
- 左边不写 = 全局,左边写名字 = 指定命名空间/类(如Date::a)
四、namespace:给名字一个“家”
🐾 基本用法
namespaceCC{intrand=10;intAdd(intleft,intright){returnleft+right;}}🐾 访问时:
printf("%d\n",CC::rand);// 10printf("%d\n",CC::Add(2,3));🐾 为什么 rand 不冲突了?
- 全局 rand 是函数
- CC::rand 是变量
- 它们在不同的命名空间域,编译器可以区分。
五、命名空间可以嵌套
namespaceCC{namespacedy{intrand=1;}namespaceqe{intrand=2;}}printf("%d\n",CC::dy::rand);// 1printf("%d\n",CC::qe::rand);// 2🐾 适合大型项目的模块分层(例如 公司::项目::模块)
六、using namespace std 到底在干嘛?他能够自动识别类型!
🐾C++ 标准库所有内容都在 std 命名空间中:
#include<iostream>// 如果没有 using 或 std::cout << "hello"; 就会错误// 方法1:全量打开usingnamespacestd;// 方法2:部分展开(推荐)usingstd::cout;usingstd::endl;// 方法3:显式使用(最安全)std::cout<<i<<std::endl;不推荐随便 using namespace std 的原因
一旦打开,你写的 vector、sort 就可能与标准库冲突。
公司/开源项目一般写 std::cout,或在 .cpp 局部展开。
七、C++vsC:输入输出
| 功能 | C | C++ |
|---|---|---|
| 输出 | printf | std::cout << |
| 输入 | scanf | std::cin >> |
| 换行 | \n | std::endl 或 “\n” |
| 类型 | 必须用格式化符 | 自动识别类型 |
| 安全 | 较低(格式错误) | 较高(编译时检查,但不是绝对) |
🐾 示例
doubles=2.22222;printf("%.2f",s);// 2.22std::cout<<s;// 2.22222(不截断)std::cin>>i>>s;// 类似 scanfstd::cout<<"i="<<i;🐾 cout / cin 优势:
- 无需记忆
%d %f %p - 可连续链式输出
- 性能略低于 printf
🐶 🐾 ✨ 🐾 🐶
八、本文全部代码
#define_CRT_SECURE_NO_WARNINGS1////初学C++的第一个代码,它的头文件通常不带.h.如<iostream.h>是错的//#include<iostream>//using namespace std; //std类似一个工具箱,用这句代码意思就是工具箱打开,里面的工具随你用//int main() //cout(输出),endl(换行),cin(输入),string(字符串),vector、map(容器),sort(算法)...都是std里的工具//{// cout << "hello world" << endl; //cout->printf;endl->换行符(\n)// return 0;//}//////////////////////////////////////////////////////////////////////////////////// C++中域有函数局部域,全局域,命名空间域,类域// //域影响的是编译时语法查找一个变量/函数/类型出处(声明或定义)的逻辑,当有了域隔离,名字冲突就解决了// //局部域和全局域除了会影响编译查找逻辑,还会影响变量的生命周期,命名空间域和类域不影响变量生命周期//接下来了解namespace////#include<iostream>//#include<stdlib.h>//namespace CC//{// int rand = 10; //rand 是个函数名,<stdlib.h>里也一个rand;// //当程序出现里另一个rand 时(也就是这里的rand)就会报错,用namespace就可以加以区分了// //放在cout里rand会被当成函数指针,输出的是一串地址数字// int Add(int left, int right)// {// return left + right;// }// struct Node// {// struct Node* next;// int val;// };//}//int a = 11; //这里出现两个a,系统会要那个呢?// //系统的搜索逻辑在没有指定域的情况下就是:先局部,再全局;所以第一个printf输出的值是1//int main()//{// int a = 1;// printf("%d\n", a);// printf("%d\n", ::a); //::是域作用限定符,有这个操作符的情况下,系统的搜索逻辑就是访问全局优先// //::前面如果没有写其他东西就是全局访问,如果有,就是先访问该域(如Date::a)//// printf("%p\n", rand); //在cout(printf)里,rand是个函数指针,打印出来的是地址数字,所以用%p// printf("%d\n", CC::rand); //用来访问命名空间namespace里的rand,输出结果就是10了//// printf("%p\n", CC::Add); //这里如果不指定(即访问全局),编译器就会报错,因为Add在局部里// printf("%d\n",CC:: Add(2,3));//// return 0;//}////////////////////////////////////////////////////////////////////////////////////////////////////////namespace还可以嵌套////#include<iostream>////namespace CC//{// //// namespace dy// {// int rand = 1;// int Add(int left, int right)// {// return left + right;// }// }// //// namespace qe// {// int rand = 2;// int Add(int left, int right)// {// return left + right;// }// }//}////int main()//{// printf("%d\n", CC::dy::rand);//1// printf("%d\n", CC::qe::rand);//2// return 0;//}//////////////////////////////////////////////////////////////////////////////////////////////////自动识别类型#include<iostream>//using namespace std;//using std::cout;//using std::endl;intmain(){inti=1;doubles=2.22222;//cout <<i << endl; //这里如果不加std::,他就会报错,因为cout和endl是头文件<iostream>定义的全局对象//下面的cin也用不了std::cout<<i<<std::endl;;//要么在文件开头写上 using namespace std//他也可以部分展开:using std::cout;// using std::endl;//为了避免我们定义的东西和库里面的冲突std::cout<<"nihao"<<" "<<"ma"<<std::endl;//会自动识别出空格符printf("%.2f",s);//保留两位小数std::cin>>i>>s;//类似scanfstd::cout<<"i="<<i<<std::endl;std::cout<<"s="<<s<<std::endl;return0;}🐶 🐾 ✨ 🐾 🐶
小狗举爪爪求关注啦!🥺
你的关注,就是我更新的最大动力~
👍 点赞 ⭐ 收藏 💬 评论