1.取模运算%的左右两边都要是整形,5.0%2错误
2.除/左右两边类型不同时涉及到类型转换,5/2=2, 5.0/2=2.5
3.自增自减:
变量在前先取值使用再增减1;变量在后先增减1再取值使用。而且变量在前的情况是在表达式主体完成之后再自增自减。
int i = 1, j = 10, vl;
vl = i++ + ++j;
/*
等价于
i = i;
j += 1;
vl = i + j;
i +=1;//i++是在表达式主体完成vl赋值之后最后执行
*/
不可对常量操作,比如3++
同一表达式可以对多变量自增自减,但对同一变量多次自增自减,结果取决于不同的编译器,会有三种不同结果
vl = i++ + ++i - i-- + --i;
printf("vl=%d, i=%d\n", vl, i);
某编译器下:vl=2, i=1
4.逻辑与、逻辑或短路特性,只执行了最左边部分,后面的不执行
int a=1, b=2, c=3, d = 4;
int m =1, n = 1;
(m = a > b ) && (n = c > d);
printf("m:%d, n:%d\n", m, n);
以上m=0但n等1不等0。
m = a>b由于>优先级大于=,等价于(m = (a>b))
5.优先级助记:
1.方圆阔(括),点箭头;
//森林方圆很大,弓箭手向空中发射点燃的箭来表示集合地点
2.父未返(负位反),子(自)增减,星暗(and,&)罗飞(逻辑非)强转((类型))求长短;
//除了父亲其他都集合了,儿子们跑进跑出找父亲,星夜还有儿子拿出多功能罗盘,飞快转动
//罗盘指针来占卜父亲的方位和吉凶
3.除乘余;
4加减;
5左右移;
6.大大等,小小等;
7.恒等不等;
//除了大儿子乘余坐镇不乱,其他人踱来踱去,等来等去没等到父亲消息
8.位于(与)
9.易货(异或)
10.货(货)
11.鲫鱼(辑与)
12.货(或)
13.条运
//原来父亲在易货市场某货摊,林子里打的猎物换几条刚运来的鲫鱼
14.全父侄(赋值),除乘余,加减,左右移,位于(与)易货(异或)货(货)
//父亲所有的侄子也来帮忙找人,除了乘余,大家急的走来走去,传来消息父亲在市场易货
15.豆腐(逗符)
//还差豆腐,晚上喝鲫鱼豆腐汤
6.运算符同一优先级的结合性:
左到右:先对最左边运算符的左右两侧的数进行计算,接着次左侧的运算符左右两侧数据,以此类推。
右到左:先对最右边运算符的左右两侧的数进行计算,接着次右侧的运算符左右两侧数据,以此类推。三类:含赋值运算符的=、-=(大小关系的==、>=、!=不算),?:,“负位反子增减”同等优先级operator
int a = 6;
a -= a *= a += 3;//带赋值op结合性右到左,a=a+3=9;a=a*a=9*9=81;a=a-a=81-81=0
7.强转op()是一中间过程,没有改变被强转变量的类型。
8.按位异或:对应位相同为0,不同为1.(助记:意见相同同0同1就握手OK,意见不同要选出老1拍板)
9.嵌入式中位运算及其重要:
将操作数第n位置1,其他位不变:num = num | 1 < <n;
将操作数第n位置0,其他位不变:num = num & ~ (1 << n);
测试操作数第n位是0是1:if( num & 1<<n)
从一指定宽度的数中取出从第n位开始m位:num >> n & (1<<m+1)-1
10.逗号表达式,优先级最低。只取最后一个表达式的值作为逗号表达式的值。同时用了逗号运算符和赋值运算符,则需要特别注意,赋值运算符的优先级高于逗号运算符。
int a1, b = 2, c = 7, d = 5; // 第1行
a1 = (++b, c--, d+3); // 第2行
本例,对于第2行,由于用逗号分开的三个表达式被包含在括号内,
所以先计算这个括号内的表达式,再进行赋值。括号内的
表达式的最终值应该是最后一个表达式的值,也就是 (d+3) 的值,为 8,所以 a1 被赋值为 8。
int a1, b = 2, c = 7, d = 5; // 第1行
a1 = ++b, c--, d+3; // 第2行
本例,对于第2行,由于赋值运算符的优先级高于逗号运算符,
所以“a1=++b” 实际是逗号表达式中的一个子表达式,虽然最终
表达式的值虽然也为 8,求值之后,“++b” 的值为3,a1被赋值为 3,而整个逗号表达式的值为 8。