C/C++中的名字空间与作用域示例详解
再来看一个例子: #include <stdio.h> struct fun{ int a; int b; }; enum fun{ A,B,C }; int main() { return 0; } 结果:编译错误
原因: 再来看一个例子: #include <stdio.h> int a = 10; int b = 20; int main() { int b = 30; a = 50; printf("a = %d,b = %dn",a,b); return 0; } 结果:通过编译,没有问题 原因,变量loop和标号loop位于不同的名字空间,变量loop位于第四种名字空间,而标号loop位于第一种名字空间。 最后再看一个例子: #include <stdio.h> int a = 10; int b = 20; int main() { int b = 30; a = 50; printf("a = %d,b); return 0; } 结果,编译通过:且输出为: 原因 虽然全局变量和局部变量位于同一个名字空间中,都是位于第4中名字空间中,但是全局变量b的作用域为文件作用域,而局部变量b的作用域为块作用域,作用域小的b会将作用域大的b隐藏掉。 其实这就是我认为,作用域是名字空间的一个补充,的原因。 两个b有着同样的名字空间,但是有着大小不同的作用域,实际上文件作用域的作用范围是包含块作用域的作用范围的,这也是为什么在函数内部依然可以访问全局变量a的原因。作用域实际上是包含的关系,小的作用域会将大的作用域隐藏掉。但是名字空间之间却是相互独立的,这一点在C++中,自定义名字空间时,会体会的更深刻。 再次表明一下我的观点,我认为,作用域是对名字空间的一个补充,当在同一个名字空间中,用作用域来描述名字(也就是标识符)的可见性,小的作用域会隐藏大的作用域。 下面说说C++中的名字空间。 首先,C++中继承了C语言中的名字空间,也就是那四类名字空间在C++中依然适用。需要说明的是,类的名字,位于第二种名字空间中,类中的成员的名字位于第三种名字空间中,这一点和struct、enum等类似。 C++中允许我们自定义名字空间,自定义的方法就是适用namespace关键字。 先考虑这样一个问题: 一个工程中有多个.c文件,其中一个.c文件让柯南完成,另外一个.c文件让小兰完成。这两个人心有灵犀,都定义了一个叫conan的全局变量,这个时候当工程链接的时候就会报错。原因是两个conan有同样的名字空间,都是位于第4种名字空间中,也有着同样的作用域,都是文件作用域,于是这两个conan就冲突了。 怎么解决呢? 前面提到过,只有同一个名字空间中同一作用域下,相同的名字才会冲突。所以要解决冲突无非就是修改名字空间或者作用域。首先说修改作用域,前面提到过,文件作用域的标识符有一个链接属性,static修饰的,的作用域仅仅限于本.c文件,而extern(或者默认情况下)作用域是所有.c文件,所以我们可以个其中一个conan加上static修饰,这样就改变了作用域,就不会冲突了,但是问题是,我们既然定义成全局变量,通常情况下,我们都希望它有外部链接属性。我们之所以定义成全局变量,很可能就是为了让其他.c文件使用。所以static虽然解决了冲突,但是没有达到我们的目的。那么我们只能够用另一种方法解决冲突了,就是修改名字空间,这在C语言中是不可行的,因为C语言中就那4中名字空间。但是在C++中是可行的,因为C++可以自定义名字空间。 于是柯南将他的 namespace nan { int conan; } 小兰将他的int conan;写成了: namespace lan { int conan; } 这样柯南的conan就在名字空间nan中了,而小兰conan就在名字空间lan中了,就不冲突了。 但是需要注意,在其他文件中引用时,需要带上名字空间名比如, 至于namespace的详细用法,以及 最后提一下C语言中怎样解决命名冲突。 C语言中怎样解决命名冲突呢?C语言并不支持自定义名字空间,所以解决命名冲突貌似只能是:1、 如果可能的话用static修饰(有些情况是不能能用static修饰的,比如提供给外部使用的函数)2、在命名上下功夫,比如使用前缀,比如libnids库中的所有函数都是nids_开头的。 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程小技巧的支持。 (编辑:淮安站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |