[zt]挺好玩的C语句

Posted on 2007-08-06 17:00 daiybh 阅读(76) 评论(0)  编辑 收藏 引用
转自紫罗兰茶馆(http://blog.vckbase.com/lishengg_blog/) 我在学习VC,或者在阅读别人写的文章的时候,偶尔碰到下面很多有趣的,并且很奇怪的语句,整理起来,以备后忘. 其实有些是不大容易想到的技巧,贴出来权当大伙饭后没事的小品文,当然不要过多的看重类似的语句学习,而忽略了基础知识。 一. 奇怪的宏定义 (1) #define for if(0); else for 按照c++标准,for中定义的变量的作用域应该只在for循环中有效,而VC却不行,比如这样定义是不对的 for(int i=0;i<90;i++) { ...; } for(int i=0;i<90;i++) //重复定义i变量 { ...; } 如果加上标题的那句,那么就可以了,就是让i作用域局限在else中. 这个问题在net中已经得到解决。 二、宏定义怪圈 #define wait_event(wq,condition) \ do{ \ if(condition) \ break; \ __wait_event(wq,condition); \ }while(0) 明明这句话只执行一次,为什么还还用do-while语句呢? 假设有这样一个宏定义 #define macro(condition) \ if(condition) dosomething(); 现在在程序中这样使用这个宏: if(temp) macro(i); else doanotherthing(); 一切看起来很正常,但是仔细想想。这个宏会展开成: if(temp) if(condition) dosomething(); else doanotherthing(); 这时的else不是与第一个if语句匹配,而是错误的与第二个if语句进行了匹配,编译通过了,但是运行的结果一定是错误的。为了避免这个错误,我们使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。 这个用法在linux源码中很常见。 三、功能强大的解释 除了/* */和 //解释以外,你见过这样的解释方法了吗? #if(0) ........ #endif 这样是为了解释掉某段程序,而不影响其中的/*...*/的作用,便于调试,而/*.....*/是不能嵌套的,编译会出错. 四、数组变脸 a[i]和i[a] 在程序里本应该用a[i],但i[a]竟然和a[i]输出的结果一样。为什么。今天把问题整理如下: i[a]是标准语法。“[]”称为下标运算符,其语法为: postfix_expression [ expression ] 其中“postfix_expression”和“expression”之中必须有一个是指针类型(或数组),而另一个是整型。 例如下面的程序是完全合法的: int a[]={0,1,2,3,4}; printf("%d\n",3[a]); 下标运算符参与的表达式在求解时仅仅是做一个变换而已,将“postfix_expression [ expression ]” 改写为“ * ( postfix_expression + expression ) ”,因此a[3]和3[a]分别改写为*(a+3)和*(3+a), 可见二者是完全等价的。但注意不要用i[a]这种形式,因为它不符合日常习惯。 实验代码: #include "stdafx.h" #include "iostream.h" int f(); int main(int argc, char* argv[]) { int a[20]={1,2,3,4,5,6,7,8,9}; cout<

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理