免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 4044 | 回复: 21
打印 上一主题 下一主题

[C] 关于C语言中的运算符++的问题,很烦躁。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-07-05 11:39 |只看该作者 |倒序浏览
这是我们论坛的一个网友帖出的问题,讨论了半天,却没有个正确答案。感兴趣的可以试试。

以下帖子转自:[C世界求索](http://cworld.xilubbs.com)。
帖子网址:http://bbs5.xilubbs.com/cgi-bin/ ... ld&message=1583
经典面视题目之一(国内篇)
#include <stdio.h>;
void main()
{
int i=1,j;
j=(i++)+(i++)+(i++);
i=1;
printf("%d,%d\n",j,(i++)+(i++)+(i++));
}

输出会一样吗?同时你知道为什么吗?[/url]

论坛徽章:
0
2 [报告]
发表于 2003-07-05 11:46 |只看该作者

关于C语言中的运算符++的问题,很烦躁。

++在后就是执行完这个表达式后变量值再++
就是说无沦有几个

当前表达式中使用的仍然是当前值
此变量值不会改变

论坛徽章:
0
3 [报告]
发表于 2003-07-05 11:50 |只看该作者

关于C语言中的运算符++的问题,很烦躁。

谢谢!
我的解释如下,你看对不对?

相信只要运行一下编译器编译运行一下就可以知道结果了,呵呵。

所以,在此我讲一下我的分析:
对于j = (i++) + (i++) + (i++);
j的值是三个(i++)表达式的值的和,因为i++的值是1,所以j等于3。而计算i的值的话,由于i++有三个,所以需要i(i初值为1)加上3个1,所以i等于4。
直接输出(i++) + (i++) + (i++)的值跟输出j的值一样,因为(i++) + (i++) + (i++)的值赋给j了。
欢迎指出不足。

论坛徽章:
0
4 [报告]
发表于 2003-07-05 11:59 |只看该作者

关于C语言中的运算符++的问题,很烦躁。

上面那个式子可以分成两部分
j = (i++) + (i++) + (i++);
====>;
j=i+i+i;
i++,i++,i++;

因为后++是在式子运算完后才执行 所以可以这么看

论坛徽章:
0
5 [报告]
发表于 2003-07-05 12:15 |只看该作者

关于C语言中的运算符++的问题,很烦躁。

为什么有人运行的结果如下:
#include
void main()
{
int i=1,j;
j=(++i)+(++i)+(++i);
i=1;
printf("%d,%d\n",j,(++i)+(++i)+(++i));
}
为何输出结果会为12与9?

而我的运行结果如下:
我是用的Visual C++ 6.0 + Windows 2000 Professional编译环境。
1、对于:
void main()
{
int i=1,j;
j=(++i)+(++i)+(++i);
i=1;
printf("%d,%d\n",j,(++i)+(++i)+(++i));
}

运行结果是:10,10

2、对于:
void main()
{
int i=1,j;
j=(i++)+(i++)+(i++);
i=1;
printf("%d,%d\n",j,(i++)+(i++)+(i++));
}

运行结果是:3,3

论坛徽章:
0
6 [报告]
发表于 2003-07-05 13:09 |只看该作者

关于C语言中的运算符++的问题,很烦躁。

++i这个会引起混淆

i++的话不会
我觉得++i没有必要使用在一个式子中多次调用情况
如这里的++i +(++i);有的编译器是先++再求和 有的是一边加一边求和
所以结果是会不一样的 写这样的代码也是危险的

但使用i++就没有这个问题 i++ +(i++)  结果在任何平台上都不变

论坛徽章:
0
7 [报告]
发表于 2003-07-05 13:35 |只看该作者

关于C语言中的运算符++的问题,很烦躁。

类似问题以前讨论过,在TCPL和TC++PL以及各种FAQ里都有说明。这样的表达式其结果为undefined,注意不是unspecified。因此,不能这样使用。

在C里只有 ||, && 运算、?:以及","运算符是有执行顺序规定的,其他的表达式其子表达式的运算顺序没有规定。所以你的问题的结论是未定义。不同的编译器可能给出不同的结果。

论坛徽章:
0
8 [报告]
发表于 2003-07-05 13:35 |只看该作者

关于C语言中的运算符++的问题,很烦躁。

另外与i++还是++i没有关系。

论坛徽章:
0
9 [报告]
发表于 2003-07-05 13:36 |只看该作者

关于C语言中的运算符++的问题,很烦躁。

如果是i++的话
我觉得结果会是统一的

但是如果是
(i++)+(++i)  
这种时间不推荐使用 结果会不统一

论坛徽章:
0
10 [报告]
发表于 2003-07-05 13:45 |只看该作者

关于C语言中的运算符++的问题,很烦躁。

干脆贴上自己看吧(C FAQ摘录)
Section 3. Expressions

3.1:        Why doesn't this code:

                a = i++;

        work?

A:        The subexpression i++ causes a side effect -- it modifies i's
        value -- which leads to undefined behavior since i is also
        referenced elsewhere in the same expression, and there's no way
        to determine whether the reference (in a on the left-hand
        side) should be to the old or the new value.  (Note that
        although the language in K&R suggests that the behavior of this
        expression is unspecified, the C Standard makes the stronger
        statement that it is undefined -- see question 11.33.)

        References: K&R1 Sec. 2.12; K&R2 Sec. 2.12; ISO Sec. 6.3; H&S
        Sec. 7.12 pp. 227-9.

3.2:        Under my compiler, the code

                int i = 7;
                printf("%d\n", i++ * i++);

        prints 49.  Regardless of the order of evaluation, shouldn't it
        print 56?

A:        Although the postincrement and postdecrement operators ++ and --
        perform their operations after yielding the former value, the
        implication of "after" is often misunderstood.  It is *not*
        guaranteed that an increment or decrement is performed
        immediately after giving up the previous value and before any
        other part of the expression is evaluated.  It is merely
        guaranteed that the update will be performed sometime before the
        expression is considered "finished" (before the next "sequence
        point," in ANSI C's terminology; see question 3..  In the
        example, the compiler chose to multiply the previous value by
        itself and to perform both increments afterwards.

        The behavior of code which contains multiple, ambiguous side
        effects has always been undefined.  (Loosely speaking, by
        "multiple, ambiguous side effects" we mean any combination of
        ++, --, =, +=, -=, etc. in a single expression which causes the
        same object either to be modified twice or modified and then
        inspected.  This is a rough definition; see question 3.8 for a
        precise one, and question 11.33 for the meaning of "undefined."
        Don't even try to find out how your compiler implements such
        things (contrary to the ill-advised exercises in many C
        textbooks); as K&R wisely point out, "if you don't know *how*
        they are done on various machines, that innocence may help to
        protect you."

        References: K&R1 Sec. 2.12 p. 50; K&R2 Sec. 2.12 p. 54; ISO
        Sec. 6.3; H&S Sec. 7.12 pp. 227-9; CT& Sec. 3.7 p. 47; PCS
        Sec. 9.5 pp. 120-1.

3.3:        I've experimented with the code

                int i = 3;
                i = i++;

        on several compilers.  Some gave i the value 3, and some gave 4.
        Which compiler is correct?

A:        There is no correct answer; the expression is undefined.  See
        questions 3.1, 3.8, 3.9, and 11.33.  (Also, note that neither
        i++ nor ++i is the same as i+1.  If you want to increment i,
        use i=i+1, i+=1, i++, or ++i, not some combination.  See also
        question 3.12.)

3.3b:        Here's a slick expression:

                a ^= b ^= a ^= b

        It swaps a and b without using a temporary.

A:        Not portably, it doesn't.  It attempts to modify the variable a
        twice between sequence points, so its behavior is undefined.

        For example, it has been reported that when given the code

                int a = 123, b = 7654;
                a ^= b ^= a ^= b;

        the SCO Optimizing C compiler (icc) sets b to 123 and a to 0.

        See also questions 3.1, 3.8, 10.3, and 20.15c.

3.4:        Can I use explicit parentheses to force the order of evaluation
        I want?  Even if I don't, doesn't precedence dictate it?

A:        Not in general.

        Operator precedence and explicit parentheses impose only a
        partial ordering on the evaluation of an expression.  In the
        expression

                f() + g() * h()

        although we know that the multiplication will happen before the
        addition, there is no telling which of the three functions will
        be called first.

        When you need to ensure the order of subexpression evaluation,
        you may need to use explicit temporary variables and separate
        statements.

        References: K&R1 Sec. 2.12 p. 49, Sec. A.7 p. 185; K&R2
        Sec. 2.12 pp. 52-3, Sec. A.7 p. 200.

3.5:        But what about the && and || operators?
        I see code like "while((c = getchar()) != EOF && c != '\n')" ...

A:        There is a special "short-circuiting" exception for those
        operators.  The right-hand side is not evaluated if the left-
        hand side determines the outcome (i.e. is true for || or false
        for &&.  Therefore, left-to-right evaluation is guaranteed, as
        it also is for the comma operator.  Furthermore, all of these
        operators (along with ? introduce an extra internal sequence
        point (see question 3..

        References: K&R1 Sec. 2.6 p. 38, Secs. A7.11-12 pp. 190-1; K&R2
        Sec. 2.6 p. 41, Secs. A7.14-15 pp. 207-8; ISO Sec. 6.3.13,
        Sec. 6.3.14, Sec. 6.3.15; H&S Sec. 7.7 pp. 217-8, Sec. 7.8 pp.
        218-20, Sec. 7.12.1 p. 229; CT& Sec. 3.7 pp. 46-7.

3.8:        How can I understand these complex expressions?  What's a
        "sequence point"?

A:        A sequence point is a point in time (at the end of the
        evaluation of a full expression, or at the ||, &&, ?:, or comma
        operators, or just before a function call) at which the dust
        has settled and all side effects are guaranteed to be complete.
        The ANSI/ISO C Standard states that

                Between the previous and next sequence point an
                object shall have its stored value modified at
                most once by the evaluation of an expression.
                Furthermore, the prior value shall be accessed
                only to determine the value to be stored.

        The second sentence can be difficult to understand.  It says
        that if an object is written to within a full expression, any
        and all accesses to it within the same expression must be for
        the purposes of computing the value to be written.  This rule
        effectively constrains legal expressions to those in which the
        accesses demonstrably precede the modification.

        See also question 3.9 below.

        References: ISO Sec. 5.1.2.3, Sec. 6.3, Sec. 6.6, Annex C;
        Rationale Sec. 2.1.2.3; H&S Sec. 7.12.1 pp. 228-9.

3.9:        So given

                a = i++;

        we don't know which cell of a[] gets written to, but i does get
        incremented by one, right?

A:        *No*.  Once an expression or program becomes undefined, *all*
        aspects of it become undefined.  See questions 3.2, 3.3, 11.33,
        and 11.35.

3.12:        If I'm not using the value of the expression, should I use i++
        or ++i to increment a variable?

A:        Since the two forms differ only in the value yielded, they are
        entirely equivalent when only their side effect is needed.
        (However, the prefix form is preferred in C++.)  See also
        question 3.3.

        References: K&R1 Sec. 2.8 p. 43; K&R2 Sec. 2.8 p. 47; ISO
        Sec. 6.3.2.4, Sec. 6.3.3.1; H&S Sec. 7.4.4 pp. 192-3, Sec. 7.5.8
        pp. 199-200.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP