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

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

附录A 操作符优先级表

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

1、赋值运算符

#include 
#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 
#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 
#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 
#define PRINT(int) printf(#int "=%d\n",int)

int main()
{
    int x=1,y=1,z=1;

    x+=y+=z;
    PRINT(xPRINT(xPRINT(x);PRINT(y);

    PRINT(z+=xPRINT(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

你可能感兴趣的:(C语言)