.命名空间的引入首先看一段代码代码语言javascriptAI代码解释#include stdio.h int rand 10; int main() { printf(%d\n, rand); return 0; }编译并不会报错但如果加上头文件stdlib呢在这里插入图片描述编译器告诉我们rand重定义了以前的定义是变量而在stdlib这个库中rand是一个函数将头文件展开变量rand会和库里面的rand函数冲突 我们在编码时会创建很多的变量、函数我们并不能保证每个变量和函数都不能同名或者是不和库中的函数重名所以我们引入关键字namespace基本格式如下代码语言javascriptAI代码解释namespace name { }namespace的本质是定义一个命名空间域避免头文件展开后会和库函数冲突这个域跟全局域各自独立不同的域可以定义同名变量代码语言javascriptAI代码解释#include stdio.h #include stdlib.h // 引入namespace进行命名隔离 namespace Vect { int rand 0; } int main() { printf(%d, Vect::rand); return 0; }编译通过在这里插入图片描述下面介绍namespace的一些性质1.1.namespace的性质不影响变量/函数的生命周期仅作名字的隔离作用namespace只能定义在全局可以嵌套定义多文件下同名的命名空间会进行合并代码语言javascriptAI代码解释#include stdio.h #include head1.h namespace Vect { // 1. 命名空间可以定义变量/函数/类型 int num 10; int* ptr num; void Print() { printf(HELLO,C!\n); } struct node { int val; struct node* next; }; // 2. 命名空间可以嵌套定义 namespace coke { // ... } } int main() { return 0; }1.2.namespace的使用编译器在编译时会按照一定的顺序进行查找变量/函数/类型 1. 局部域通俗理解是自己家 2. 全局域通俗理解是公共区域展开的命名空间别人家声明你可访问这两个域相同优先级而查找命名空间也有三种方式using将命名空间中某个成员展开项目中推荐这种方式使用域作用限定符::指定查找using展开全部的命名空间项目中非常不推荐日常练习无所谓代码语言javascriptAI代码解释#include stdio.h // 使用方法 // 1.域作用限定符指定访问 int num 10; namespace Vect { int num 0; char ch ?; } int main() { printf(%d\n, Vect::num); printf(%c\n, Vect::ch); // 若域作用限定符左边无命名空间默认查找全局域 printf(%d\n, ::num); printf(%d\n, num); }在这里插入图片描述代码语言javascriptAI代码解释// 2. using展开局部对象 namespace Vect { int num 0; char ch ?; } using Vect::num; int main() { printf(%d\n, num); printf(%c\n, Vect::ch); // 若域作用限定符左边无命名空间默认查找全局域 }![[Pasted image 20250626191832.png]]代码语言javascriptAI代码解释// 3. using展开全体对象 namespace Vect { int num 0; char ch ?; } using namespace Vect; int main() { printf(%d\n, num); printf(%c\n, ch); // 若域作用限定符左边无命名空间默认查找全局域 }在这里插入图片描述思考局部域、全局域、命名空间域有什么联系和区别局部域、全局域和命名空间域是 C 中三种作用域局部域在函数或代码块内部只在当前块内有效。全局域定义在所有函数外部整个程序都能访问可能需要注意extern。命名空间域用来组织代码防止命名冲突通过namespace::变量展开局部变量或者全部展开三种方式访问。三者的区别在于作用范围和访问方式它们之间可以嵌套使用但同名时遵循局部优先原则命名空间通过域作用限定符来区分。实际开发中我们倾向使用局部变量和命名空间来增强代码的可读性和安全性尽量少使用全局变量。