C-运算符
&&与|| 的短路规则应该都知道。。
++
看一下自增运算符: ++ -> 这里看一下后增, 即到底什么时候增??
看下面这两个程序:
#include <stdio.h>
int g = 0;
int f()
{
return g++;
}
int main()
{
if( f() && f() )
{
printf("%d\n", g);// 那肯定就是0啦。 这里是进不来的
}
printf("%d\n", g); //1
return 0;
}
#include <stdio.h>
int f(int i, int j)
{
printf("%d, %d \n", i, j);
}
int main()
{
int k = 1;
f(k, k++); //结果 : 2 ,1
printf("%d\n", k); //2
return 0;
}
上面两个程序,我们需要讨论一个问题就是, ++(后增)到底什么时候去改变其所作用的变量的值?
->答案是,当到达程序执行的顺序点时。
顺序点:它是指在执行过程中修改变量值得最晚时刻。
一般编译器规定: 在程序达到顺序点的时候,之前所做的以前操作都必须反应到后续的访问操作中。
那么程序中那些地方是顺序点呢?
1)每个完整表达式的结束
2)&&, ||, ?:, 以及逗号表达式的每个运算对象计算之后
3)函数调用中对所有时间参数的求值完成之后。(在进入函数之前)
对于上面的程序,你如果知道
1)++(后增)运算符的实现原理
2)再加上顺序点的原理,肯定就能理解结果为什么是这样的。
后增的实现原理
1)先用一个临时变量记住被增变量
2)对被增变量执行增加运算
3)返回先前的临时变量
!
你要知道它到底是干什么?
! 它只认识0, 即看到0他就返回1, 不是0他就返回0
三目运算符
对于三目运算符,我们需要知道一点, -> 它返回的是值, 而不是变量, 即不能作为左值。
那么如何让他作为左值呢(搞到内存不就好办了)?
int a = 1, b = 2, c = 3;
*(a < b ? &a : &b) = 3; //返回的是a这个变量
printf("%d\n", a); //a变成了3
贪心法则
何为贪心法则呢? 他是编译器处理符号的一种方式:
1)编译器处理的每个符号应尽可能多的包含字符
2)编译器以从左向右的顺序一个一个尽可能多的读入符号
3)当读入的字符不可能和已经读入的字符组成合法字符为止.
看下面的例子:
y/*p = ? //这里p是一个指针
int i = 2;
a+++b -> (a++) + b
++i+++i+++i = ?; //这是错误的, 按照贪心法则, 会这样解析: ++i之后变为了2,继续就变成 2++ 但是常量能自加吗???
贪心法则是不是很坏呢? 是不是一不小心就套进去了? 怎么遏制呢?
-> 贪心法则的遏制符 ” “, 对空格。 空格不仅能遏制贪心法则, 还可以让程序美观。
这些知道为什么大牛的C程序为什么都那么多空格了吗??????
应该知道的几个优先级
如果你实在不想去记那些优先级, 最好的办法是在该加括号的地方加括号->都能看明白。
不过知道下面这几个优先级关系, 好处还是很大的:
1) . 的优先级高于 *
2) [] 的优先级高于 *
3) 函数() 的优先级高于 *
4) == 和 != 高于位操作运算符
C语言的隐式类型转换
1)算术运算符中,低类型转换为高类型(double)
2)赋值表达式中, 表达式的值转换为左边变量的类型
3)函数调用时,实参类型转换为形参
4)函数返回值中, return表达式的值转换为返回类型