C语言中的名字层次
来源:互联网 发布:船舶ais数据 编辑:程序博客网 时间:2024/05/05 15:15
P.J Plauger的"The Standard C Library"一书的Chapter0的章后练习中有这样的一道题:编写一个包含如下一行语句的正确的程序: x: ((struct x*)x)->x=x(5);
并描述这行语句中x的5种截然不同的use,这里其实涉及到这么一个知识或者说概念:C语言的命名空间(namespace),在"C语言参考手册"中还被称作: overloading class。 这 里namespace,并非C++中的那个keyword "namespace",这里的namespace更多是编译器为了识别不同范围下的标识符而进行的划分,而不是提供给应用程序员的类似c++中的那个 namespace facility。再次注意:C的namespace不是一个关键字。
简单分析一下这行语句:x: ((struct x*)x)->x=x(5); 这里有5个x,第一印象:这样的语句能编译过去么?那既然P.J Plauger提出了这样的问题,那么自然有solution。
从左到右顺序:
第一个x -- 毋庸置疑,这是一个标号(label) ;
第二个x -- 这里的x显然是一个struct tag(结构体标志);
第三个x -- 这里的x 无法确定其具体身份,可能是一指针类型,也可能就是一个整型;
第四个x -- x前面有->,显然这个x是某结构体的一个成员变量;
第五个x -- x(5)让人"浮想联翩",第一印象是函数调用,细致一想还可能是一个宏哦(你肯定会说不可能,呵呵,别着急,慢慢来) 到底如何增加一些语法元素能让这一行能顺利通过编译,并执行后得到合理结果呢?
我们不妨先来温习一下C标准中对C的"命名空间"的诠释。 在"C语言参考手册"中有如此说明,标准C将其Namespace分成了五种,分别是:
1) 预处理器宏名
2) 语句标号
3) 结构、枚举、联合结构的标志
4) 成员名
5) 其他名称 包括变量名、函数名、typedef名称和枚举常量
有了以上的说明,我们有了第一种方案:上面说了,语句x: ((struct x*)x)->x=x(5)中有三个x都是可以确定的,不确定的是第三个x和最后一个x。我们先考虑让最后一个x为一个函数。 考虑到最后一个名称空间的说明,一旦最后一个x为函数的话,第三个x就不能为变量名、typedef名称和枚举常量了。如果x是对象宏(不带参数的宏),显然也不合理;那么我们先将x实现为函数看看:
struct x { //for the 2nd x
int x; //for the 4th x };
int x(int a) { //for the 3rd and 5th x
return a; }
int main()
{
x: ((struct x*)x)->x=x(5);
}
这个在gcc(sunos or mingw on windows下)下编译能顺利通过。但是执行一下编译出的程序,会出现致命错误。初略分析一下也不奇怪。函数x的地址是在代码段,那块内存区域是只读且受保护的,尝试强制赋值显然os是不允许的。 第一种方案虽然能通过编译,但是执行结果不合理。
我们来做第二种尝试:试着将最后一个x实现为一个函数宏(带参数的宏)。
struct x { //for the 2nd x
int x; //for the 4th x };
struct x ax;
#define x(a) (a);
int main() {
int x = (int)(&ax);
x: ((struct x*)x)->x=x(5);
printf("%d/n", ((struct x*)x)->x); //output: 5
}
这回,我们得到了正确的且合理的solution了。在P.J Plauger的"The Standard C Library"一书中还有一张关于C语言命名空间的图,记起来更形象。
- C语言中的名字层次
- C 语言中的名字空间(namespace)
- C语言编程软件名字叫什么
- 层次状态机的实现 c语言
- 语言层次
- c语言打印当前源文件的名字、行数、函数名
- C语言:运行中获取宏名字的技巧
- C语言:运行中获取宏名字的技巧
- c语言标识符的名字空间和作用域
- C语言中枚举(enum)变量可以没有名字
- C语言:运行中获取宏名字的技巧
- C语言基础 优秀习惯起名字与赋初值
- R语言将层次聚类中的树分成簇
- 树的层次遍历(c语言描述)
- C语言基础-数据类型提升的层次结构
- (C语言)二叉树层次遍历(数据结构十六)
- 二叉树层次遍历(C语言实现)
- 数据结构 BFS层次遍历二叉树【C语言版本】
- OAF二次开发step by step(三)--对具体的BC4J对象的客户化
- .class文件与.project文件
- IBM对于IT的新注解
- 花千树
- JSF学习总结
- C语言中的名字层次
- 关于 page,request,application,session的作用域(转)
- 快到三十
- 灵魂挣扎
- 想翻译Memory Management Algorithms and Implementation in c/c++
- C# 环境变量的配置
- OAF二次开发step by step(四)--OAF二次开发程序的部署
- C# 环境变量的配置
- LDAP是什么?