《C语言解惑》源码笔记摘录(Updating)

来源:互联网 发布:JavaScript字符串分割 编辑:程序博客网 时间:2024/06/01 07:22

// C语言解惑源码笔记摘录

附录A 操作符优先级表

运算符 操作符 关联规则 关联操作符 () [] -> . 从左到右 一元操作符 ! ++ – + - (type) * sizeof 从右到左 乘法和除法
    / %
从左到右 加法和减法 + — 从左到右 移位操作符 << >> 从左到右 关系操作符 < <= > >= 从左到右 “相等”比较 == != 从左到右 位操作符 & 从左到右 位操作符 ^ 从左到右 位操作符 从左到右 逻辑操作符 && 从左到右 逻辑操作符 从左到右 条件操作符 ?: 从右到左 赋值操作符 = += -= 等等 从右到左 逗号 , 从左到右
  • PS:只有一元操作符、条件操作符和赋值操作符是从右到左,其余均为从左到右。

1、赋值运算符

#include <stdio.h>#define PRINTX printf("%d\n",x)int main(){    int x=2,y,z;    x*=3+2;PRINTX;    x*=y=z=4;PRINTX;    x=y==z;PRINTX;    x==(y=z);PRINTX; 

}

  • 注意:
  • 1、第四步 x==(y=z);PRINTX;中
    初始值:x=1,z=4,(y=z)有(y=4),即有(x==4)为FALSE,即0。 但x值没发现变化(“==”操作符不改变操作数的值),所以PRINT语句仍然输出1。
  • 2、x++运算,有先计算后,后赋值;++x则相反。

2、逻辑操作符和增量操作符

#include <stdio.h>#define PRINT(int) printf("%d\n",int)int main(){    int x,y,z;    x=2;y=1;z=0;    x=x&&y||z;PRINT(x);    PRINT(x||!y&&z);    x=y=1;    z=x++-1;PRINT(x);PRINT(z);    z += -x++ + ++y;PRINT(x);PRINT(z);    z = x/ ++x;PRINT(z); }
  • 注意:
  • 1、为避免二义性,若一个字符串可以解释为多个操作符,则C编译器中有一个原则”构成操作符的字符个数越多越好”,
    根据该原则”x+++++y”解释为”x++ ++ +y”,不合法。因此表达时需”x++ + ++y”

  • 2、注意,z = x/ ++x;PRINT(z);类似写法最好不要。 因为 初始值:x=3,z=0;
    z = x/ ++x;等价于
    z = x/(++x);等价于
    z = (x/(++x));等价于
    (z = (x/(++x))); 不知道先++还是先/,也就是不清楚被除数是3还是4。

3、二进制位操作符

#include <stdio.h>#define PRINT(int) printf(#int"=%d\n",int)int main(){    int x,y,z;    x=03;y=02;z=01;    PRINT(x|y&z);    PRINT(x|y&~z);    PRINT(x^y&~z);    PRINT(x&y&&z);    x=1;y=-1;    PRINT(!x|x);    PRINT(~x|x);    PRINT(x^x);    x <<=3;PRINT(x);    y <<=3;PRINT(y);    y >>=3;PRINT(y);}
  • 注意:
  • 1、x=03,这里指的是x为八进制数3。同理,y、z均为八进制数2和1。
  • 2、x<<=3即x左移3位并赋值给x,同理y>>=为右移3位并赋值给y。左移n位,即对应的十进制数乘以2^n倍;右移n位,即对应的十进制数除以2^n倍

4、关系操作符和条件操作符

#include <stdio.h>#define PRINT(int) printf(#int "=%d\n",int)int main(){    int x=1,y=1,z=1;    x+=y+=z;    PRINT(x<y?y:x);    PRINT(x<y?x++:y++);    PRINT(x);PRINT(y);    PRINT(z+=x<y?x++:y++);    PRINT(y);PRINT(z);    x=3;y=z=4;    PRINT((z>=y>=x)?1:0);    PRINT(z>=y&&y>=x);}
  • 注意:
  • 1、在PRINT (x < y ? x++:y++); 中此时初始值x=3,y=2,z=1。则有(FALSE?x++:y++),即有((y++))=(2)(注意此处++为后缀,先计算后,自增赋值,因此输出仍为2。y输出后有y=3。且此处x++未被求值,所以此时仍有x=3)
  • 2、这里表明比较三个数大小时”z>=y>=x”错,”z>=y>=x”对。

5、操作符的优先级和求值顺序

#include <stdio.h>#define PRINT3(x,y,z) printf(#x "=%d\t" #y "=%d\t" #z "=%d\n",x,y,z)int main(){    int x,y,z;    x=y=z=1;    ++x || ++y && ++z;PRINT3(x,y,z);    x=y=z=1;    ++x && ++y || ++z;PRINT3(x,y,z);    x=y=z=1;    ++x && ++y && ++z;PRINT3(x,y,z);    x=y=z=-1;    ++x && ++y || ++z;PRINT3(x,y,z);    x=y=z=-1;    ++x || ++y && ++z;PRINT3(x,y,z);    x=y=z=-1;    ++x && ++y && ++ ++z;PRINT3(x,y,z);}
  • 注意:1、C语言中有规则:在按照从左到右的顺序对一个逻辑表达式求值时,只要知道它的实际结果就不会对其余结果求值。
  • eg:printtf(FALSE && (++y)),此时就不会对y进行求值了,直接输出结果为FALSE,即0,因为FALSE与任何值求与(&&)均为FALSE,即0
0 0
原创粉丝点击