L*****e 发帖数: 8347 | 1 很早就想写这样一篇博文了,可是一直没来得及动笔。在学校的时候,时间似乎总是不
够用,因为一旦有点时间,你就想是不是该用来多看点论文。所以我很高兴,工作的生
活给了我真正自由的时间,让我可以多分享一些自己的经验。
我今天想开始写这系列文章的原因是,很多程序员的头脑中都有一些通过“非理性”方
式得到的错误观点。这些观点如此之深,以至于你没法跟他们讲清楚。即使讲清楚了,
一般来说也很难改变他们的习惯。
程序员的世界,是一个“以傲服人”的世界,而不是一个理性的,“以德服人”的世界
。很多人喜欢在程序里耍一些“小聪明”,以显示自己的与众不同。由于这些人的名气
和威望,人们对这些小聪明往往不加思索的吸收,以至于不知不觉学会了很多表面上聪
明,其实导致不必要麻烦的思想,根深蒂固,难以去除。接着,他们又通过自己的“傲
气”,把这些错误的思想传播给下一代的程序员,从而导致恶性循环。人们总是说“聪
明反被聪明误”,程序员的世界里,为这样的“小聪明”所栽的根头,可真是数不胜数
。以至于直到今天,我们仍然在疲于弥补前人所犯下的错误。
所以从今天开始,我打算陆续把自己对这些“小聪明”的看法记录在这里,希望看了的
人能够发现自己头脑里潜移默化的错误,真正提高代码的“境界”。可能一下子难以记
录所有这类误区,不过就这样先开个头吧。
小聪明1:片面追求“短小”
我经常以自己写“非常短小”的代码为豪。有一些人听了之后很赞赏,然后说他也很喜
欢写短小的代码,接着就开始说 C 语言其实有很多巧妙的设计,可以让代码变得非常
短小。然后我才发现,这些人所谓的“短小”跟我所说的“短小”,完全不是一回事。
我的程序的“短小”,是建立在语义明确,概念清晰的基础上的。在此基础上,我力求
去掉冗余的,绕弯子的,混淆的代码,让程序更加直接,更加高效的表达我心中设想的
“模型”。这是一种在概念级别的优化,而程序的短小精悍只是它的一种“表象”。这
种短小,往往是在“语义” (semantics) 层面的,而不是在“语法”层面死抠几行代
码。我绝不会为了程序“显得短小”而让它变得难以理解,或者容易出错。
相反,很多其它人所追求的“短小”,却是盲目的,没有原则的。在很多时候,这些小
伎俩都只是在“语法” (syntax) 层面,比如,想办法把两行代码写成一行。可以说,
这种“片面追求短小”的错误倾向,造就了一批语言设计上的错误,以及一批“擅长于
”使用这些错误的程序员。
举一个简单的例子,就是很多语言里都有的 i++ 和 ++i 这两个“自增”操作(下文合
称“++操作”。很多人喜欢在代码里使用这两个东西,因为这样可以“节省一行代码”
。殊不知,节省掉的那区区几行代码,比起由此带来的混淆和错误,其实是九牛之一毛。
从理论上讲,++操作本身就是错误的设计。因为它们把对变量的“读”和“写”两种根
本不同的操作,毫无原则的合并在一起。这种对读写操作的混淆不清,带来了非常难以
发现的错误,甚至在某些时候带来效率的低下。
相反,一种等价的,“笨”一点的写法,i = i + 1,不但更易理解,而且更符合程序
内在的一种精妙的“哲学”原理。这个原理,其实来自一句古老的谚语:你不能踏进同
一条河流两次。也就是说,当你第二次踏进“这条河”的时候,它已经不再是之前的那
条河!这听起来有点玄,但是我希望能够用一段话解释清楚它跟 i = i + 1 的关系:
现在来想象一下你拥有明察秋毫的“写轮眼”,能看到处理器的每一步微小的操作,每
一个电子的流动。现在对你来说,i = i + 1 的含义是,让 i 和 1 进入“加法器”。
i 和 1 所含有的信息,以 bit 为大小,被加法器的线路分解,组合。经过一番复杂的
转换之后,在加法器的“输出端”,形成一个“新”的整数,它的值比 i 要大 1。接
着,这个新的整数通过电子线路,被传送到“另一个”变量,这个变量的名字,“碰巧
”也叫做 i。特别注意我加了引号的词,你是否能用头脑想象出线路里面信息的流动?
我是在告诉你,i = i + 1 里面的第一个 i 跟第二个 i,其实是两个完全不同的变量
——它们只不过名字相同而已!如果你把它们换个名字,就可以写成 i2 = i1 + 1。当
然,你需要把这条语句之后的所有的 i 全都换成 i2(直到 i 再次被“赋值”)。这
样变换之后,程序的语义不会发生改变。
我是在说废话吗?这样把名字换来换去有什么意义呢?如果你了解编译器的设计,就会
发现,其实我刚刚告诉你的哲学思想,足以让你“重新发明”出一种先进的编译器技术
,叫做 SSA(static single assignment)。我只是通过这个简单的例子让你意识到,
++操作不但带来了程序的混淆,而且延缓甚至阻碍了人们发明像 SSA 这样的技术。如
果人们早一点从本质上意识到 i = i + 1 的含义(其实里面的两个 i 是完全不同的变
量),那么 SSA 可能会提前很多年被发明出来。
(好了,到这里我承认,想用一段话讲清楚这个问题的企图,失败了。)
所以,有些人很在乎 i++ 与 ++i 的区别,去追究 (i++) + (++i) 这类表达式的含义
,追究 i++ 与 ++i 谁的效率更高,…… 其实都是徒劳的。“精通”这些细微的问题
,并不能让你成为一个好的程序员。真正正确的做法其实是:完全不使用 i++ 或者 ++
i。
当然由于人们约定俗成的习惯,在某种非常固定,非常简单,众人皆知的“模式”下,
你还是可以使用 i++ 和 ++i。比如: for (int i=0; i < n; i++)。但是除此之外,
最好不要在任何其它地方使用。特别不要把 ++ 放在表达式中间,或者函数的参数位置
,比如 a[i++], f(++i) 等等,因为那样程序就会变得难以理解,容易出错。如果你把
两个以上的 ++ 放在同一个表达式里,就会造成“非确定性”的错误。这种错误会造成
程序可能在不同的编译器下出现不同的结果。
虽然我对这些都了解的非常清楚,但我不想继续探讨这些问题。因为与其记住这些,不
如完全忘记 i++ 和 ++i 的存在。
好了,一个小小的例子,也许已经让你意识到了片面追求短小程序所带来的巨大代价。
很可惜的是,程序语言的设计者们仍然在继续为此犯下类似的错误。一些“新”的语言
,设计了很多类似的,旨在“缩短代码”,“减少打字量”的雕虫小技。也许有一天你
会发现,这些雕虫小技所带来的,除了短暂的兴奋,剩下的就是无尽的烦恼。
思考题:
1. Google 公司的代码规范里面规定,在任何情况下 for 语句和 if 语句之后必须写
花括号,即使 C 和 Java 允许你在其只包含一行代码的时候省略它们。比如,你不能
这样写
for (int i=0; i < n; i++)
some_function(i);
而必须写成
for (int i=0; i < n; i++) {
some_function(i);
}
请分析:这样多写两个花括号,是好还是不好?
(提示,Google 的代码规范在这一点上是正确的。为什么?)
2. 当我第二次到 Google 实习的时候,发现我一年前给他们写的代码,很多被调整了
结构。几乎所有如下结构的代码:
if (condition) {
return x;
} else {
return y;
}
都被人改成了:
if (condition) {
return x;
}
return y;
请问这里省略了一个“else”和两个花括号,会带来什么好处或者坏处?
(提示,改过之后的代码不如原来的好。为什么?)
3. 根据本文对于 ++ 操作的看法,再参考传统的图灵机的设计,你是否发现图灵机的
设计存在类似的问题?你如何改造图灵机,使得它不再存在这种问题?
(提示,注意图灵机的“读写头”。)
4. 参考这个《Go 语言入门指南》,看看你是否能从中发现由于“片面追求短小”而产
生的,别的语言里都没有的设计错误? |
g*****g 发帖数: 34805 | 2 这篇写得倒还不错。关于coding style其实Sun的java coding convention写得很好,
其中就包括了这个if必须加花括号。
至于++i, i++,本人只用i++,除了for以外,每次都独立一行。 |
L*****e 发帖数: 8347 | 3 好虫给讲讲他的思考题第二题?
2. 当我第二次到 Google 实习的时候,发现我一年前给他们写的代码,很多被调整了
结构。几乎所有如下结构的代码:
if (condition) {
return x;
} else {
return y;
}
都被人改成了:
if (condition) {
return x;
}
return y;
请问这里省略了一个“else”和两个花括号,会带来什么好处或者坏处?
【在 g*****g 的大作中提到】 : 这篇写得倒还不错。关于coding style其实Sun的java coding convention写得很好, : 其中就包括了这个if必须加花括号。 : 至于++i, i++,本人只用i++,除了for以外,每次都独立一行。
|
g*****g 发帖数: 34805 | 4 这个在我看来没什么差别。不存在一行代码变两行,逻辑会出错而且编译器通过的可能
。也许C缺省返回0的能有点差别。java是没啥区别的。
我个人喜欢比较简洁的那种模式。有时候会有一堆特殊情况,先给处理了,剩下的是
通用例子的情况。
【在 L*****e 的大作中提到】 : 好虫给讲讲他的思考题第二题? : 2. 当我第二次到 Google 实习的时候,发现我一年前给他们写的代码,很多被调整了 : 结构。几乎所有如下结构的代码: : if (condition) { : return x; : } else { : return y; : } : 都被人改成了: : if (condition) {
|
s********k 发帖数: 6180 | 5 第二个方法怎么看着这么别扭,如果真的要实现特殊情况和通用,这样写还不如goto这
种被人唾弃的清楚
【在 g*****g 的大作中提到】 : 这个在我看来没什么差别。不存在一行代码变两行,逻辑会出错而且编译器通过的可能 : 。也许C缺省返回0的能有点差别。java是没啥区别的。 : 我个人喜欢比较简洁的那种模式。有时候会有一堆特殊情况,先给处理了,剩下的是 : 通用例子的情况。
|
p*****2 发帖数: 21240 | 6
我跟goodbug一样,喜欢第二种。
【在 s********k 的大作中提到】 : 第二个方法怎么看着这么别扭,如果真的要实现特殊情况和通用,这样写还不如goto这 : 种被人唾弃的清楚
|
s***o 发帖数: 6934 | 7 agree
【在 g*****g 的大作中提到】 : 这篇写得倒还不错。关于coding style其实Sun的java coding convention写得很好, : 其中就包括了这个if必须加花括号。 : 至于++i, i++,本人只用i++,除了for以外,每次都独立一行。
|
L*****e 发帖数: 8347 | 8 我也是用第二种。他的这个问题可以换一个角度考虑,是不是写了if就一定要写else?
如果不是,答案就清楚了。。。
【在 p*****2 的大作中提到】 : : 我跟goodbug一样,喜欢第二种。
|
d*******r 发帖数: 3299 | |
X****r 发帖数: 3557 | 10 我个人倒是更喜欢第一种,因为不需要看到那个return就能知道后面的语句在条件成立
的时候不会被执行,看代码的时候可以省个半秒钟。不过同事习惯比自己习惯更重要,
所以现在还是按第二种在写。
【在 L*****e 的大作中提到】 : 我也是用第二种。他的这个问题可以换一个角度考虑,是不是写了if就一定要写else? : 如果不是,答案就清楚了。。。
|
|
|
t***a 发帖数: 416 | 11 嗯,我也觉得第二种是更主流一点的习惯。。。。
【在 X****r 的大作中提到】 : 我个人倒是更喜欢第一种,因为不需要看到那个return就能知道后面的语句在条件成立 : 的时候不会被执行,看代码的时候可以省个半秒钟。不过同事习惯比自己习惯更重要, : 所以现在还是按第二种在写。
|
p*****2 发帖数: 21240 | 12
这个我当时就没看懂。说实话。
【在 L*****e 的大作中提到】 : 我也是用第二种。他的这个问题可以换一个角度考虑,是不是写了if就一定要写else? : 如果不是,答案就清楚了。。。
|
p*****2 发帖数: 21240 | 13
第二种的话,如果后面的else 语句很多的话就更清晰了。少一层嵌套。
【在 X****r 的大作中提到】 : 我个人倒是更喜欢第一种,因为不需要看到那个return就能知道后面的语句在条件成立 : 的时候不会被执行,看代码的时候可以省个半秒钟。不过同事习惯比自己习惯更重要, : 所以现在还是按第二种在写。
|
j*a 发帖数: 14423 | 14 我觉得二里面第一种写法好
你要么定个变量result,最后 return result;
要么if/else里面都return
不喜欢if/else里面一个return一个继续向下走
【在 L*****e 的大作中提到】 : 很早就想写这样一篇博文了,可是一直没来得及动笔。在学校的时候,时间似乎总是不 : 够用,因为一旦有点时间,你就想是不是该用来多看点论文。所以我很高兴,工作的生 : 活给了我真正自由的时间,让我可以多分享一些自己的经验。 : 我今天想开始写这系列文章的原因是,很多程序员的头脑中都有一些通过“非理性”方 : 式得到的错误观点。这些观点如此之深,以至于你没法跟他们讲清楚。即使讲清楚了, : 一般来说也很难改变他们的习惯。 : 程序员的世界,是一个“以傲服人”的世界,而不是一个理性的,“以德服人”的世界 : 。很多人喜欢在程序里耍一些“小聪明”,以显示自己的与众不同。由于这些人的名气 : 和威望,人们对这些小聪明往往不加思索的吸收,以至于不知不觉学会了很多表面上聪 : 明,其实导致不必要麻烦的思想,根深蒂固,难以去除。接着,他们又通过自己的“傲
|
d********g 发帖数: 10550 | 15 两个原因:
1. 更清晰(去掉else后在缩进上反而更显式地表示“else”这种情况)
2. 版本管理。比如要加一个判断条件,如果第一种写法,那么必须在else那一行加一
个if,或者改成switch,或者elif(取决于哪种语言)。当然也可以再写一个单独的if
但是比较行为艺术。用versioning的都知道,改一行代码的开销比单独删除或者添加都
要大,因为例如git是按照单行为一个单位,改了一行相当于删除一行再添加一行,这
样第二种写法添加更方便。当然不同语言对这个的影响也不一样
好,
【在 L*****e 的大作中提到】 : 好虫给讲讲他的思考题第二题? : 2. 当我第二次到 Google 实习的时候,发现我一年前给他们写的代码,很多被调整了 : 结构。几乎所有如下结构的代码: : if (condition) { : return x; : } else { : return y; : } : 都被人改成了: : if (condition) {
|
d**********x 发帖数: 4083 | 16 我觉得没啥意义
是++i还是i++,是if {return} return还是if {return}else{return} 在大多数情况下
既不影响效率,也不影响可读性,王x就喜欢鼓捣这些莫名其妙的东西引起争议,还显
得自己高深无比
if
【在 d********g 的大作中提到】 : 两个原因: : 1. 更清晰(去掉else后在缩进上反而更显式地表示“else”这种情况) : 2. 版本管理。比如要加一个判断条件,如果第一种写法,那么必须在else那一行加一 : 个if,或者改成switch,或者elif(取决于哪种语言)。当然也可以再写一个单独的if : 但是比较行为艺术。用versioning的都知道,改一行代码的开销比单独删除或者添加都 : 要大,因为例如git是按照单行为一个单位,改了一行相当于删除一行再添加一行,这 : 样第二种写法添加更方便。当然不同语言对这个的影响也不一样 : : 好,
|
r*g 发帖数: 3159 | 17 一边鄙视别人讨论++i/i++,一边纠结于if/else还是if。太搞笑了。
【在 L*****e 的大作中提到】 : 很早就想写这样一篇博文了,可是一直没来得及动笔。在学校的时候,时间似乎总是不 : 够用,因为一旦有点时间,你就想是不是该用来多看点论文。所以我很高兴,工作的生 : 活给了我真正自由的时间,让我可以多分享一些自己的经验。 : 我今天想开始写这系列文章的原因是,很多程序员的头脑中都有一些通过“非理性”方 : 式得到的错误观点。这些观点如此之深,以至于你没法跟他们讲清楚。即使讲清楚了, : 一般来说也很难改变他们的习惯。 : 程序员的世界,是一个“以傲服人”的世界,而不是一个理性的,“以德服人”的世界 : 。很多人喜欢在程序里耍一些“小聪明”,以显示自己的与众不同。由于这些人的名气 : 和威望,人们对这些小聪明往往不加思索的吸收,以至于不知不觉学会了很多表面上聪 : 明,其实导致不必要麻烦的思想,根深蒂固,难以去除。接着,他们又通过自己的“傲
|
L*****e 发帖数: 8347 | 18 我来具体说一下为什么我倾向于第二种。。。
1. 很多情况下你开始写条件语句时,你并不知道你在if条件下要return,所以if{}以
内的部分和以外的部分不是if和else的关系。因为加上了return语句后,这两部分才转
换为if和else的关系。如果按第一种写法,将来需要refactoring,不在if的条件下
return,你需要重新判断else里的部分应该在else里还是不应该在else里。
2. 从TDD的角度出发,有了function interface,就可以写unit test。这个时候
function内的逻辑都还没有,只需要一个default的return语句。
3. 王垠给出的例子很简单,但实际应用中的条件语句可能极其复杂,所以一般情况下
,我都会保证在条件语句外有return语句,这也给将来refactoring带来方便。。。
if
【在 d********g 的大作中提到】 : 两个原因: : 1. 更清晰(去掉else后在缩进上反而更显式地表示“else”这种情况) : 2. 版本管理。比如要加一个判断条件,如果第一种写法,那么必须在else那一行加一 : 个if,或者改成switch,或者elif(取决于哪种语言)。当然也可以再写一个单独的if : 但是比较行为艺术。用versioning的都知道,改一行代码的开销比单独删除或者添加都 : 要大,因为例如git是按照单行为一个单位,改了一行相当于删除一行再添加一行,这 : 样第二种写法添加更方便。当然不同语言对这个的影响也不一样 : : 好,
|
N******K 发帖数: 10202 | 19 以前学校老师教的时候 说要第一种
后来发现 第一种不是人读的代码
如果 else 跟着/嵌套 else 10个之后 你会晕倒的
还不如
if condition A do something and return
if condition B do something and return
......
if condition Z do something and return
(if none of the above)
do some thing and return
这些条件完全测试的不同的方面
这在算法预处理简单情况时 非常有效
【在 L*****e 的大作中提到】 : 好虫给讲讲他的思考题第二题? : 2. 当我第二次到 Google 实习的时候,发现我一年前给他们写的代码,很多被调整了 : 结构。几乎所有如下结构的代码: : if (condition) { : return x; : } else { : return y; : } : 都被人改成了: : if (condition) {
|
L*****e 发帖数: 8347 | 20 觉得你没有看清楚他说的是什么问题。。。
【在 r*g 的大作中提到】 : 一边鄙视别人讨论++i/i++,一边纠结于if/else还是if。太搞笑了。
|
|
|
N******K 发帖数: 10202 | 21 垃圾 他当个宝捡起来耍
【在 d**********x 的大作中提到】 : 我觉得没啥意义 : 是++i还是i++,是if {return} return还是if {return}else{return} 在大多数情况下 : 既不影响效率,也不影响可读性,王x就喜欢鼓捣这些莫名其妙的东西引起争议,还显 : 得自己高深无比 : : if
|
L*****e 发帖数: 8347 | 22 他举的例子合不合适另论,但他在这篇里谈的程序不应该片面追求短小,而应该语义清
晰明确的主张我以为是正确的。
程序就应该像自然语言一样浅显明了,知道基本的语法,文科生也应该像读文章一样能
读懂程序。
【在 d**********x 的大作中提到】 : 我觉得没啥意义 : 是++i还是i++,是if {return} return还是if {return}else{return} 在大多数情况下 : 既不影响效率,也不影响可读性,王x就喜欢鼓捣这些莫名其妙的东西引起争议,还显 : 得自己高深无比 : : if
|
p*****2 发帖数: 21240 | 23
有道理。其实这片文章我早看过。不过没什么好感觉。
【在 d**********x 的大作中提到】 : 我觉得没啥意义 : 是++i还是i++,是if {return} return还是if {return}else{return} 在大多数情况下 : 既不影响效率,也不影响可读性,王x就喜欢鼓捣这些莫名其妙的东西引起争议,还显 : 得自己高深无比 : : if
|
p*****2 发帖数: 21240 | 24
看来左眼也是个研究语言的大牛呀。
【在 L*****e 的大作中提到】 : 他举的例子合不合适另论,但他在这篇里谈的程序不应该片面追求短小,而应该语义清 : 晰明确的主张我以为是正确的。 : 程序就应该像自然语言一样浅显明了,知道基本的语法,文科生也应该像读文章一样能 : 读懂程序。
|
L*****e 发帖数: 8347 | 25 没有没有,我就一文科生,遇到我读不懂的程序,我就觉得写得有问题。。。
不过老高主张的literate programming也大概是这个意思,老高的文章就写得很好,很
多编程牛人的文章都写得很好。。。
【在 p*****2 的大作中提到】 : : 看来左眼也是个研究语言的大牛呀。
|
N******K 发帖数: 10202 | 26 程序可读性 比什么茴香豆写法 重要多了
【在 L*****e 的大作中提到】 : 他举的例子合不合适另论,但他在这篇里谈的程序不应该片面追求短小,而应该语义清 : 晰明确的主张我以为是正确的。 : 程序就应该像自然语言一样浅显明了,知道基本的语法,文科生也应该像读文章一样能 : 读懂程序。
|
L*****e 发帖数: 8347 | 27 小王同学的这篇博文没说啥茴香豆写法吧?不就是在谈程序可读性吗?
【在 N******K 的大作中提到】 : 程序可读性 比什么茴香豆写法 重要多了
|
d**********x 发帖数: 4083 | 28 有的东西只是他自以为的语义清晰明确
人与人的认知是不同的,王x往好了说,一直个长不大的孩子,活在自己的世界里
往差了说,就是情商堪比三岁小儿
况下
还显
【在 L*****e 的大作中提到】 : 他举的例子合不合适另论,但他在这篇里谈的程序不应该片面追求短小,而应该语义清 : 晰明确的主张我以为是正确的。 : 程序就应该像自然语言一样浅显明了,知道基本的语法,文科生也应该像读文章一样能 : 读懂程序。
|
t****a 发帖数: 1212 | 29 王银的观点乍看,貌似有道理,可仔细一想,却不容易实施。如何算语义清晰明确呢?
对C++程序员清晰明确的东西,对其他语言程序员比如haskell/lisp之类的,是否就算
清晰明确了呢?30年前清晰明确的标准,是否合适今天呢?这有放之四海皆准的真理在
这里吗?
怎样的标准才是好的?Google coding style的标准就是正确答案吗?
说真的,看完这个帖子我越来越糊涂了。
为什么,不同的风格总要评个高下呢。可不可以存在一个模糊的区间,比不了,不可比。
【在 L*****e 的大作中提到】 : 他举的例子合不合适另论,但他在这篇里谈的程序不应该片面追求短小,而应该语义清 : 晰明确的主张我以为是正确的。 : 程序就应该像自然语言一样浅显明了,知道基本的语法,文科生也应该像读文章一样能 : 读懂程序。
|
L*****e 发帖数: 8347 | 30 嗯,好像大多数人包括我都比较倾向第二题的第二种写法,不知道他认为第二种写法的
缺点在哪里,他也没有揭晓答案。。。
我觉得这孩子聪明还是蛮聪明的,但是接触的东西和经验都还有限,又经常爱做惊人之
语,所以他的成长的过程,就是一个不断自扇耳光的过程。。。
【在 d**********x 的大作中提到】 : 有的东西只是他自以为的语义清晰明确 : 人与人的认知是不同的,王x往好了说,一直个长不大的孩子,活在自己的世界里 : 往差了说,就是情商堪比三岁小儿 : : 况下 : 还显
|
|
|
a****i 发帖数: 1182 | 31 漂亮话谁都会说,问题就是他的例子恰当不恰当
恰当的例子可以叫effective xxx
不恰当的,只能叫自作聪明
if else的情况,经常会做null判断
if (string == null) {
return null;
}
这里是把其它部分用else包起来,还是不包,最后return?
另外,++i 和 i = i + 1; 是两个概念吧
听他那意思要把 ++ 都换成 i = i +1?
【在 L*****e 的大作中提到】 : 他举的例子合不合适另论,但他在这篇里谈的程序不应该片面追求短小,而应该语义清 : 晰明确的主张我以为是正确的。 : 程序就应该像自然语言一样浅显明了,知道基本的语法,文科生也应该像读文章一样能 : 读懂程序。
|
B***i 发帖数: 724 | 32 我觉得程序和自然语言一样, 都有个习惯问题。 自然语言有方言, 程序也有方言。
可读性是有环境的。 在一个公司里, 或者在一个部门里, 大家follow 相似的coding
convention, 这样大家的code 就容易读,程序的结构类似, design pattern 尽量
用大家都知道的。
每次换个公司, 读code都要一定时间来适应, 就是这个道理。
【在 t****a 的大作中提到】 : 王银的观点乍看,貌似有道理,可仔细一想,却不容易实施。如何算语义清晰明确呢? : 对C++程序员清晰明确的东西,对其他语言程序员比如haskell/lisp之类的,是否就算 : 清晰明确了呢?30年前清晰明确的标准,是否合适今天呢?这有放之四海皆准的真理在 : 这里吗? : 怎样的标准才是好的?Google coding style的标准就是正确答案吗? : 说真的,看完这个帖子我越来越糊涂了。 : 为什么,不同的风格总要评个高下呢。可不可以存在一个模糊的区间,比不了,不可比。
|
L*****e 发帖数: 8347 | 33 我是觉得他文中的主张正确,但是例子举得不好。不同语言有不同的语法syntax,就像
中英法意日各国语言一样,语义清晰明确应该是指在各自的语法syntax基础上,把程序
逻辑清楚地像写essay一样叙说出来,不要用“技巧”玩言简意赅的把戏,把复杂的逻
辑用短小的程序实现大部分情况没有太大意义,甚至有害。。。
【在 t****a 的大作中提到】 : 王银的观点乍看,貌似有道理,可仔细一想,却不容易实施。如何算语义清晰明确呢? : 对C++程序员清晰明确的东西,对其他语言程序员比如haskell/lisp之类的,是否就算 : 清晰明确了呢?30年前清晰明确的标准,是否合适今天呢?这有放之四海皆准的真理在 : 这里吗? : 怎样的标准才是好的?Google coding style的标准就是正确答案吗? : 说真的,看完这个帖子我越来越糊涂了。 : 为什么,不同的风格总要评个高下呢。可不可以存在一个模糊的区间,比不了,不可比。
|
L*****e 发帖数: 8347 | 34 嗯,if else的那个确实举得不好,不过那个不是他文中的例子而是他的所谓思考题,
也不知道他的理由是什么,所以也是我把它拿出来请大家讨论的原因。我以为我遗漏了
什么明显的地方。
关于i++和++i的例子,还是算恰当的,这个syntax表达不自然。i++和++i是说在不同的
时候执行i = i + 1,他的意思是不如不知道++这种syntax,而在该做i = i + 1时执行
i = i + 1。。。
【在 a****i 的大作中提到】 : 漂亮话谁都会说,问题就是他的例子恰当不恰当 : 恰当的例子可以叫effective xxx : 不恰当的,只能叫自作聪明 : if else的情况,经常会做null判断 : if (string == null) { : return null; : } : 这里是把其它部分用else包起来,还是不包,最后return? : 另外,++i 和 i = i + 1; 是两个概念吧 : 听他那意思要把 ++ 都换成 i = i +1?
|
a****i 发帖数: 1182 | 35 ++i 理解起来很容易,没有比 i = i + 1; 理解起来更难
这个例子更烂,
++ i 类似于说 increase i,你总得让程序员有点自己的语言吧,说 ++的时候,
就是在说increase
i = i + 1; 包括一个计算,一个赋值,是在说:把i加1,然后把结果赋给i
if else的例子也没这么离谱
【在 L*****e 的大作中提到】 : 嗯,if else的那个确实举得不好,不过那个不是他文中的例子而是他的所谓思考题, : 也不知道他的理由是什么,所以也是我把它拿出来请大家讨论的原因。我以为我遗漏了 : 什么明显的地方。 : 关于i++和++i的例子,还是算恰当的,这个syntax表达不自然。i++和++i是说在不同的 : 时候执行i = i + 1,他的意思是不如不知道++这种syntax,而在该做i = i + 1时执行 : i = i + 1。。。
|
O*******d 发帖数: 20343 | 36 我原来在的一个大公司里,对于coding style,有严格规定。 并且要求每个人安装
AStyle来保证coding style。
例如
单行的code block,必须加大括号
if(true == condition)
{
doSomething;
}
else
{
doSomethingElse;
}
成对的大括号,必须上下对齐。 下边的这段code style被禁止。
if(true == condition) {
doSomething;
}
一个函数只能有一个return
禁止使用exception, 因为exception是变相的 long goto. 你甚至很难找到exception
到哪里去了。
所有的单参数的condition test,必须使用true, false,例如
if(true == condition)
而不是
if(condition)
在condition test中,如果有常数,常数必须放在==左边。
每一行只能有一个statement。
int a,b,c; 被禁止。
必须写成
int a;
int b;
int c;
tab必须变成空格。 |
L*****e 发帖数: 8347 | 37 能用通用的语言表达清楚的地方,非要用程序员自己的语言的理由是什么?而且,也不
是所有程序员都清楚i++和++i的区别。++i一样是有赋值发生的,否则i的变量增值怎么
发生的?
i = 1;
j = i++;
VS
i = 1;
j = i;
i = i + 1; |
a****a 发帖数: 5763 | 38 你这水平,呵呵,呵呵,呵呵
【在 a****i 的大作中提到】 : ++i 理解起来很容易,没有比 i = i + 1; 理解起来更难 : 这个例子更烂, : ++ i 类似于说 increase i,你总得让程序员有点自己的语言吧,说 ++的时候, : 就是在说increase : i = i + 1; 包括一个计算,一个赋值,是在说:把i加1,然后把结果赋给i : if else的例子也没这么离谱
|
A*******t 发帖数: 443 | 39 single static assignment 作为一种构建Intermediate Language的方法早在龙书里面
就有了吧。。。
【在 L*****e 的大作中提到】 : 很早就想写这样一篇博文了,可是一直没来得及动笔。在学校的时候,时间似乎总是不 : 够用,因为一旦有点时间,你就想是不是该用来多看点论文。所以我很高兴,工作的生 : 活给了我真正自由的时间,让我可以多分享一些自己的经验。 : 我今天想开始写这系列文章的原因是,很多程序员的头脑中都有一些通过“非理性”方 : 式得到的错误观点。这些观点如此之深,以至于你没法跟他们讲清楚。即使讲清楚了, : 一般来说也很难改变他们的习惯。 : 程序员的世界,是一个“以傲服人”的世界,而不是一个理性的,“以德服人”的世界 : 。很多人喜欢在程序里耍一些“小聪明”,以显示自己的与众不同。由于这些人的名气 : 和威望,人们对这些小聪明往往不加思索的吸收,以至于不知不觉学会了很多表面上聪 : 明,其实导致不必要麻烦的思想,根深蒂固,难以去除。接着,他们又通过自己的“傲
|
L*****e 发帖数: 8347 | 40 “在condition test中,如果有常数,常数必须放在==左边”
这个不只是个style问题,而是有其实际意义的,因为很多时候都会不小心把“==”写
成“=”,把常数写在左边就杜绝了这种bug的发生。。。
【在 O*******d 的大作中提到】 : 我原来在的一个大公司里,对于coding style,有严格规定。 并且要求每个人安装 : AStyle来保证coding style。 : 例如 : 单行的code block,必须加大括号 : if(true == condition) : { : doSomething; : } : else : {
|
|
|
a****a 发帖数: 5763 | 41 C++里最丑的一部分就是c语言里留下的这些所谓的convention
除了添乱和少打两个字符没别的用
这就是为什么pascak远比c语言适合教学的原因
pascal很少有这种扯淡的惯例
【在 L*****e 的大作中提到】 : 能用通用的语言表达清楚的地方,非要用程序员自己的语言的理由是什么?而且,也不 : 是所有程序员都清楚i++和++i的区别。++i一样是有赋值发生的,否则i的变量增值怎么 : 发生的? : i = 1; : j = i++; : VS : i = 1; : j = i; : i = i + 1;
|
c****p 发帖数: 6474 | 42 ++i和i++有副作用,
尤其是多个++i/i++出现在同一个语句中的时候,
标准中没有规定,实际运行结果往往取决于编译器实现。
举个例子,,
int i = 5;
printf("%d %d %d", i++, i++, i++); // UB
【在 a****i 的大作中提到】 : ++i 理解起来很容易,没有比 i = i + 1; 理解起来更难 : 这个例子更烂, : ++ i 类似于说 increase i,你总得让程序员有点自己的语言吧,说 ++的时候, : 就是在说increase : i = i + 1; 包括一个计算,一个赋值,是在说:把i加1,然后把结果赋给i : if else的例子也没这么离谱
|
a****a 发帖数: 5763 | 43 恩
这些在c标准里都是未定义行为
【在 c****p 的大作中提到】 : ++i和i++有副作用, : 尤其是多个++i/i++出现在同一个语句中的时候, : 标准中没有规定,实际运行结果往往取决于编译器实现。 : 举个例子,, : int i = 5; : printf("%d %d %d", i++, i++, i++); // UB
|
c****p 发帖数: 6474 | 44 我觉得这个取决于实际的应用场合,在极端追求性能的地方,可以用短小性能好但是非
常不易懂的语句。
语义不够清晰的问题可以通过注释解决。
当然在绝大多数场合,在短小和语义清楚没有太大矛盾的时候,可以用语义清楚的表达
。。
【在 L*****e 的大作中提到】 : 他举的例子合不合适另论,但他在这篇里谈的程序不应该片面追求短小,而应该语义清 : 晰明确的主张我以为是正确的。 : 程序就应该像自然语言一样浅显明了,知道基本的语法,文科生也应该像读文章一样能 : 读懂程序。
|
a****a 发帖数: 5763 | 45 问题是现在编译器技术决定了i++这种玩意除了添乱没有任何意义
【在 c****p 的大作中提到】 : 我觉得这个取决于实际的应用场合,在极端追求性能的地方,可以用短小性能好但是非 : 常不易懂的语句。 : 语义不够清晰的问题可以通过注释解决。 : 当然在绝大多数场合,在短小和语义清楚没有太大矛盾的时候,可以用语义清楚的表达 : 。。
|
O*******d 发帖数: 20343 | 46 现在的编译器做优化,比人工做的好。 写码,易读性很重要。只要不是太出格就可以
了。 把优化交给编译器去做。
【在 c****p 的大作中提到】 : 我觉得这个取决于实际的应用场合,在极端追求性能的地方,可以用短小性能好但是非 : 常不易懂的语句。 : 语义不够清晰的问题可以通过注释解决。 : 当然在绝大多数场合,在短小和语义清楚没有太大矛盾的时候,可以用语义清楚的表达 : 。。
|
c****p 发帖数: 6474 | 47 我上帖说的不是指i++。
不过单独的i=i+1这种我还是喜欢用i++。
更容易出问题的还有这种吧:
a = a - b - c; // 很容易写成 a -= b - c;
【在 a****a 的大作中提到】 : 问题是现在编译器技术决定了i++这种玩意除了添乱没有任何意义
|
n******t 发帖数: 4406 | 48 别扯了。。
说道添乱的事情C++可牛B太多了。
什么function overloading, operator overloading,
还有reference,哪个不是添乱的?
【在 a****a 的大作中提到】 : C++里最丑的一部分就是c语言里留下的这些所谓的convention : 除了添乱和少打两个字符没别的用 : 这就是为什么pascak远比c语言适合教学的原因 : pascal很少有这种扯淡的惯例
|
c****p 发帖数: 6474 | 49 怎么发到邮箱里去了。。
有些优化是算法级的,编译器搞不来的。。。
比如卡马克出名的那句?比如判定是不是2的幂的(这个可能已经有指令集支持了?)?
【在 O*******d 的大作中提到】 : 现在的编译器做优化,比人工做的好。 写码,易读性很重要。只要不是太出格就可以 : 了。 把优化交给编译器去做。
|
a****a 发帖数: 5763 | 50
我又没说c++其他部分不丑
在我看来。最好是pascal的语法和 c的 style
【在 n******t 的大作中提到】 : 别扯了。。 : 说道添乱的事情C++可牛B太多了。 : 什么function overloading, operator overloading, : 还有reference,哪个不是添乱的?
|
|
|
e*******e 发帖数: 1144 | 51 "程序过分追求短小不好"这个谁都同意
但感觉实在没必要这么长篇大论的
随便给一个短小但可读性很差的句子作为例子就ok了
【在 L*****e 的大作中提到】 : 我是觉得他文中的主张正确,但是例子举得不好。不同语言有不同的语法syntax,就像 : 中英法意日各国语言一样,语义清晰明确应该是指在各自的语法syntax基础上,把程序 : 逻辑清楚地像写essay一样叙说出来,不要用“技巧”玩言简意赅的把戏,把复杂的逻 : 辑用短小的程序实现大部分情况没有太大意义,甚至有害。。。
|
N******K 发帖数: 10202 | 52 operator overloading很好啊 矩阵乘法这种东西
【在 n******t 的大作中提到】 : 别扯了。。 : 说道添乱的事情C++可牛B太多了。 : 什么function overloading, operator overloading, : 还有reference,哪个不是添乱的?
|
m********5 发帖数: 17667 | 53 这篇它说得没问题, 类似大陆计算机考试那种奇技淫巧是要不得的
不过这个应该是一个普遍的共识, 王写出来好像是他第一个提出来的一样...
【在 L*****e 的大作中提到】 : 很早就想写这样一篇博文了,可是一直没来得及动笔。在学校的时候,时间似乎总是不 : 够用,因为一旦有点时间,你就想是不是该用来多看点论文。所以我很高兴,工作的生 : 活给了我真正自由的时间,让我可以多分享一些自己的经验。 : 我今天想开始写这系列文章的原因是,很多程序员的头脑中都有一些通过“非理性”方 : 式得到的错误观点。这些观点如此之深,以至于你没法跟他们讲清楚。即使讲清楚了, : 一般来说也很难改变他们的习惯。 : 程序员的世界,是一个“以傲服人”的世界,而不是一个理性的,“以德服人”的世界 : 。很多人喜欢在程序里耍一些“小聪明”,以显示自己的与众不同。由于这些人的名气 : 和威望,人们对这些小聪明往往不加思索的吸收,以至于不知不觉学会了很多表面上聪 : 明,其实导致不必要麻烦的思想,根深蒂固,难以去除。接着,他们又通过自己的“傲
|
m********5 发帖数: 17667 | 54 ++这种不易读的东西还能提高效率?!
您是不是以为编译器还是20-30年前的老货?
少写两行代码和性能屁关系没有...
【在 c****p 的大作中提到】 : 我觉得这个取决于实际的应用场合,在极端追求性能的地方,可以用短小性能好但是非 : 常不易懂的语句。 : 语义不够清晰的问题可以通过注释解决。 : 当然在绝大多数场合,在短小和语义清楚没有太大矛盾的时候,可以用语义清楚的表达 : 。。
|
a****a 发帖数: 5763 | 55
这玩意造成的麻烦远比好处多
【在 N******K 的大作中提到】 : operator overloading很好啊 矩阵乘法这种东西
|
g***9 发帖数: 15 | |
g****y 发帖数: 2810 | 57 谷歌的if else还是有道理的。如果调试过程中,condition这个语句出错,但是程序继
续执行,if和else的内部都不会进入。这样函数就没有return了。 |
t**********0 发帖数: 1700 | 58 蛋疼
【在 L*****e 的大作中提到】 : 很早就想写这样一篇博文了,可是一直没来得及动笔。在学校的时候,时间似乎总是不 : 够用,因为一旦有点时间,你就想是不是该用来多看点论文。所以我很高兴,工作的生 : 活给了我真正自由的时间,让我可以多分享一些自己的经验。 : 我今天想开始写这系列文章的原因是,很多程序员的头脑中都有一些通过“非理性”方 : 式得到的错误观点。这些观点如此之深,以至于你没法跟他们讲清楚。即使讲清楚了, : 一般来说也很难改变他们的习惯。 : 程序员的世界,是一个“以傲服人”的世界,而不是一个理性的,“以德服人”的世界 : 。很多人喜欢在程序里耍一些“小聪明”,以显示自己的与众不同。由于这些人的名气 : 和威望,人们对这些小聪明往往不加思索的吸收,以至于不知不觉学会了很多表面上聪 : 明,其实导致不必要麻烦的思想,根深蒂固,难以去除。接着,他们又通过自己的“傲
|
d***a 发帖数: 13752 | |
s****y 发帖数: 38 | 60 大多数有经验的C程序员一般都会采纳下面的句式:
if(condition)
return x;
return y;
其主要原因是转换成机器指令后会减少一条跳转指令,而跳转指令一般会影响到指令流
水线的效率,实际损失好几个时钟周期。现在的CPU流水线比较深(当然没当初的奔4深)
, 从读指令到指令解码的流水线也较长,跳转指令的影响因此也不可忽视。
另,目前的编译器并不作此类优化。(两年前试的,相信现在应该没变化吧) |
|
|
c**y 发帖数: 2282 | 61 有道理!
【在 s****y 的大作中提到】 : 大多数有经验的C程序员一般都会采纳下面的句式: : if(condition) : return x; : return y; : 其主要原因是转换成机器指令后会减少一条跳转指令,而跳转指令一般会影响到指令流 : 水线的效率,实际损失好几个时钟周期。现在的CPU流水线比较深(当然没当初的奔4深) : , 从读指令到指令解码的流水线也较长,跳转指令的影响因此也不可忽视。 : 另,目前的编译器并不作此类优化。(两年前试的,相信现在应该没变化吧)
|
x****d 发帖数: 1766 | 62
Really? I don't remember what reason Martin Fowler says about this, but he
does say "Replace Nested Conditional with Guard Clauses". Many don't really
like it, I guess WangYin is one of them.
【在 s****y 的大作中提到】 : 大多数有经验的C程序员一般都会采纳下面的句式: : if(condition) : return x; : return y; : 其主要原因是转换成机器指令后会减少一条跳转指令,而跳转指令一般会影响到指令流 : 水线的效率,实际损失好几个时钟周期。现在的CPU流水线比较深(当然没当初的奔4深) : , 从读指令到指令解码的流水线也较长,跳转指令的影响因此也不可忽视。 : 另,目前的编译器并不作此类优化。(两年前试的,相信现在应该没变化吧)
|
b*****e 发帖数: 474 | 63 I remember that some old compilers (Sun Solaris??? can't remember exactly)
have crappy flow analysis and would generate a compiler warning says that
function does not always end with a return if your code looks like this:
So, moving the else part out actually would suppress the warning.
I've also seen some coding standards that require all functions with a
return value to end with a return statement. |
d***a 发帖数: 13752 | 64 不是这个原因。第一,return语句会被编译成多条机器指令,如果编译器不优化,“真
实”地多产生一个return,代价不小。第二,有branch prediction的时候,else部分
多出来的那一条跳转指令对性能影响一般不大,因为那一条跳转指令是无条件跳转,
prediction的准确度几乎能做到100%。
再说,现在的编译优化会用conditional move把这个if语句去掉。假设用MIPS,
condition是x < y, x和y是整数:
slt $t0, $s0, $s1 # Set-less-then, assume x is $0 and y is $1
movn $v0, $s0, $t0 # Return value is x if the condition is true
movz $v0, $s1, $t0 # Return value is y if the condition is false
... # Restore register values
addi $sp, $sp, N # Restore stack top
jr $ra # Return
深)
【在 s****y 的大作中提到】 : 大多数有经验的C程序员一般都会采纳下面的句式: : if(condition) : return x; : return y; : 其主要原因是转换成机器指令后会减少一条跳转指令,而跳转指令一般会影响到指令流 : 水线的效率,实际损失好几个时钟周期。现在的CPU流水线比较深(当然没当初的奔4深) : , 从读指令到指令解码的流水线也较长,跳转指令的影响因此也不可忽视。 : 另,目前的编译器并不作此类优化。(两年前试的,相信现在应该没变化吧)
|
y******o 发帖数: 921 | 65
...我经常只写一个=,以后也把常数写左边了...
【在 L*****e 的大作中提到】 : “在condition test中,如果有常数,常数必须放在==左边” : 这个不只是个style问题,而是有其实际意义的,因为很多时候都会不小心把“==”写 : 成“=”,把常数写在左边就杜绝了这种bug的发生。。。
|
m********5 发帖数: 17667 | 66 这个太old school了, 早就不是这样的了, 不止两年, 我记得老早就有优化
仍然这么写, 是避免condition有错后没有return
至少 gcc 4.x 都没这个问题了, 刚刚才全试了一遍, 编译结果没有任何不同
我自己以前遇到这个问题只有一些单片机的compiler
你能报一下你的compiler么? 我也去注意一下
深)
【在 s****y 的大作中提到】 : 大多数有经验的C程序员一般都会采纳下面的句式: : if(condition) : return x; : return y; : 其主要原因是转换成机器指令后会减少一条跳转指令,而跳转指令一般会影响到指令流 : 水线的效率,实际损失好几个时钟周期。现在的CPU流水线比较深(当然没当初的奔4深) : , 从读指令到指令解码的流水线也较长,跳转指令的影响因此也不可忽视。 : 另,目前的编译器并不作此类优化。(两年前试的,相信现在应该没变化吧)
|
m********5 发帖数: 17667 | 67 +1
另外前面有人也说得对, condition 如果有错, 会导致后面说没return
【在 b*****e 的大作中提到】 : I remember that some old compilers (Sun Solaris??? can't remember exactly) : have crappy flow analysis and would generate a compiler warning says that : function does not always end with a return if your code looks like this: : So, moving the else part out actually would suppress the warning. : I've also seen some coding standards that require all functions with a : return value to end with a return statement.
|
A*******t 发帖数: 443 | 68 刚才跑去试验了一下,clang生成的代码完全一样。
深)
【在 s****y 的大作中提到】 : 大多数有经验的C程序员一般都会采纳下面的句式: : if(condition) : return x; : return y; : 其主要原因是转换成机器指令后会减少一条跳转指令,而跳转指令一般会影响到指令流 : 水线的效率,实际损失好几个时钟周期。现在的CPU流水线比较深(当然没当初的奔4深) : , 从读指令到指令解码的流水线也较长,跳转指令的影响因此也不可忽视。 : 另,目前的编译器并不作此类优化。(两年前试的,相信现在应该没变化吧)
|
S***k 发帖数: 370 | 69 第2个问题,我两个都用。
如果是我自己code内部调用的函数,用if/else。
如果有别的地方(特别是其他人的code)需要在下游调用这个函数,用if。 |
m********5 发帖数: 17667 | 70 hehe 主要很多人的知识已经 outdated; 比如我还看到有人一个劲死塞inline
其实现在的 compiler 完全 ignore 这个 keyword...
【在 A*******t 的大作中提到】 : 刚才跑去试验了一下,clang生成的代码完全一样。 : : 深)
|
|
|
a****a 发帖数: 5763 | 71 nod
相当搞笑
相对于现代的编译器,很多所谓的优化就是在乎扯淡
【在 m********5 的大作中提到】 : hehe 主要很多人的知识已经 outdated; 比如我还看到有人一个劲死塞inline : 其实现在的 compiler 完全 ignore 这个 keyword...
|
d**********x 发帖数: 4083 | 72 inline现在一般只是个提示
编译器会自己判断是否inline
但是在特定情况下,force inline是有用的。
【在 m********5 的大作中提到】 : hehe 主要很多人的知识已经 outdated; 比如我还看到有人一个劲死塞inline : 其实现在的 compiler 完全 ignore 这个 keyword...
|
b***i 发帖数: 3043 | 73 condition都错了,要retun做甚?
【在 m********5 的大作中提到】 : +1 : 另外前面有人也说得对, condition 如果有错, 会导致后面说没return
|
c*****m 发帖数: 1160 | 74 "code complete" covers all these.
A programmer who doesn't like "code complete" is not a good programmer. |
s*****n 发帖数: 5488 | 75 都是闲的蛋疼。优化的被优化,错误的会被警告。如果你有个路径没有返回,会被警告
的。
这个王垠一旦接了地气,水平就是刚毕业的大学生。
【在 a****a 的大作中提到】 : nod : 相当搞笑 : 相对于现代的编译器,很多所谓的优化就是在乎扯淡
|
m********5 发帖数: 17667 | 76 这种情况不多的, 编译器优化通常更正确, 我做过大量实验, 不过可能我优化水平有限.
但对于满code塞inline的家伙,他肯定不如编译器厉害
force inline多数造成问题
我觉得还不如直接玩编译器的参数, 比如-finline-limit等
【在 d**********x 的大作中提到】 : inline现在一般只是个提示 : 编译器会自己判断是否inline : 但是在特定情况下,force inline是有用的。
|
c**u 发帖数: 550 | 77 这个是为什么第二种不好?
【在 L*****e 的大作中提到】 : 好虫给讲讲他的思考题第二题? : 2. 当我第二次到 Google 实习的时候,发现我一年前给他们写的代码,很多被调整了 : 结构。几乎所有如下结构的代码: : if (condition) { : return x; : } else { : return y; : } : 都被人改成了: : if (condition) {
|
n*y 发帖数: 26 | 78 程序的可读性是第一位的,二十年前的软件工程就这么说了。
又不是什么新玩意。
第二个例子两种写法都能看得懂。可读性没区别,何必纠缠这个小问题。 |
m********5 发帖数: 17667 | 79 感觉他挺适合回去骗2B本科生当人生导师的, 不回去可惜了
【在 n*y 的大作中提到】 : 程序的可读性是第一位的,二十年前的软件工程就这么说了。 : 又不是什么新玩意。 : 第二个例子两种写法都能看得懂。可读性没区别,何必纠缠这个小问题。
|
P******k 发帖数: 154 | 80 你在骂李开复?
【在 m********5 的大作中提到】 : 感觉他挺适合回去骗2B本科生当人生导师的, 不回去可惜了
|
|
|
x**8 发帖数: 4844 | 81 C都没学通就在网上充大牛,无知装有知。知道除了赋值加1外,++i比i++快吗?不要跟
人说GCC会帮你优化一切。笑死。 |
x****o 发帖数: 21566 | 82 谦虚一点不会死的, 你还是好好补补这方面的知识吧
【在 m********5 的大作中提到】 : hehe 主要很多人的知识已经 outdated; 比如我还看到有人一个劲死塞inline : 其实现在的 compiler 完全 ignore 这个 keyword...
|
a****i 发帖数: 1182 | 83 你这个例子举的……
i = i + 1; 你知道换一行写
i ++你就非要写在同一行?
i = 1;
i ++;
j = i;
vs
i = 1;
i = i + 1;
j = i;
对理解有什么区别?
要写在同一行,j = i = i + 1; 也不是那么好看吧
然后说的就是 ++ --是 increment 和decrement,
和 i = i + 1, i = i - 1 概念上是有区别的
更不用说 i ++ 和 i2 = i1 + 1的区别了
【在 L*****e 的大作中提到】 : 能用通用的语言表达清楚的地方,非要用程序员自己的语言的理由是什么?而且,也不 : 是所有程序员都清楚i++和++i的区别。++i一样是有赋值发生的,否则i的变量增值怎么 : 发生的? : i = 1; : j = i++; : VS : i = 1; : j = i; : i = i + 1;
|
g*****s 发帖数: 1288 | 84 好像有些style扯蛋。
>禁止使用exception, 因为exception是变相的 long goto. 你甚至很难找到exception
到哪里去了
exception 在Java里无处不在。
>tab必须变成空格。
什么道理?来一个全局变量名替换,所有对齐作废?Python怎么办?
【在 O*******d 的大作中提到】 : 我原来在的一个大公司里,对于coding style,有严格规定。 并且要求每个人安装 : AStyle来保证coding style。 : 例如 : 单行的code block,必须加大括号 : if(true == condition) : { : doSomething; : } : else : {
|
x**8 发帖数: 4844 | 85 就说这个goto吧,公司很多假高手到处吹goto不能用,那是newbie的错误用法。看看
linux kernel的code, gcc的code里有多少goto, 大把大把地用。
还有就是这个pre-increment和post-increment, 在速度上是会有差别的,虽然现在gcc
优化很厉害,在加上各种语言里针对pre-increment的特殊优化,以及现代Desktop机的
巨大cache,有时pre-increment甚至会比post-increment更快。但是,C作为一种语言不
是只为某种architecture服务的,在不同情况下(尤其是嵌入系统中)区别很大的。
exception
【在 g*****s 的大作中提到】 : 好像有些style扯蛋。 : >禁止使用exception, 因为exception是变相的 long goto. 你甚至很难找到exception : 到哪里去了 : exception 在Java里无处不在。 : >tab必须变成空格。 : 什么道理?来一个全局变量名替换,所有对齐作废?Python怎么办?
|
g****t 发帖数: 31659 | 86 这个非常好.
我原来在的一个大公司里,对于coding style,有严格规定。 并且要求每个人安装
AStyle来保证coding style。
例如
单行的code block,必须加大括号
if(true == condition)
{
doSomething;
}
else
{
doSomethingElse;
}
成对的大括号,必须上下对齐。 下边的这段code style被禁止。
if(true == condition) {
doSomething;
}
一个函数只能有一个return
禁止使用exception, 因为exception是变相的 long goto. 你甚至很难找到exception
到哪里去了。
所有的单参数的condition test,必须使用true, false,例如
if(true == condition)
而不是
if(condition)
在condition test中,如果有常数,常数必须放在==左边。
每一行只能有一个statement。
int a,b,c; 被禁止。
必须写成
int a;
int b;
int c;
tab必须变成空格。
【在 O*******d 的大作中提到】 : 我原来在的一个大公司里,对于coding style,有严格规定。 并且要求每个人安装 : AStyle来保证coding style。 : 例如 : 单行的code block,必须加大括号 : if(true == condition) : { : doSomething; : } : else : {
|
s******e 发帖数: 1751 | 87 at ibm os code base all c code forbids tab.
exception
【在 g*****s 的大作中提到】 : 好像有些style扯蛋。 : >禁止使用exception, 因为exception是变相的 long goto. 你甚至很难找到exception : 到哪里去了 : exception 在Java里无处不在。 : >tab必须变成空格。 : 什么道理?来一个全局变量名替换,所有对齐作废?Python怎么办?
|
s******e 发帖数: 1751 | 88 os/compiler code style requirements are different from other applications.
gcc
【在 x**8 的大作中提到】 : 就说这个goto吧,公司很多假高手到处吹goto不能用,那是newbie的错误用法。看看 : linux kernel的code, gcc的code里有多少goto, 大把大把地用。 : 还有就是这个pre-increment和post-increment, 在速度上是会有差别的,虽然现在gcc : 优化很厉害,在加上各种语言里针对pre-increment的特殊优化,以及现代Desktop机的 : 巨大cache,有时pre-increment甚至会比post-increment更快。但是,C作为一种语言不 : 是只为某种architecture服务的,在不同情况下(尤其是嵌入系统中)区别很大的。 : : exception
|
g****t 发帖数: 31659 | 89 风格这个东西应该是因应用环境而有区别的.
C code有很多是和关键性的硬件相关的,这种情况下,用冗余代码换取极端的robustness
,这个方向肯定是正确的.
tab这个我倒不懂为什么.是不是会让有些分析代码文本,算内存或者算堆栈的工具出错?
at ibm os code base all c code forbids tab.
exception
【在 s******e 的大作中提到】 : at ibm os code base all c code forbids tab. : : exception
|
O*******d 发帖数: 20343 | 90 exception产生很多问题。 一旦使用exception,你要假设每一个statement都会扔出来
exception。 如果不小心,你的code会有很多clean up code被跨过。 扔出exception
很爽,但是要完美地控制它的去向,需要很仔细的规划。所以我原来的公司里,直接在
configuration里把exception禁止了。 我们用C++。
tab的缺点是和空格没有任何视觉上的区别。 经常容易混用。 在不同的editor上,如
果tab宽度设定不一样,混合的tab和空格会看起来有很大不同。所以在editor的控制里
,直接把tab置换成空格。
exception
【在 g*****s 的大作中提到】 : 好像有些style扯蛋。 : >禁止使用exception, 因为exception是变相的 long goto. 你甚至很难找到exception : 到哪里去了 : exception 在Java里无处不在。 : >tab必须变成空格。 : 什么道理?来一个全局变量名替换,所有对齐作废?Python怎么办?
|
|
|
t*****n 发帖数: 4908 | 91 成对的大括号,必须上下对齐。 下边的这段code style被禁止。
if(true == condition) {
doSomething;
}
严重同意这个。省了这一行,读程序非常别扭。而且不止一次关于{}匹配被抓出bug。
不知道那个傻子搞出来这么愚蠢的东四。
【在 O*******d 的大作中提到】 : 我原来在的一个大公司里,对于coding style,有严格规定。 并且要求每个人安装 : AStyle来保证coding style。 : 例如 : 单行的code block,必须加大括号 : if(true == condition) : { : doSomething; : } : else : {
|
m*********t 发帖数: 527 | 92 我喜欢 early return, 读起来比 nested if else 要明了多了。。。。。
【在 g****t 的大作中提到】 : 这个非常好. : : 我原来在的一个大公司里,对于coding style,有严格规定。 并且要求每个人安装 : AStyle来保证coding style。 : 例如 : 单行的code block,必须加大括号 : if(true == condition) : { : doSomething; : }
|
d**********x 发帖数: 4083 | 93 我的装逼贴里面讨论过了吧
exception的abi问题更是要命
必须要在边界上catch住然后再用别的办法传出去
丑的一坨
exception
【在 O*******d 的大作中提到】 : exception产生很多问题。 一旦使用exception,你要假设每一个statement都会扔出来 : exception。 如果不小心,你的code会有很多clean up code被跨过。 扔出exception : 很爽,但是要完美地控制它的去向,需要很仔细的规划。所以我原来的公司里,直接在 : configuration里把exception禁止了。 我们用C++。 : tab的缺点是和空格没有任何视觉上的区别。 经常容易混用。 在不同的editor上,如 : 果tab宽度设定不一样,混合的tab和空格会看起来有很大不同。所以在editor的控制里 : ,直接把tab置换成空格。 : : exception
|
d***a 发帖数: 13752 | 94
那是K&R style,Kernighan and Ritchie那本经典C语言书里用的
Dennis Ritchie就是发明了C语言,并和Ken Thompson一起写了Unix的那位先驱
编程风格这东西属于软科学,是随时代变化的
编程有没有style,非常重要
不同style之间的具体差别,我觉得并不是太重要,不值得吵来吵去
去了哪家公司,就follow那家公司的风格
这是为什么我觉得,王垠这家伙纯属是无病呻吟...
【在 t*****n 的大作中提到】 : 成对的大括号,必须上下对齐。 下边的这段code style被禁止。 : if(true == condition) { : doSomething; : } : 严重同意这个。省了这一行,读程序非常别扭。而且不止一次关于{}匹配被抓出bug。 : 不知道那个傻子搞出来这么愚蠢的东四。
|
t****a 发帖数: 1212 | 95
---------------------------------------------
---------------------------------------------
Aglee!
【在 d***a 的大作中提到】 : : 那是K&R style,Kernighan and Ritchie那本经典C语言书里用的 : Dennis Ritchie就是发明了C语言,并和Ken Thompson一起写了Unix的那位先驱 : 编程风格这东西属于软科学,是随时代变化的 : 编程有没有style,非常重要 : 不同style之间的具体差别,我觉得并不是太重要,不值得吵来吵去 : 去了哪家公司,就follow那家公司的风格 : 这是为什么我觉得,王垠这家伙纯属是无病呻吟...
|
s*****n 发帖数: 5488 | 96 zheg这个用netbeans format 或者vs 美好一下。
然后看看提示好好了。
codes style 还有要程序员操心是上个世纪的事情了
【在 g****t 的大作中提到】 : 这个非常好. : : 我原来在的一个大公司里,对于coding style,有严格规定。 并且要求每个人安装 : AStyle来保证coding style。 : 例如 : 单行的code block,必须加大括号 : if(true == condition) : { : doSomething; : }
|
g*******t 发帖数: 7704 | 97 整天追求这些就完蛋了,
牛人都是在勤奋写开源代码, |
l*********s 发帖数: 5409 | 98 me too.
【在 m*********t 的大作中提到】 : 我喜欢 early return, 读起来比 nested if else 要明了多了。。。。。
|
s*****V 发帖数: 21731 | 99 PYTHON的TAB必须变成空格,否则语法检查都通不过。
别的语言可能也有同样问题,TAB在不同编辑器上看起来不一样。
robustness
错?
【在 g****t 的大作中提到】 : 风格这个东西应该是因应用环境而有区别的. : C code有很多是和关键性的硬件相关的,这种情况下,用冗余代码换取极端的robustness : ,这个方向肯定是正确的. : tab这个我倒不懂为什么.是不是会让有些分析代码文本,算内存或者算堆栈的工具出错? : : at ibm os code base all c code forbids tab. : exception
|
h*******g 发帖数: 508 | |
|
|
g*****g 发帖数: 34805 | 101 这是java的标准风格。只能说是个习惯问题。
【在 t*****n 的大作中提到】 : 成对的大括号,必须上下对齐。 下边的这段code style被禁止。 : if(true == condition) { : doSomething; : } : 严重同意这个。省了这一行,读程序非常别扭。而且不止一次关于{}匹配被抓出bug。 : 不知道那个傻子搞出来这么愚蠢的东四。
|
p**o 发帖数: 3409 | 102 http://www.python.org/dev/peps/pep-0008/#tabs-or-spaces
python缩进全用tab或全用空格都行,只是全空格更流行,新项目鼓励全用空格而已。
我身边就有几个写过十几万python代码的tab党。
其实混用也不是“通不过检查”,而是解释器有可能把tab解析成程序员意料之外的列
数,
有可能造成语法错误或语义错误。所以“不混用”在社区里成为“半强制”的共识——
只是共识,并没有在python语法规范里。
【在 s*****V 的大作中提到】 : PYTHON的TAB必须变成空格,否则语法检查都通不过。 : 别的语言可能也有同样问题,TAB在不同编辑器上看起来不一样。 : : robustness : 错?
|
d****i 发帖数: 4809 | 103 if (true) {
//...
}
这个好像叫K&R style的缩进格式,就是发明C语言的那两个人,可能来自于最早贝尔实
验室版本的Unix C code。那种上下对齐配对的缩进格式好像叫BSD style, 可能来自于
BSD Unix的源代码。其实用什么都可以,只要保持前后consistent就可以了。
【在 g*****g 的大作中提到】 : 这是java的标准风格。只能说是个习惯问题。
|
d****i 发帖数: 4809 | 104 tab这个东西,在某些UNIX的系统下定义和PC的Windows下的是不一样的,所以从UNIX下
面写好的code, 到了Windows下会出现对不齐的现象。以前我用过的Solaris和HP-UX都
有这种现象。
robustness
错?
【在 g****t 的大作中提到】 : 风格这个东西应该是因应用环境而有区别的. : C code有很多是和关键性的硬件相关的,这种情况下,用冗余代码换取极端的robustness : ,这个方向肯定是正确的. : tab这个我倒不懂为什么.是不是会让有些分析代码文本,算内存或者算堆栈的工具出错? : : at ibm os code base all c code forbids tab. : exception
|
d****i 发帖数: 4809 | 105 这个对的,C++的exception handling在嵌入式程序里面是不允许用的。
exception
【在 O*******d 的大作中提到】 : exception产生很多问题。 一旦使用exception,你要假设每一个statement都会扔出来 : exception。 如果不小心,你的code会有很多clean up code被跨过。 扔出exception : 很爽,但是要完美地控制它的去向,需要很仔细的规划。所以我原来的公司里,直接在 : configuration里把exception禁止了。 我们用C++。 : tab的缺点是和空格没有任何视觉上的区别。 经常容易混用。 在不同的editor上,如 : 果tab宽度设定不一样,混合的tab和空格会看起来有很大不同。所以在editor的控制里 : ,直接把tab置换成空格。 : : exception
|
p**v 发帖数: 853 | 106 试了试用sublime和emacs+python-mode,sublime用的是tab,emacs是空格,
虽然我对齐是敲的是tab。我想sublime应该可以定制tab键吧。
从通用的角度还是空格好吧,这个tab在不同系统上不一样的问题至少
影响到我看代码。perforce在linux下的tab default是8spaces,每次review
的时候都得手动改回4个。
【在 p**o 的大作中提到】 : http://www.python.org/dev/peps/pep-0008/#tabs-or-spaces : python缩进全用tab或全用空格都行,只是全空格更流行,新项目鼓励全用空格而已。 : 我身边就有几个写过十几万python代码的tab党。 : 其实混用也不是“通不过检查”,而是解释器有可能把tab解析成程序员意料之外的列 : 数, : 有可能造成语法错误或语义错误。所以“不混用”在社区里成为“半强制”的共识—— : 只是共识,并没有在python语法规范里。
|
p**v 发帖数: 853 | 107 虽然我不怎么写java,但也不喜欢下面的style。不过我们的code base
里面两种都有。下面的style一眼看去全是括号和换行,对我来说严重影响到可读性,
而且条件多了的话还得翻屏。
if ()
{
do this;
}
else
{
do that;
}
【在 g*****g 的大作中提到】 : 这是java的标准风格。只能说是个习惯问题。
|
W*******e 发帖数: 1268 | 108 如果是应用系统程序,第一种If比较好
如果需要性能比如iPad应用程序,用第二种有原因的 |
c********l 发帖数: 8138 | 109 对不齐只有两个原因
1,tab占多少位不统一,有的认为是4字符,有的认为是8字符
2,tab和空格混用
【在 d****i 的大作中提到】 : tab这个东西,在某些UNIX的系统下定义和PC的Windows下的是不一样的,所以从UNIX下 : 面写好的code, 到了Windows下会出现对不齐的现象。以前我用过的Solaris和HP-UX都 : 有这种现象。 : : robustness : 错?
|
c********l 发帖数: 8138 | 110 关于i++和++i,还有其它的那些c++的tricks & trivials
除了在面试中有可能被恶心的阿三面试官外,其它时候根本没有实际的用处
很多人鄙视孔乙己的“‘茴’字的4种写法”,却对i++,++i这些东西津津乐道 |
|
|
p**o 发帖数: 3409 | 111 没用过sublime不清楚;我买了wingide的license,他家的重构功能和debug probe太好
用了。sublime这么高级的编辑器应该可以定制tab吧,我印象中除了Windows notepad
之外的编辑器都可以。
python推荐空格缩进,是与79列宽的要求相一致的,tab可以显示成不同列宽,谈79列
就没意义了。我其实是希望python强制空格缩进的,可惜PEP8留了余地。
【在 p**v 的大作中提到】 : 试了试用sublime和emacs+python-mode,sublime用的是tab,emacs是空格, : 虽然我对齐是敲的是tab。我想sublime应该可以定制tab键吧。 : 从通用的角度还是空格好吧,这个tab在不同系统上不一样的问题至少 : 影响到我看代码。perforce在linux下的tab default是8spaces,每次review : 的时候都得手动改回4个。
|
W*******e 发帖数: 1268 | 112 python的强制缩进就像一个joke
【在 p**o 的大作中提到】 : 没用过sublime不清楚;我买了wingide的license,他家的重构功能和debug probe太好 : 用了。sublime这么高级的编辑器应该可以定制tab吧,我印象中除了Windows notepad : 之外的编辑器都可以。 : python推荐空格缩进,是与79列宽的要求相一致的,tab可以显示成不同列宽,谈79列 : 就没意义了。我其实是希望python强制空格缩进的,可惜PEP8留了余地。
|
a****a 发帖数: 5763 | 113 不是就像
python的强制缩进就是一个joke
搞python的人脑子进水了才会想出来这样的style
【在 W*******e 的大作中提到】 : python的强制缩进就像一个joke
|
d****i 发帖数: 4809 | 114 这个没啥吧,以前Fortran77也是这样的
【在 W*******e 的大作中提到】 : python的强制缩进就像一个joke
|
L***n 发帖数: 6727 | 115 ++i 包含了一点具体实现的信息,i=i+1更纯粹一点,不过我觉得无所谓,
编程是为了应用的。
【在 a****i 的大作中提到】 : ++i 理解起来很容易,没有比 i = i + 1; 理解起来更难 : 这个例子更烂, : ++ i 类似于说 increase i,你总得让程序员有点自己的语言吧,说 ++的时候, : 就是在说increase : i = i + 1; 包括一个计算,一个赋值,是在说:把i加1,然后把结果赋给i : if else的例子也没这么离谱
|
L***n 发帖数: 6727 | 116 赞
【在 O*******d 的大作中提到】 : 我原来在的一个大公司里,对于coding style,有严格规定。 并且要求每个人安装 : AStyle来保证coding style。 : 例如 : 单行的code block,必须加大括号 : if(true == condition) : { : doSomething; : } : else : {
|
L***n 发帖数: 6727 | 117 和性能无关,前面说的i++就是syntax sugar而已
【在 c****p 的大作中提到】 : 我觉得这个取决于实际的应用场合,在极端追求性能的地方,可以用短小性能好但是非 : 常不易懂的语句。 : 语义不够清晰的问题可以通过注释解决。 : 当然在绝大多数场合,在短小和语义清楚没有太大矛盾的时候,可以用语义清楚的表达 : 。。
|
W*******e 发帖数: 1268 | 118 Fortran77的block设计也是有问题
【在 d****i 的大作中提到】 : 这个没啥吧,以前Fortran77也是这样的
|
d**********x 发帖数: 4083 | 119 王x这种无理闹三分的诡辩。。。
每次都让人有一种很无力的感觉
比如说所谓的“小聪明”其实现实中也处处可见。为什么我们会说stores,不说places
where you can buy things...?后者语义多明确、多易懂。。
人脑的认知是有其规律的,短小未必就不易懂,门外汉和王x这种神经病看着不易懂的
未必就不易懂。
是非
表达
【在 L***n 的大作中提到】 : 和性能无关,前面说的i++就是syntax sugar而已
|
L***n 发帖数: 6727 | 120 王垠没挤进学术界的门,学术界的好东西就是优美的思想产品没学到,坏
东西就是装逼虚荣自大都学了个十足,,悲剧啊...其实他的小文章挺不错
的,就是把什么“愚蠢”之类的自以为是的点评去掉,就事论事就好了
places
【在 d**********x 的大作中提到】 : 王x这种无理闹三分的诡辩。。。 : 每次都让人有一种很无力的感觉 : 比如说所谓的“小聪明”其实现实中也处处可见。为什么我们会说stores,不说places : where you can buy things...?后者语义多明确、多易懂。。 : 人脑的认知是有其规律的,短小未必就不易懂,门外汉和王x这种神经病看着不易懂的 : 未必就不易懂。 : : 是非 : 表达
|
|
|
j********x 发帖数: 2330 | 121 王目前定位就是个低级李开复,就跟李开复为了名声 金钱不惜退掉自己学者的伪装一
样,王也不得不一次又一次的以露怯来拉近跟读者的距离
p np其其意义在于它是计算机科学到目前为止最有可能在基本理论上有所突破的问题。
说到底计算机科学还是太年轻,数学里面每个领域都有类似的基础问题,而计算机只有
一个。 |
j********x 发帖数: 2330 | 122 I = I + 1这种能理解,就已经颠覆了没学cs的小心肝儿了
纠结++i跟 i=i+1的还不如研究茴香豆呢。。。
【在 L*****e 的大作中提到】 : 能用通用的语言表达清楚的地方,非要用程序员自己的语言的理由是什么?而且,也不 : 是所有程序员都清楚i++和++i的区别。++i一样是有赋值发生的,否则i的变量增值怎么 : 发生的? : i = 1; : j = i++; : VS : i = 1; : j = i; : i = i + 1;
|
g****t 发帖数: 31659 | 123 李当年的phd论文说是某方向开山之作并不为过吧.
王好像10年都没拿到phd.
王现在就是民间科学家.李属于民间business major辅导员.
王目前定位就是个低级李开复,就跟李开复为了名声 金钱不惜退掉自己学者的伪装一
样,王也不得不一次又一次的以露怯来拉近跟读者的距离
p np其其意义在于它是计算机科学到目前为止最有可能在基本理论上有所突破的问题。
说到底计算机科学还是太年轻,数学里面每个领域都有类似的基础问题,而计算机只有
一个。
【在 j********x 的大作中提到】 : 王目前定位就是个低级李开复,就跟李开复为了名声 金钱不惜退掉自己学者的伪装一 : 样,王也不得不一次又一次的以露怯来拉近跟读者的距离 : p np其其意义在于它是计算机科学到目前为止最有可能在基本理论上有所突破的问题。 : 说到底计算机科学还是太年轻,数学里面每个领域都有类似的基础问题,而计算机只有 : 一个。
|
A******g 发帖数: 612 | 124 return在最后是为了减少没有return的bug
if {
...
return;
} else {
...
return;
}
用g++ -Wall会给没有return的warning |