关于运算符小记

来源:互联网 发布:网络安全 书 知乎 编辑:程序博客网 时间:2024/05/21 23:34

一.++--操作符

首先从一段备受讨论的代码着手:

#include <stdio.h>

int main()

{

   int i=3;

   printf("%d\n",(++i)+(++i)+(++i));

   return 0;

}

这段代码曾经和同学讨论过很久,答案也很多,大多是151618这三种。

其实没有讨论的必要,答案可能是16或者18,这要看你的编译器怎么计算了。VC6中计算结果是16,就是采用先计算前两个i的合,就是i先自加两次,所以两个5相加;然后与第三个自加的i相加得结果16.

18的结果就是先三个i自加,然后再计算三者的和。但是就是不可能是15。原因应该是和计算机的体系结构有关,我的理解是在计算机执行上述操作时,一条指令将(++i+++i)调入执行,这两个(++i)进入保留栈后,由于i没有准备好,即执行两者相加的两个操作数为就绪态,所以先执行++i操作,这两个++i操作在硬件许可情况下并行执行,所以得到上面的结果,个人理解。

如果上面的代码中小括号全部去掉会怎么样呢?呵呵,在VC6中会报错:'++' needs l-value;但是不一样的情况我们经常会遇见很多++或者--出现的时候,这种情况我们就要遵从C语言中的“贪心法”规则:从左往右一个一个读入符号,如果读到下一个符号与先前读入的符号能够组成一个有意义的符号,则继续读入下一个符号,直到读入的符号不能与先前的符号组成一个有意义的符号;

二.一些比较容易出错的算术符优先级问题:

1..(点)的优先级高于**p.f等价于*(p.f),而不是(*p).f

2.[]的优先级高于*int *a[]等价于int *(a[]),一个元素为int指针的数组;是一个而不是int (*a)[],一个指向int数组的指针。

3.()高于*:int *fp()等价于int *fp()),fp是一个返回int *的函数;而不是一个返回int的函数指针。

4.算术运算符高于位移运算符a<<3+2等价于a<<(3+2)a,而不是先左移3再加2;注意位移运算符位移时需要注意位移量不要超过数据的长度,发生溢出!也不要小于0;

5.逗号运算符在所有的运算符中优先级最低i=1,2;等价于(i=1),2;而不是i=(1,2);

6.==和!=高于赋值符和位操作:如c=getchar()!=EOF等价于c=(getchar()!=EOF),而不是(c=getchar()!=EOF;(a&b!=0)等价于a&(b!=0),而不是(a&b)!=0。