看下面例子

在C语言中我们学过局部优先原理,所以上述代码输出了20,那么我们就是想输出10,那么该怎么输出呢?这时就需要用到预作用分解符了

在输出rand时,在前面加上::就能够输出10了。
::的作用可以理解为改变查找规则,在C语言中默认的查找规则就是先局部,后全局。而如果有了::就可以实现直接去全局找而不去局部,::还可以指定直接去特定的域中查找。
::的前面如果什么都不加,就代表直接去全局中找,而如果::的前面加了域名,就会直接去该域中查找。
看下面代码



我们都知道在头文件stdlib.h中有个函数叫rand,而在引用了该文件的同时在全局定义变量rand时就会出现命名冲突,而在局部定义变量rand时,就不会出现命名冲突。这个也很正常,因为局部和全局是两个不同的域,并且在局部定义的也输出了10,在全局的rand也输出了该函数的地址。
那么这时就有一个问题,我们怎么样才能够在全局再定义一个rand呢?这时就需要命名空间了。

这里用到了关键字namespace,后面跟上我们自定义的名字haha和大括号,这时名为haha的域就建立好了,我们在里面创建变量就不会和域外面的起冲突了,当然了在同一块域中也是会存在命名冲突的问题的。
需要注意的是,在haha中的变量rand和在全局中的变量性质是一样的,都是存放在静态区的,只是给rand建了一座围墙haha,我们首先遵循的规则是先局部、后全局,在main函数中并没有定义rand,所以去全局找,注意此时haha中的rand也是在全局的,但是这里并没有输出10,而是输出了stdlib.h中的rand函数的地址,那是因为我们去全局找的时候找不到haha中的rand,因为有haha这座围墙着,所以我们如果想输出10,就得用到::。

上面说到::是改变查找规则的,我们在::前面写上我们指定的域haha,这时就会直接去haha中查找rand。
::和命名空间呢?我们可以把命名空间想象成一座围墙,在命名空间里的变量和其它的任何变量并无区别,只是加上了一座围墙,使得编译器去寻找的时候找不到命名空间里的变量。而::就可以理解为一把钥匙,::可以进入指定的围墙里面,使得编译器去寻找的时候就能够找到命名空间里的变量。