C 语言的语法问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bwangel
V2EX    C

C 语言的语法问题

  •  
  •   bwangel 2015-05-27 20:52:10 +08:00 1692 次点击
    这是一个创建于 3865 天前的主题,其中的信息可能已经有所发展或是发生改变。
    #include <stdio.h> int main(int argc,char *argvspan class="p">[]) { int num; printf("%d %d\n",(num=100,1),num); return 0; } 

    上面是代码,谁能给我解释一下那个(num=100,1)的值为什么是1,这条语句是个啥意思啊?

    20 条回复    2015-08-17 10:34:56 +08:00
    bwangel
        1
    bwangel  
    OP
       2015-05-27 20:53:03 +08:00
    程序的运行结果是
    1 100
    bwangel
        2
    bwangel  
    OP
       2015-05-27 20:53:41 +08:00
    感觉这个语句好神奇啊,哪位大牛能给俺科普科普,不胜感激!
    moro
        3
    moro  
       2015-05-27 20:55:32 +08:00
    逗号表达式的返回值,应该是最后一个逗号的值。
    wy315700
        4
    wy315700  
       2015-05-27 20:55:51 +08:00
    @bwangel
    num=100,1
    这句话首先 是给num赋值100
    其次,这个是逗号分割的表达式, (a,b,c,d) 这个表达式的值 是d,
    所以 (num=100,1) = 1
    moro
        5
    moro  
       2015-05-27 20:55:54 +08:00
    其它语言也是一样的。
    rrfeng
        6
    rrfeng  
       2015-05-27 20:56:53 +08:00   1
    (num=100,1)

    逗号运算符的优先级最低,作为一个整体,逗号表达式的值为最后一个表达式的值。
    xdeng
        7
    xdeng  
       2015-05-27 20:57:10 +08:00
    3、4楼正解
    bwangel
        8
    bwangel  
    OP
       2015-05-27 21:06:06 +08:00
    可不可以这样想,逗号的功能就是分割语句,相当与将多个语句整合成一条。然后它的结合性是从左到右。比如这条语句:

    ```c
    num = 10, num = 20, num = 30
    ```

    先执行num = 30 ,再执行num=20,最后执行num = 10

    然后相当于变成了这个样子的代码(仅供参考,可能不是很严谨)
    ```c
    10,20,30
    ```

    然后再执行10,20,代码就变成了这个样子
    ```c
    20,30
    ```

    最后执行20,30这条语句,然后整个表达式的值就是30了?

    各位看官,我分析的对不?
    bwangel
        9
    bwangel  
    OP
       2015-05-27 21:06:36 +08:00
    额,为啥回复就不支持markdown。。。。。
    theFool
        10
    theFool  
       2015-05-27 21:22:14 +08:00
    @bwangel 不对。 num应该是==30. 照你的说法num==10了。
    msg7086
        11
    msg7086  
       2015-05-27 21:25:25 +08:00
    并非是分割语句,而是分割表达式。

    a = b 是赋值表达式
    a = b; 是赋值语句
    wy315700
        12
    wy315700  
       2015-05-27 21:27:39 +08:00
    @bwangel
    逗号表达式是C的一种表达式

    http://en.wikipedia.org/wiki/Comma_operator
    bwangel
        13
    bwangel  
    OP
       2015-05-27 21:37:01 +08:00
    @msg7086 ,恩,确实是,我的表达有误!
    bwangel
        14
    bwangel  
    OP
       2015-05-27 21:40:11 +08:00
    @theFool ,不是很理解你想说的意思,意思是我分析的那个num赋值顺序(30,20,10)不对,还是说我那个=不对,应该写成==
    theFool
        15
    theFool  
       2015-05-27 21:43:15 +08:00
    @bwangel 分析不对。照你的说法先执行num = 30 ,再执行num=20,最后执行num = 10 ,那num最后应该是等于10的。
    qiuyi116
        16
    qiuyi116  
       2015-05-27 22:49:29 +08:00
    (num=100, 1)整体是一个逗号表达式,它的值是最后一个逗号后的值,即1;而逗号表达式的前面一个表达式是个赋值表达式,使得num的值为100。所以输出的值为1,100.
    Maxi
        17
    Maxi  
       2015-05-30 21:54:58 +08:00
    优先级问题 ,逗号运算符级别最低 。所以先 100先给赋值用, 再计算逗号表达式的值. 如果num = (100, 1) 则是先计算逗号表达式的值。
    FrankHB
        18
    FrankHB  
       2015-06-06 14:35:52 +08:00
    @bwangel 逗号的功能不一定是“分隔语句”。
    首先你得了解,C的语法中逗号并不都是一回事。有些逗号只是标点而不是操作符,如函数调用的postfix-expreesion中的分隔参数的逗号;而逗号表达式里的逗号操作符是另一回事。
    最重要的影响语义的差异之一是,前者不限定求值顺序,而后者会插入一个sequence point。这里没有这个坑,但不知道迟早被坑。
    语句之间是有sequence point的。从这个意义上来看,逗号操作符可以认为是在“分隔语句”。虽然实际上更像是个应付语句可用性缺陷设计的workaround(嘛,while条件里塞不进语句咋办……用逗号擦屁股吧)。而其它逗号,就显然不是这个意思。
    printf("%d %d\n",(num=100,1),num);这坨里面,本来分号之前按postfix-expression来看,里面的逗号是argument-expression-list的组成部分用于分隔作为参数assignment-expression的硬编码的分隔符而不是逗号操作符,但这里硬加了个括号,而作为argument的assignment-expression当然没法包括没配对的括号,语法分析就只能把(num=100,1)当作整个assignment-expression,然后继续规约:conditional-expression→...→primary-expression→( expression )→expression , assignment-expression这里面的逗号就是逗号操作符了。
    这里的要点是语法规则决定了assignment-expression的逗号不会被作为操作符,而加上括号以后括号里面的东西可以不是assignment-expression而是允许包含逗号操作符的一般expression,因此加上括号以后含义就变了。
    wlee1991
        19
    wlee1991  
       2015-08-17 09:26:25 +08:00 via iPhone
    @FrankHB 有没有英文出处 可以贴出来吗
    wlee1991
        20
    wlee1991  
       2015-08-17 10:34:56 +08:00
    c 语言提供一种特殊的运算符,逗号运算符,优先级别最低,它将两式联接起来,如:( 3+5,6+8 )称为逗号表达式,其求解过程先表达式 1 ,后表达式 2 ,整个表达式值是表达式 2 的值。
    如:(3+5, 6+8 )的值是 14 ,(a=3*5, a*4 )的值是 60 ,原因在于赋值运算符优先级高于逗号运算符。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5411 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 01:48 PVG 09:48 LAX 17:48 JFK 20:48
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86