zoukankan      html  css  js  c++  java
  • 预科C运算符与表达式

    1.运算符?

    是用来进行某种运算的符号

    几目运算符? 这个运算符需要几个操作数就称为几目

    单目运算符

    双目运算符

    三目运算符

    结合性 :从左至右 从右至左

    当两个运算符的优先级是一样的,看结合性

    优先级 :单目运算符 > 算术运算符 > 关系运算符 > 逻辑运算符 > 条件运算符 > 赋值运算符 > 逗号运算符

    1)算术运算符

    ++ -- :单目运算符

    * / % + - :双目运算符 ,结合性从左至右,先乘除后加减

    eg:

    5/4 =1 (整数进行算术运算其结果为整数)

    5.0/4 => 1.25

    double3/2=1.0

    double3/2 =1.5

    % :求余 ,要求两个操作数都必须为整数

    5%4 =>1

    4%5 =>4

    C语言的表达描述数学表达式  a/b => a*1.0/b

    a+b b+a C语言中含义是不一样的

    i = 5,j = 6;

    (i++) +(i+j) =>17

    (i+j)+(i++) =>16

    ======================

    表达式的值 做完表达式后i的值

    i++ i i = i+1

    ++i i+1 i = i+1

    i-- i i = i-1

    --i i-1 i = i-1

    eg:

    i = 5;

    a = i++;//把表达式(i++)的值赋值给ai++这个表达式的值为5

    a = (++i);

    NOTE:

    ++ -- 隐含了 “赋值”

    i = i+1;

    i = i-1;

    so :

    (i+j)++ =>error

    (1+2)++ =>error

    i++ ; =>i必须要是一个变量

    (2)关系运算符:用来判断两个东西的关系的运算符

    < <= > >=

    == !=

    双目运算符, 从左至右

    关系表达式 :用关系运算符连接起来的式子

    关系表达式的值 “关系成立 (1)”  “关系不成立(0)”

    eg:

    5 > 4  =>1

    3 <= 4 =>1

    5 > 4 > 3  这是一个合法的表达式

    5 > 4 > 3 =(5>4)>3

    =>1>3

    =>0

    数学上的5 > 4 > 3 C语言中的含义是不一样的

    如何描述我们数学上的5 > 4 > 3  

    5 >4 并且 4 > 3

    (3)逻辑运算符

    !  逻辑非  单目运算符  取反

    && 逻辑与   双目运算符  从左至右  “并且”

    || 逻辑或   双目运算符  从左至右  “或者”

    逻辑表达式 :用逻辑运算符连接起来的式子

    逻辑表达式的值 :逻辑真(非0,1) 逻辑假(0

    &&  :左右两边结果都为真 =》真

    || :左右两边只要有一者为真 =》真

    eg:

    a = 4,b = 5

    a && b =>1

    a || b =>1

    !a|| b =>1

    5 > 3 && 8 < 4-!0

    =>1 && 0 =>0

    练习:

    int a = 1,b = 2,c = 3,d = 4,m = 1,n = 1;

    (m = a > b) && (n = c > d);

    printf("%d %d %d %d %d %d ",a,b,c,d,m,n);

    =>1 2 3 4 0 1

    // m = 0  n = 1

    C语言运算符的“惰性运算”

    (1) a && b && c

    只有a为真,才需要判断b的值

    只有ab都为真,才需要判断c的值

    (2)a || b || c

    只要a为真,就不需要判断bc的值

    只有a为假,才需要判断b的值

    只有ab都为假,才需要判断c的值

    4)位运算符

    位运算符是按照bit为来进行计算运算

    &  按位与

    | 按位或

    ^ 按位异或

    ~ 按位取反

    <<  按位左移

    >> 按位右移

    除了~是单目运算符,其余都是双目运算符,结合性都是从左至右

    位运算的操作数只能是整数(int/short/long/char

    所有的位运算都需要把操作数变成bit位序列,然后在进行操作

    ~ (按位取反) 单目运算符

    0 ->1

    1 ->0

    int a = ~3;

    printf("%d ",a);//-4

    printf("%u ",a);//2^32-4

    ~3:

    00000000 00000000 00000000 00000011

    11111111 11111111 11111111 11111100

    %d:

    11111111 11111111 11111111 11111011 (-1)

    00000000 00000000 00000000 00000100

    %d =>-4

    %u:

    11111111 11111111 11111111 11111100

    %u =>2^32-1-3

    ===========

    int a = ~(-3);

    printf("%d ",a);//2

    printf("%u ",a);//2

    -3

    00000000 00000000 00000000 00000011 3

    11111111 11111111 11111111 11111100 (取反)

    11111111 11111111 11111111 11111101 (+1)

    ~(-3) 00000000 00000000 00000000 00000010

    %d :

    00000000 00000000 00000000 00000010

    %u :

    00000000 00000000 00000000 00000010

    -3+4:

    //==================================

    & (按位与) :双目运算符 “与”

    a b a&b

    1 1 1

    1 0 0

    0 1 0

    0 0 0

    & :如果两个bit位操作数都为1 ,结果才为1

    否则为0

    eg :

    3 & 5 == ?

    00000011

    00000101

    &   00000001

    假设有一个整型变量a.要把a的第5bit变为0,其他bit位不变,该如何操作?

    a :xxxx....Xxxxxx

    & :1111....011111   ~(1<<5)  00000000 00000000 00000000 00100000

    a = a & ~(1<<5)

    1&为原值,与0|为原值

    结论:

    一个bit位与0进行“按位与”,其结果为0

    x & 0 == 0

    一个bit位与1进行“按位与”,其结果保留原值

    x & 1 == x

    (-3)&(-5) =>

    -3  :11111101

    -5  :11111011

    & :11111001

    //==========================

    | (按位或) :双目运算符, 结合性从左至右

    a b a|b

    1 1 1

    1 0 1

    0 1 1

    0 0 0

    按位或,只有有一个bit操作数为1,其结果为1

    假设有一个整型变量a.要把a的第5bit变为置1,其他bit位不变,该如何操作?

    a :xxxx....Xxxxxx

    | :0000....100000   1 << 5

    a = a | (1<<5)

    (-3)&(-5) =>-1

    结论:

    一个bit位与0进行“按位或”,其结果保留原值

    x | 0 == x

    一个bit位与1进行“按位或”,其结果为1

    x | 1 == 1

    //=======================

    ^ (按位异或) 双目运算符  “异或”  不同为1 相同为0

    a b a^b

    1 1 0

    1 0 1

    0 1 1

    0 0 0

    练习:

    (-3)^(-5) =>6

    假设有一个整型变量a.要把a的第5bit变为置1,其他bit位取反,该如何操作?

    a = (a|(1<<5))^(~(1<<5))

    假设有一个整型变量a.要把a的第5bit变为保留,其他bit位取反,该如何操作?

    a :xxxx....Xxxxxx

    ^ :1111....011111   

    a = a^(~(1<<5))

    结论:

    一个bit位与0进行“按位异或”,其结果保留原值

    x ^ 0 == x

    一个bit位与1进行“按位异或”,其结果取反

    x ^ 1 == ~x

    //========================================

    << (按位左移)  双目运算符  将bit位整体往左边移

    a << n  abit位整体左移n

    高位左移后,丢弃,低位补0

    如果左移后丢弃的高位全部为0 ,那么左移n位,就表示原值乘以2n次方

    1 << 5

    >> (按位右移) : 双目运算符  将bit位整体往右边移

    x >> n  xbit位整体右移n

    低位右移后,舍弃 ,高位?

    有符号数 :高位全部补符号位

    无符号数 :高位全部补0

    int  a = -1;  //1111111 11111111 11111111 11111111

    a = a >> 31;

    printf("%d ",a);//-1

    ======

    unsigned int a = -1;//

    a = a >> 31;//00000000 00000000 00000000 00000001

    printf("%d ",a);//1

    (5) 条件运算符

    ?= 三目运算符

    expression1 ? expression2 : expression3

    上面是一个条件表达式:

    如果expression1的值为真,则整个条件表达式的值为expression2这个表达式的值

    如果expression1的值为假,则整个条件表达式的值为expression3这个表达式的值

    eg:

    a = 5>4 ? 4 :3;

    (6)赋值运算符  双目运算符  ,从右至左

    =

    a = 5+3;// 赋值运算符的左边必须是一个可写的地址(左值)

    赋值表达式 :有赋值运算符连接起来的式子

    赋值表达式的值就是最后赋值后左边变量的那个值

    a = 6;

    b = a = 5;//合法

    复合的赋值运算符:赋值运算符和算术运算符,位运算符组成的复合的运算符

    += -= %= *= /=

    <<=  >>=  |= &= ^=

    a  += 1  =a = a+1

    a += 5+6 => a = a +(5+6)

    (7) 逗号运算符:  双目运算符 优先级最低  从左至右

    表达式1,表达式2

    逗号表达式的求值顺序

    先求表达式1的值,然后再求表达式2的值

    整个表达式的值是表达式2的值

    int a = 5,b = 6;

    a = (a=6,a+b); =>12

    逗号表达式值扩展:

    表达式1,表达式2,....表达式n

    求值顺序

    先求表达式1的值,然后再求表达式2的值,再求表达式3的值

    ....一直求导表达式n的值

    整个表达式的值是表达式n的值

    (8)指针运算符

    *(指向)   &(取地址符)

    (9)求字节运算符 (sizeof

    sizeof()  :运算时只看括号内是什么数据类型,单位是字节

    sizeof(1)  =>4

    sizeof(1.0) =>8

    int a;

    sizeof(a+1) =>4

    sizeof(a+1.0) =>8

    printf("%d ",sizeof(1.0));

    (10) 分量运算符

    用来求结构体变量的成员变量

    .

    ->

    (11)下标运算符

    []  :用来求取数组元素

    int a[10];//定义了一个数组,数组名a,里面有10int元素

    a[0]

    (12)强制类型转换运算符

    (类型)

    float f = 3.6;

    (int)f +3.5 => 6.5

    (int)(f+3.5) =>7

    (13)其他

    函数调用运算符

    2.表达式

    表达某个意思的式子

    C语言中一般是用运算符连接操作数的式子,叫表达式

    是表达式就有一个值 =》表达式的值 =》表达式值类型

    作业:

    答案

    第一题(x>>p& ((1<<n) - 1)

    第二题 上题取出来| (y & ( ~0 << n))

    第三题 x ^ ( ( ( 1 << n ) - 1 ) << p )

    第四题 (x & ( ( 1 << n) - 1) << (sizeof(x) * 8 - n) ) | x>>n

    第二次尝试:

    1.x中第p位开始的nbit

    //先将x左移p是可以的,41,依次左移1,相与

    //大哥的思路 (x>>p&(~(-1<<n))

    2.x中第p位开始的nbit位设置为y中最右边的n位的值

    x的其余位不变

    //000111000这种的取到n之后的数值,再进行右移p

    //自己感觉,用~-1)进行取到所有的X,之后直接右移P位,但不知道会不会破坏原来的//数值  (x&(~(-1)))>>p    ((x>>p&(~(-1<<n))|y<<n

    3.x中第p位开始的nbit位取反,其余位不变

    //异或001100这种字符串

    //反正都是用-1,想到先右移p,再左移p,再全部相异或  x^(((-1)>>p)<<p)

    4.x循环右移n

    //还是用-1进行处理,((x | (-1) << n) << (long - n) ) | (x >> n)

    5.

    分析以下程序的输出结果

    char c = -56 >> 30;

    printf("%d ",c);

    printf("%u ",c);

    ========

    char c = -56u >> 30;

    printf("%d ",c);

    printf("%u ",c);

    第一次尝试:

    // 1.x中第p位开始的nbit

    //1<<(p + 1)..1<<(p + n) 每个与P进行按位与 ,最后叠加也进行与就好 再合并就好应该来说。。

    // 2.x中第p位开始的nbit位设置为y中最右边的n位的值

    // x的其余位不变

    //逆运算

    // 3.x中第p位开始的nbit位取反,其余位不变

    //n左移之后异或

    // 4.x循环右移n

    //取第一位,全体左移,替换最后一位

    // 5.

    // 分析以下程序的输出结果

    // char c = -56 >> 30;

    //-56补码 241 1100 0111   右移30位后 321 再取8

    // printf("%d ",c);

    //补码81,所以得到答案 -1255

    // printf("%u ",c);2^32 - 1

    // ========

    // char c = -56u >> 30;

    //-56补码 240 1100 0111   右移30位后 321 再取8

    // printf("%d ",c);右移后全为0  3 3 结果

    // printf("%u ",c);

    运算符优先级

    优先级

    运算符

    名称或含义

    使用形式

    结合方向

    说明

    1

    []

    数组下标

    数组名[整型表达式]

    左到右

     

    ()

    圆括号

    (表达式)/函数名(形参表)

     

    .

    成员选择(对象)

    对象.成员名

     

    ->

    成员选择(指针)

    对象指针->成员名

     

    2

    -

    负号运算符

    -算术类型表达式

    右到左

    单目运算符

    (type)

    强制类型转换

    (纯量数据类型)纯量表达式

     

    ++

    自增运算符

    ++纯量类型可修改左值表达式

    单目运算符

    --

    自减运算符

    --纯量类型可修改左值表达式

    单目运算符

    *

    取值运算符

    *指针类型表达式

    单目运算符

    &

    取地址运算符

    &表达式

    单目运算符

    !

    逻辑非运算符

    !纯量类型表达式

    单目运算符

    ~

    按位取反运算符

    ~整型表达式

    单目运算符

    sizeof

    长度运算符

    sizeof 表达式

    sizeof(类型)

     

    3

    /

    表达式/表达式

    左到右

    双目运算符

    *

    表达式*表达式

    双目运算符

    %

    余数(取模)

    整型表达式%整型表达式

    双目运算符

    4

    +

    表达式+表达式

    左到右

    双目运算符

    -

    表达式-表达式

    双目运算符

    5

    <<

    左移

    整型表达式<<整型表达式

    左到右

    双目运算符

    >>

    右移

    整型表达式>>整型表达式

    双目运算符

    6

    >

    大于

    表达式>表达式

    左到右

    双目运算符

    >=

    大于等于

    表达式>=表达式

    双目运算符

    <

    小于

    表达式<表达式

    双目运算符

    <=

    小于等于

    表达式<=表达式

    双目运算符

    7

    ==

    等于

    表达式==表达式

    左到右

    双目运算符

    !=

    不等于

    表达式!= 表达式

    双目运算符

    8

    &

    按位与

    整型表达式&整型表达式

    左到右

    双目运算符

    9

    ^

    按位异或

    整型表达式^整型表达式

    左到右

    双目运算符

    10

    |

    按位或

    整型表达式|整型表达式

    左到右

    双目运算符

    11

    &&

    逻辑与

    表达式&&表达式

    左到右

    双目运算符

    12

    ||

    逻辑或

    表达式||表达式

    左到右

    双目运算符

    13

    ?:

    条件运算符

    表达式1? 表达式2: 表达式3

    右到左

    三目运算符

    14

    =

    赋值运算符

    可修改左值表达式=表达式

    右到左

     

    /=

    除后赋值

    可修改左值表达式/=表达式

     

    *=

    乘后赋值

    可修改左值表达式*=表达式

     

    %=

    取模后赋值

    可修改左值表达式%=表达式

     

    +=

    加后赋值

    可修改左值表达式+=表达式

     

    -=

    减后赋值

    可修改左值表达式-=表达式

     

    <<=

    左移后赋值

    可修改左值表达式<<=表达式

     

    >>=

    右移后赋值

    可修改左值表达式>>=表达式

     

    &=

    按位与后赋值

    可修改左值表达式&=表达式

     

    ^=

    按位异或后赋值

    可修改左值表达式^=表达式

     

    |=

    按位或后赋值

    可修改左值表达式|=表达式

     

    15

    ,

    逗号运算符

    表达式,表达式,…

    左到右

    从左向右顺序结合

     

     

     

     

     

    作业答案

    1.x中第p位开始的nbit

    (x >> p)&((1<<n)-1)

    2.x中第p位开始的nbit位设置为y中最右边的n位的值

    x的其余位不变

    ((x>>p)&((1<<n)-1) )|(y&(~0<<n))

    3.x中第p位开始的nbit位取反,其余位不变

    x^(((1<<n)-1)<<p)

    4.x循环右移n

    (x&((1<<n)-1) <<(sizeof(x)*8-n)) | x >>n

    5.

    分析以下程序的输出结果

    char c = -56 >> 30;

    printf("%d ",c);//-1

    printf("%u ",c);//2^32-1

    -56的补码;

    11001000

    11111111

    ========

    char c = -56u >> 30;

    printf("%d ",c);//3

    printf("%u ",c);//3

    unsigned int : -56u

    补码:

    00000000 00000000 00000000 00111000 (56)

    11111111 11111111 11111111 11000111 (取反)

    11111111 11111111 11111111 11001000 -56的补码)

    00000000 00000000 00000000 00000011  >> 30

    int =>char

    00000011

    char =>int

    END

  • 相关阅读:
    JSP自定义标签_用简单标签控制标签体执行10次
    JSP自定义标签_用简单标签实现控制标签体是否执行
    eclipse 使用lombok 精简java bean
    转 :关于springmvc使用拦截器
    转: spring静态注入
    spring 4.0+quartz2.2 实现持久化
    排除maven jar冲突 maven tomcat插件启动报错 filter转换异常
    转 Quartz将Job持久化所需表的说明
    转 maven jetty 插件
    ORA-14300: 分区关键字映射到超出允许的最大分区数的分区
  • 原文地址:https://www.cnblogs.com/qihuanye-229110/p/11147299.html
Copyright © 2011-2022 走看看