在c语言中,我们知道有两个作用域,全局作用域和局部作用域,也就是函数作用域。我们通常将在很多局部作用域中出现的变量定义为全局变量,这样避免了很多的传参步骤,节约了时间,比如:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int a = 10, b = 20;
int add()
{
return a - b;
}
int sub()
{
return a - b;
}
int mul()
{
return a * b;
}
int div()
{
return a / b;
}
int main()
{
printf("%d %d %d %d\n", add(), sub(), mul(), div());
return 0;
}
这样写就比
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int add(int a, int b)
{
return a - b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
int a = 10, b = 20;
printf("%d %d %d %d\n", add(a, b), sub(a, b), mul(a, b), div(a, b));
return 0;
}
这样写要方便得多;
但是有时也会有尴尬的情况发生,比如:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
int rand()
{
printf("hello world\n");
return 1;
}
int main()
{
int* p = (int *)malloc(sizeof(int) * 10);
return 0;
}
这里比较先进的编译器就会报警告⚠,说参见"rand"的前一个定义,但是比较落后的编译器就会报错,因为在头文件stdlib.h中就有一个rand函数
这里如果又要定义一个rand函数又要使用stdlib.h头文件怎么实现呢?
引入一个命名空间的概念,命名空间可以理解成一个coder自己创建出来的作用域,在这个作用域里面,变量和函数是独立的。
这里先介绍一下命名空间的使用方法 和结构体很类似
结构体就是
struct xxx
{
//变量,函数,结构体嵌套....
};
命名空间是
namespace xxx
{
//变量,函数,结构体....
}
如果将上面的代码写成:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
namespace csdn
{
int rand()
{
printf("hello world\n");
return 1;
}
}
int main()
{
int* p = (int *)malloc(sizeof(int) * 10);
return 0;
}
就不会有报错/警告了;
那么再思考一个问题,既然是一个作用域的存在,可以不可以存在两个名字相同的命名空间呢?
答案是可以的
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
namespace csdn
{
int a = 10;
int b = 20;
}
namespace csdn
{
int c;
int d;
}
using namespace csdn;
int main()
{
printf("%d\n", a);
return 0;
}
这样写,并不会报错,但是要注意,两个相同的命名空间里面不可以有相同名字的变量或者函数。因为编译器对两个名字相同的命名空间的处理方法是将他们合并成一个,但是有了相同的就等于在一个作用域中重复定义,到底该听谁的呢0.0
说完了命名空间的定义,再介绍一下如何使用命名空间内部的变量
作用域访问限定符:: 使用方法就是 命名空间名 :: 命名空间内部的变量名
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
int a = 1;
int b = 2;
namespace csdn
{
int a = 10;
int b = 20;
}
int main()
{
int a = 100;
int b = 200;
printf("%d %d\n", a, b);
return 0;
}
如果这样,输出的结果应该是哪个a,哪个b呢
如果我要输出的是csdn命名空间里面的a和b呢?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
int a = 1;
int b = 2;
namespace csdn
{
int a = 10;
int b = 20;
}
int main()
{
int a = 100;
int b = 200;
printf("%d %d\n", csdn :: a, csdn :: b);
return 0;
}
这样就输出了csdn里面的a和b
那如果要输出全局变量的a和b呢?全局变量好像没有命名空间名啊?
那就不加不就好了..
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
int a = 1;
int b = 2;
namespace csdn
{
int a = 10;
int b = 20;
}
int main()
{
int a = 100;
int b = 200;
printf("%d %d\n", :: a, :: b);
return 0;
}
全局作用域就是 :: 前面没有任何的字符!
现在不仅要用命名空间中的变量名,而且命名空间中的某个变量用的次数很多,又不想每次都命名空间::变量名,那应该怎么办呢
可以直接将命名空间中的变量变成全局变量
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
namespace csdn
{
int a = 10;
int b = 20;
}
using csdn::a;
int main()
{
printf("%d\n", a);
return 0;
}
但是要注意,我们在这里using csdn ::a之后就不可以再在全局变量中定义a了,因为这个时候a已经是全局作用域里的东西了,再定义相当于是重复定义
而如果整个命名空间中的变量名用的次数都很多,我们可以直接将整个命名空间都using了
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
namespace csdn
{
int a = 10;
int b = 20;
}
using namespace csdn;
int main()
{
printf("%d\n", a);
return 0;
}
这里其实和之后很多cpp程序用到的using namespace std;是一样的
但是要注意,这里我们人为定义一个命名空间并且将其全部内容定义为全局的,如果函数命名的很不巧,很容易和头文件里的内容冲突。此方法小心使用~