看看你的C语言水平如何-- <测试2>

[复制链接]
2743|7
 楼主| mindshare 发表于 2012-6-5 15:46 | 显示全部楼层 |阅读模式
本帖最后由 mindshare 于 2012-6-5 16:02 编辑

不上机你能知道数组a的内容会被改成什么吗?上机知道结果了,你能知道原因吗?:)
  1. // 测试题目 --> 1
  2. void main(void)
  3. {
  4.         int i = 0;
  5.         int x = 0;
  6.         int a[4] = {11,22,33,44};        

  7.         a[x++] = a[x++] + 1;
  8.         
  9.         for(i=0;i<4;i++)
  10.         {
  11.                 printf("%d \n",a[i]);
  12.         }
  13. }


  1. // 测试题目 --> 2
  2. int f(void)
  3. {
  4.         static int x = 0;

  5.         return (x++);        
  6. }

  7. void main(void)
  8. {
  9.         int i = 0;
  10.         int a[4] = {11,22,33,44};        

  11.         a[f()] = a[f()] + 1;
  12.         
  13.         for(i=0;i<4;i++)
  14.         {
  15.                 printf("%d \n",a[i]);
  16.         }
  17. }
 楼主| mindshare 发表于 2012-6-11 17:03 | 显示全部楼层
复合操作符
+=                -=                *=                /=                %=                <<=                >>=                &=                ^=                |=

        优点:代码更容易阅读和书写,效率更高

        这里只以+=为例讨论,其他具有同样的效果
        a += expression 它的功能相当于 a = a + expression
        唯一的不同之处是+=操作数只求值一次,它们确保表达式在执行加法运算前已经被完整求值。
        a = a + 5和a+=5之间的差别并不明显,因为现在的编译器知道优化a的运算为一次,但如下情况就不一样了。
        a[f()] += 1;                        //        a[f()]只求值一次
        a[f()] = a[f()] + 1;              //        编译器不知道f()是否有副作用,会对a[f()]求值两次       

        所以,在某些情况下使用复合操作符效率更高
李冬发 发表于 2012-6-11 21:10 | 显示全部楼层
a[x++] = a[x++] + 1;
---------
不同的编译器会给出不同的结果。

评分

参与人数 1威望 +1 收起 理由
mindshare + 1

查看全部评分

highgear 发表于 2012-6-11 22:11 | 显示全部楼层
这是 c 语言的语法问题, 不同的编译器都会给出相同的结果.

a[x++] = a[x++] + 1; 等效于 a[x] = a[x] + 1; x++; x++;

评分

参与人数 1威望 +1 收起 理由
mindshare + 1

查看全部评分

 楼主| mindshare 发表于 2012-6-12 00:05 | 显示全部楼层
++ 和 --
        前缀和后缀形式的增值操作符都复制了一份变量值的拷贝。用于周围表达式的值正是这份拷贝,前缀操作符在进行复制之前增加变量的值,后缀操作符在进行复制之后才增加变量的值,这些操作符的结果不是被它们所修改的变量,而是变量的拷贝
 楼主| mindshare 发表于 2012-6-12 00:07 | 显示全部楼层
求值顺序是可以保证下面的语句
        if(count!=0) && sum/count < smallaverage)
        即使当变量count为0时,也不会产生一个”用0作除数”的错误
        c语言中的某些运算符总是以一种已知的、规定的顺序来对其操作数进行求值,而另外一些则不是,例如: a<b&&c<d
        c语言的定义说明a<b应当首先被求值,如果a<b,此时必须进一步对才c<d求值,以确定整个表达式的值,如果a大于b或者等于b,则无需对c<d求值,表达式肯定为假

        c语言中只有四个运算符(&&、||、?: 和,)存在规定的求值顺序。
        运算符&&和||都是先对左侧操作数求值,只有需要时才对右侧的操作数求值。
        运算符?:在a?b:c中,操作数a先被求值,根据a的值再求操作数b或者c的值,
        逗号运算符,先对左操作数求值,该值被”丢弃”,再对右操作数求值,作为表达式结果

        c语言中其他所有运算符对其操作数求值的顺序是未定义的,尤其是,赋值运算符并不保证任何求值顺序。例如:
        y[i] = x[i++];
        y[i]中的i是在i自增之前,还是i自增之后求值是没有任何保证的。
断点断了 发表于 2012-6-12 10:14 | 显示全部楼层
只是逻辑上复杂点而已...
cainiao518 发表于 2020-9-15 13:36 | 显示全部楼层
有点复杂
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

114

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部