V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
darasion
V2EX  ›  程序员

王垠的几道思考题,你的回答是?

  •  
  •   darasion · 2013-03-15 23:25:55 +08:00 · 6803 次点击
    这是一个创建于 4052 天前的主题,其中的信息可能已经有所发展或是发生改变。
    http://blog.sina.com.cn/s/blog_5d90e82f0101j529.html

    先说我自己,
    两道思考题中提到的风格,是我比较喜欢的。

    第三道题,
    暂时不太懂,半路出家没学过理论。
    31 条回复    1970-01-01 08:00:00 +08:00
    tioover
        1
    tioover  
       2013-03-16 15:39:22 +08:00 via Android
    最后一题大概是:=
    Xrong
        2
    Xrong  
       2013-03-16 15:52:35 +08:00
    希望有人解释下第二题,语义上感觉一样啊
    Alex_L
        3
    Alex_L  
       2013-03-16 16:55:25 +08:00 via iPad
    @tioover := 有什么问题?
    volCANo
        4
    volCANo  
       2013-03-17 11:56:54 +08:00
    @Xrong 我觉得第二道题这么改的意义在于:
    不管这个方法的逻辑是怎样,是必须保证要有return的。
    所以在你程序逻辑之外(if else),你需要有return。
    y
        5
    y  
       2013-03-17 12:31:57 +08:00
    @tioover += 也是一个吧。
    alexrezit
        6
    alexrezit  
       2013-03-17 12:37:47 +08:00   ❤️ 1
    1. 加上花括号是个好习惯;

    2. 在某些编译器的默认设置里, 这样的结构是要给出一个 warning 的:
    myFreakyFunction {
    if (what) { return oo; }
    else { return xx; }
    }
    必须要写成这样来消除这个 warning:
    myFreakyFunction {
    if (what) { return oo; }
    else { return xx; }
    return xx;
    }
    例如旧版本 Xcode 默认的编译器, 但现在最新版本已经不会给出 warning 了, 貌似是从 Apple LLVM 4.x 开始.

    其实为了逻辑更清晰, 我自己现在已经尽量在每个 function / method 里只 return 一次了. 例如当 type 为 BOOL 时:
    BOOL myFreakyFunction {
    BOOL isXXX = NO;
    if (what) { isXXX = YES; }
    else { isXXX = NO; }
    return isXXX;
    }
    而不是:
    BOOL myFreakyFunction {
    if (what) { return NO; }
    else { return YES; }
    }
    或:
    BOOL myFreakyFunction {
    if (what) { return NO; }
    return YES;
    }
    cassyfar
        7
    cassyfar  
       2013-03-17 12:54:37 +08:00
    @alexrezit 什么version的编译器报warning啊?我用Gcc-redhat-4.1.2这种老编译器都没给出warning...
    我觉得改了之后至少逻辑不清晰了,不能一眼看去就知道是个if else逻辑,我不会写被改成的第二个,也不知道第一个有什么错...
    我赞成你的写法,保留一个return。

    @volCANo 为什么return不能放if语句里? 只要if语句执行了,肯定就会有一个return被执行。
    volCANo
        8
    volCANo  
       2013-03-17 13:57:00 +08:00
    @cassyfar 肯定有吗?又不是说if else 里面一定要有return,如果里面不写呢?
    代码逻辑是没什么问题的,只是编码规范。你想想,如果if else里面的东西非常多,你去读甚至都找不到return在哪儿,那么你会觉得这代码不爽吗?应该会的,甚至你会说,这个函数没有返回,是错的。
    所以在if else外面写return,别人读起来会容易些。这只是个编码规范问题。
    还有第一个if后面只有一句代码也要加大括号,我一直有这个习惯,我的理由是:虽然你现在是只要一行,但以后非常有可能要添加逻辑,就不只是一行了,到时候也要加括号;况且,都加括号不是更一致吗?而且,很多编译器都帮你加好了,你写个if 后面的大括号都自动给你不气了。
    for4
        9
    for4  
       2013-03-17 14:09:54 +08:00
    @Xrong
    @cassyfar

    赞同@volCANo 的说法

    if {
    return 1
    } else {
    return 2
    }
    这种在后面不再加个return x的话, golang就不会让编译通过
    laskuma
        10
    laskuma  
       2013-03-17 15:21:45 +08:00
    不觉得他说的有道理 这只是纯粹的taste上的问题 你偏好哪一种 风格不差 看着不乱 易于理解就好了 他对++的分析我倒是很赞成 这种带side effect太多的语句写多了连debug的时候都会造成困难 但是关于if(){return}else{return}却是我不能接受的 个人还是觉得if(){return}return;的写法没有什么难理解的 代码一行行看下来也都明白 多写一个return反而会让人摸不着头脑
    best1a
        11
    best1a  
       2013-03-17 15:33:22 +08:00
    第二种写法还有一些别的好处,比如有时可以减少一下if的嵌套
    qiukun
        12
    qiukun  
       2013-03-17 15:50:31 +08:00
    @for4 golang 毕竟是 google's lang
    cassyfar
        13
    cassyfar  
       2013-03-17 17:02:09 +08:00
    @volCANo 你理解错我最后一句了。

    @for4 你这...例子举得
    perrywky
        14
    perrywky  
       2013-03-18 13:57:11 +08:00
    其实他说的道理《代码大全》里都已经提到了,就是“代码是写给人看的”

    1. 加上花括弧,块的边界更清晰,别人读起来更轻松
    2. 去掉花括弧,语义发生了变化,第二个return从“其它情况”变成了“默认情况”,本来是很简单的互斥关系,现在第一个return成了特殊情况,读代码的人就会想,还有没有其他特殊情况呢?
    GTim
        15
    GTim  
       2013-03-18 17:40:58 +08:00
    1. 防止手贱在 if 后加了 分号(";");另外一个就是某些代码编辑器tab和space不分的情况下,某些人就会进入思维误区,为是并行还是串行想破脑袋;其它风格问题

    2.语义上来说是不一样的,同样可以防止某些人手贱 把 else 写成 else if

    3. 不要只研究i = i+1 和 i++两个表达式,而是要研究上下文!何况 i++ 与 ++i本身就是两种语境;举个例子:a = ++i; 和 a=i=i+1;哪种更好? a=i++;用一条语句怎么写加法的方式 ?

    这三个问题,一般都是语义上的问题,计算机是死的,人是活的,但更悲剧的是计算机遵守交通规则,但人却不一定遵守交通规则;计算机的智力几乎都是一样的,但人的呢?千奇百怪,很多人就是转不过那个弯弯
    GTim
        16
    GTim  
       2013-03-18 17:45:04 +08:00
    针对第三个问题,有很多牛角尖可以钻的,仔细研究下去,可能永远出不了那个坑
    guotie
        17
    guotie  
       2013-03-18 17:49:00 +08:00
    i++ ++i单独写没有任何问题;

    如果单独写i++ 也要改成i = i + 1就有点装逼了
    iEverX
        18
    iEverX  
       2013-03-18 23:47:21 +08:00
    @guotie
    同意

    @perrywky
    对于第二个,虽然是这样说,但是默认不就是意味着以上都不满足的情况吗?
    if (...) { return ... }
    return
    还是感觉这样比较清爽、舒服、习惯
    leafduo
        19
    leafduo  
       2013-03-19 01:04:15 +08:00
    第一个加括号是有必要的,改代码的时候不会忘记加,switch 里面的 break 语句同理。

    第二个更多是 personal taste 的问题吧,另外就是有的版本的编译器对第一种写法会给 warning,最新版本的 clang 已经能识别两种了。

    对于自增操作符这种,我都是觉得实践中哪个清楚、方便就用哪个,没歧义的时候就用自增,难理解了就拆开。
    skydark
        20
    skydark  
       2013-03-19 08:48:22 +08:00
    @tioover 同希望解释一下最后一题,thx~
    zhujinliang
        21
    zhujinliang  
       2013-03-19 09:00:12 +08:00
    @GTim C语言里一边移动指针一边取出数据或写入数据是多么的惬意。 while(count--) *pBuf++ = 0x00;
    fancl20
        22
    fancl20  
       2013-03-19 10:39:47 +08:00   ❤️ 1
    @cassyfar warn 报的是一个有返回值的函数可能不返回值。
    @skydark 估计是说 go 把定义变量和对变量赋值混淆了
    GTim
        23
    GTim  
       2013-03-19 17:57:38 +08:00
    @zhujinliang 我也是
    tioover
        24
    tioover  
       2013-03-20 08:14:17 +08:00 via Android   ❤️ 1
    @skydark
    @Alex_L
    大半…是猜的…惭愧
    作者给了入门连接,说明可能不是什么深的特性,比如gontinue ,而比较简单的特性,看起来又是:=最可疑。感觉上是省略了对类型的声明交给编译器,和++对赋值的省略很像。
    zztom
        25
    zztom  
       2013-03-20 08:24:19 +08:00
    花括号应该是个还习惯,不过我起初加他的理由竟然是为了好看
    skydark
        26
    skydark  
       2013-03-20 08:35:35 +08:00
    @fancl20 @tioover 个人倒是觉得这种编译器自己能推断的事情交给它们做很对啦……
    不过又仔细看了下,是因为`:=`允许 redeclaration 吗?不过它的 redeclaration 很受限一般倒是不会出什么问题,但的确会产生看起来是声明+初始化的地方进行了重新赋值的行为……
    http://golang.org/ref/spec#Short_variable_declarations
    palxex
        27
    palxex  
       2013-03-20 09:36:29 +08:00
    ++这几个例子,拿任意高级语言举例都不错。就放在C里不合适……因为它就是高级语法的汇编。强调的是语句可以几乎直接对应到不长的汇编段落。
    i++这种情况下,i强调的是一个内存地址,用图灵机的语言,就是一个具体可以打孔的位置。你对这一个位置强调i2=i1+1,i2跟i1是两个不同的变量……完全没有意义。
    在SSA的情况下强调其是两个变量,正是因为"变量"与"地址"的解耦,让更高级的优化成为可能。但这本来就不是C,甚至C++这类语言的设计目的。如果要批判这里,C的指针设计才是更应该批判的,但这就是它的设计——和精髓:可移植汇编语言。unix hater's handbook分析的不错,这个特性让unix和C得以病毒式传播,而且方兴未艾。
    关于王垠的第三题,如果要改造图灵机,维持相同的计算能力并规避地址的存在……我简单的大脑当机了若干次也没什么结果。莫非要改造成lambda演算?
    alexrezit
        28
    alexrezit  
       2013-03-20 09:46:34 +08:00
    @cassyfar
    以前用 Xcode 默认的 Apple LLVM 就会报 warning. 因为它需要返回值, 又没有给一个返回值. (其实是编译器没有对 if else 做静态分析以为它没有给一个返回值)

    @iEverX
    但如果后来又需要加一些其他的判断呢?
    iEverX
        29
    iEverX  
       2013-03-20 12:37:36 +08:00
    @alexrezit
    如果原来的写法,需要加一些判断你要怎么写,不也是加一个 else if 吗?有什么区别吗
    alexrezit
        30
    alexrezit  
       2013-03-20 12:49:45 +08:00
    @iEverX
    就是说值不能直接返回的情况, 而要二次判断后再返回. 如果按那种写法就需要三处以上的 return 了, 而且每处 return 所在的层级还不同.
    iEverX
        31
    iEverX  
       2013-03-21 21:34:50 +08:00
    @alexrezit
    不明白你的意思。我认为,这两种写法是完全等价的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2781 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 13:19 · PVG 21:19 · LAX 06:19 · JFK 09:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.