既然,你对这个有兴趣,我又正好现在没事,就跟你好好聊聊,希望你有耐心看完。
#define alland(x,y,z) (x) = (x) & (y) & (z)
#define allor(x,y,z) (x) = (x) | (y) | (z)
#define andthenor(x,y,z) (x) = (x) & (y) | (z)
#define andafteror(x,y,z) (x) = (x) & ((y) | (z))
#define orthenand(x,y,z) (x) = (x) | (y) & (z)
#define orafterand(x,y,z) (x) = (x) | ((y) & (z))
由此,可以看出,只要你定义的足够的多,就能有“第二种写法” 应对各种情况。 但是,如果你都用这种方法写代码,自己写是没有问题,如果这代码转给第三人看,或者发帖求助,别人是劈死你的心都有。
那么,既然换一种写法有那么多人会不爽,为什么 会有 a &=b; 和 a = a & b; 编译器自带的这两种写法呢?这个牵涉到历史遗留问题,别急,会跟你讲清楚的。
最开始,最正统的C语言,是只有 a = a & b; 这一种写法的, 等号左边是赋值目的地,等号右边是表达式,或者说计算方式。这个表达方式用现在的话来讲, 很"C语言"。
那么为什么后来会引入(或者说创造出) a &= b; 这种不正统的书写方式呢? 受环境所迫。就和现在新产品面世,必须要推广建立用户基础一样,C语言推出之初,是没有用户基础的,那时候大多数人都在用A语言,即汇编。C语言门槛低,适合初学者,这是没错,但是,每人愿意学啊,就好像屠龙绝技学了,之后你没有龙可以屠,有什么用呢? 初学者学了C, 开发团队的前辈们还在用A, 这怎么搞?(当时并没有汇编和C混合编程这个功能的)。于是,让已经编程多年的老手,转移到C ,成了关键。其中商业当中的运作,弯弯绕绕就不讲了,直接跳到关键点。 C语言的语法,对用了一辈子汇编的人来说,是非常不友好的。为了让这些人更快的掌握C, 于是C语言非常“贴心”的增加了,符合汇编人的书写习惯的“第二种写法”。
比如说: a = a & b; 他的意思是,把 a 和 b 相与 并且,把结果保存到 a
汇编中,没有这种写法的,汇编中只有类似这样的: ANL A,B 即把 B 的值 与到 A, 汇编中不需要考虑结果保存去哪里,也不能考虑结果保存在哪里,
所以,针对汇编用户的习惯, C语言 “很贴心” 的 增加了 a &= b; 这种 “很汇编” 的写法。 同类的还有很多,
比如: a |= b; 对应: ORL A,B
比如: a +=b; 对应: ADD A,B
比如: a++ 对应: INC A
比如: a-- 对应: DEC A又比如: while(!TI); 对应: JNB TI,$ 正统的写法应该是用表达式: while(TI == 0) 等等,很多很多。
总之,为了拉拢这批 老编程员 投入C的怀抱,提供了大量的“很汇编”的“第二种写法”。
所以,刚开始的时候,这一类的 “不怎么C” 的C语言,反而是使用频率最高的。而新人们,虽然可能没有学过汇编,看到前辈们这样写,为了不给前辈们增加阅读成本,也尽量的这么写。(现在看来,以前的新人们真的很贴心)。 所以,这些新人们,也习惯了使用这种“非标”的C代码,久而久之本来作为权益之计的“第二种书写法”就根深蒂固的成为了一种标准书写规范。哪怕进化到了 TC , C++, 都一直延续保留了下来。
扯远了,我们扯回来。重点来了:
你会经常在看别人的代码里看到 a &= b; a +=b; 这些“非标”的书写方式, 但是,你很好奇 a = a & b & c 有没有类似的写法,因为你在别人的代码里没有机会看到。 那么,为什么你会看不到呢? 不是因为没有,不是因为写不出来, 因为 a = a & b & c 完全不符合 汇编逻辑。 所以不会有人使用 “很汇编” 的写法,去写这样的表达式,所以,你看不到实例。 硬写是可以的, 根据实际应用情况, 可以写成 a &= b & c; 也可以由第三种写法,但是,这样做就刻意了。 老汇编程序员, 把 a = a & b; 写成 a &= b; 可以提高阅读效率,降低阅读成本, 但是 a &= b & c 这种写法,对于习惯汇编逻辑的老程序员一样是要绕脑子的。 所以,他本人不会这样写, 新人们也不会这样写,因此,你基本不会在他人程序里面看到,假如有看到,那么这个人一定是 刻意装X的,决不是习惯问题,或者编程逻辑问题。
洋洋洒洒写了一大堆,主要是让你了解一下,有多种写法的历史背景,以及为什么很多人会习惯用一些 “很不C” 的 “第二种写法”。 算是“科普”吧。
|