关于运算符小记
2012-04-17 21:39
162 查看
一.++、--操作符
首先从一段备受讨论的代码着手:
#include <stdio.h>
int main()
{
int i=3;
printf("%d\n",(++i)+(++i)+(++i));
return 0;
}
这段代码曾经和同学讨论过很久,答案也很多,大多是15,16,18这三种。
其实没有讨论的必要,答案可能是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。
首先从一段备受讨论的代码着手:
#include <stdio.h>
int main()
{
int i=3;
printf("%d\n",(++i)+(++i)+(++i));
return 0;
}
这段代码曾经和同学讨论过很久,答案也很多,大多是15,16,18这三种。
其实没有讨论的必要,答案可能是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。
相关文章推荐
- 关于取地址运算符&以及指针的问题
- 小记:关于Visual Studio编译链接出现控制台闪退的解决办法
- 关于SystemUI的简单小记
- Asp.net关于用户验证小记
- C#2.0 关于new运算符、ref,out参数值
- 关于自加运算符与二元运算符
- 关于"&"运算符效率低下的问题,有什么好的解决办法?
- 【C#】开发小记——关于WebBrowser中使用百度地图PanTo之后滚轮放大缩小失效
- JavaScript中关于parseInt(),Number(),parseFloat()以及一元运算符“+”将字符串类型转换为数字类型的对比
- 运算符(%):关于负数求模该如何求解
- 关于编译器的内存分配有感小记
- 关于As效率及屏幕自适应的小记
- 关于C++多继承问题小记
- 关于web应用编码问题小记
- 关于拷贝构造函数和重载成员运算符=
- 小记:关于STM32进入低功耗模式后无法烧写程序的解决办法
- java中 关于运算符注意的事项
- #奇葩论--关于C语言中的仅用"[]"运算符实现加法运算
- 关于java中的图片压缩小记
- 关于注解support annotations 的小记