嵌入式LinuxC语言运算符与表达式-创新互联

运算符与表达式
1.  运算符
    运算符:用来进行某种运算的符号
    eg:
        + - * / %

    a、几目运算符
        运算符需要带几个操作数
        单目运算符:运算符只需要一个操作数
            eg: ++ -- ……
        双目运算符:运算符需要两个操作数
            eg:+ - * / % ……
        三目运算符:运算符需要三个操作数
            eg:(表达式1) ? (表达式2):(表达式3)
    
    b、结合性
        决定运算式先算哪个,后算哪个
        从左至右的结合性,从右至左的结合性
        eg:
            + 从左至右的结合性
                a + b
                先算表达式a的值,再算表达式b的值,最后a+b
            在C语言中,表达式a+b和表达式b+a不一样
            eg:
                int i = 5, j = 6;
                (i++) + (i+j);//17 5+12 i++=5 i=6
                (i+j) + (i++);//16  11+5 i++=5 i=5

    c、优先级
        在一个含有多个运算符的表达式中,先算哪个运算符后算哪个运算符
        单目运算符 >算数运算符 >关系运算符 >逻辑运算符 >条件运算符 >赋值运算符 >d逗号运算符

    (1)算数运算符
        ++ --:单目运算符
        * / % + -:双目运算符,从左至右的结合性
            eg:
                3 + 5 =>8
                5 / 4 =>1 (整数进行算数运算的结果为整数)
                5.0 / 4 =>1.25
                    typeof(5 / 4) =>int
                    typeof(5.0 / 4) =>double
                (double)(3 / 2) =>1.0
                (double)3 / 2 =>1.5
            
            用C语言的表达式来描述一个数学表达式:
                数学:a / b
                C语言:(double)a / b
                        1.0*a / b
        
            %:求余,取膜,要求两边的操作数都必须为整数
                5 % 4 =>1
                5 % 1.0 =>ERROR
                4 % 5 =>4

            ++:自增运算符
                i++
                ++i

            --:自减运算符
                i--
                --i

            ++和-- 单目运算符,要求操作数必须为一个lvalue
                左值:location value 可写的地址 变量一边都会具备左值
                eg:
                    5++ ERROR 常量
                    (a+b)++ ERROR 表达式
                    (a++)++ ERROR

                    表达式的值  做完表达式后i的值
             i++        i           i=i+1
             ++i       i+1          i+i+1
             i--        i           i=i-1
             --i       i-1          i=i-1

             eg:
                int i = 5;
                int a = i++;
                printf("%d\n", a); //5
                printf("%d\n", i); //6

                int i = 6;
                (i++) + (i++) + (i++) //无意义,看编译器

    (2)关系运算符
        用来判断两个东西关系的运算符。
        "关系":数值大小关系
            >< ==
            >=<= !=
            双目运算符,结合性从左至右
        
        关系表达式:用关系运算符连接起来的式子
        关系表达式的值:
            关系成立    1
            关系不成立  0
        eg:
            表达式      表达式的值
            5 >4           1
            3<= 2          0
            5 >4 >3       0
     <=>(5 >4) >3 
                    5 >4表达式的值与3比较
                    1 >3
        
        (3)逻辑运算符
            用来描述逻辑关系的运算符
            !     逻辑非   单目运算符  “取反”
            &&     逻辑与   双目运算符  “并且”  从左至右的结合性
            ||     逻辑或   双目运算符  “或者”  从左至右的结合性

            逻辑表达式:用逻辑运算符连接起来的式子
            逻辑表达式的真:
                逻辑真(非0,1)
                逻辑假 0
            
            eg:
                a = 4, b = 5

                !a + 5 =>5

                5 >3 && 8< 3 - !0 //0
                    ->!0 1
                    ->3-1 = 2
                    ->1 && 0 =>0

                int a, b, c, d, m, n;
                a = 1;
                b = 2;
                c = 3;
                d = 4;
                m = n = 1;
                (m = a >b) && (n = c >d);
                printf("%d\n", m);  //0
                printf("%d\n", n);  //1

                C语言中的运算符是 惰性运算
                    (1) a && b && c
                        只有a为真时,才需要判断b的值
                        只有a和b都为真时,才会判断c的值
                        只要a为假,后面的b和c都不会判断
                    (2) a || b || c
                        只有a为假时,才需要判断b的值
                        只有a和b都为假时,才需要判断c的值
                        只要a为真,后面的b和c都不会判断
        
                用逻辑表达式判断y(年份)是否为闰年
                    1.平常闰年:能被4整除,但是不能被100整除
                    2.世纪闰年:嫩被400整除
                    if((y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0)))
                    {
                        printf("%d是闰年\n", y);
                    }
                    else
                    {
                        printf("%d不是是闰年\n", y);
                    }
                用逻辑表达式判断y(年份)是否不为闰年
                    !(y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0))
            
        (4)位运算符
            位运算符是指按bit位来进行的运算
            位运算要求操作数必须是整数

            有如下:
                &   按位与
                |   按位或
                ^   按位异或
                ~   按位取反
     <<  按位左移
                >>按位右移
            除了~是单目运算符之外,其他都是双目运算符,结合性都是从左至右
            位运算符操作数只能是整数
            所有位运算都需要把操作数变成bit序列,然后再按bit位来进行计算

            ~ (按位取反) :单目运算
                0 ->1
                1 ->0
            eg:
                int a = ~3;
                printf("%d\n", a);//-4
                printf("%u\n", a);//2^32-4
                    3:  00000000 00000000 00000000 00000011
                    ~3: 11111111 11111111 11111111 11111100
                    a:  11111111 11111111 11111111 11111100
                    %d: 符号位 1 负数
                        -1:    11111111 11111111 11111111 11111011
                        取反:  000000000 00000000 00000000 00000100
                        |负数|:4
                    %u:11111111 11111111 11111111 11111100

            &(按位与) :双目运算符
                a   b   a&b
                0   0    0
                0   1    0
                1   0    0
                1   1    1
            两个bit位都为1是才为1
            eg:
                int a = 3 & 5;//a=1
                3:00000000 00000000 00000000 00000011
                5:00000000 00000000 00000000 00000101
                &:-----------------------------------
                a:00000000 00000000 00000000 00000001

            假设一个整型变量a,把a的第bit4位变为0,其他bit位不变。
                a: xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxXxxx
                &: 11111111 11111111 11111111 1111110111<- ~(1<< 3)
                =>xxxxxxxx xxxxxxxx xxxxxxxx xxxxxx0xxx
                a = a & ~(1<< 3);
            一个bit位与0进行“按位与”的操作,结果为0
                x & 0 =>0
            证明:
                x为bit位,0 or 1
                when x == 0, x & 0 =>0
                when x == 1, x & 0 =>0
            一个bit位与1进行 “按位与”的操作,结果位其本身
                x & 1 =>x
            证明:
                x为bit位,0 or 1
                when x == 0, x & 1 =>0
                when x == 1, x & 1 =>1

            | (按位或) : 双目运算符
                a   b   a|b
                0   0    0
                0   1    1
                1   0    1
                1   1    1
            两个bit位都为0时才为0否则为1
            eg:
                int a = 3 | 5;// a=7
                3:00000000 00000000 00000000 00000011
                5:00000000 00000000 00000000 00000101
                |:-----------------------------------
                a:00000000 00000000 00000000 00000111

             假设一个整型变量a,把a的第bit5位置1,其他bit位不变。
                a: xxxxxxxx xxxxxxxx xxxxxxxx xxxXxxxxx
                |: 00000000 00000000 00000000 0000100000<- 1<< 5
                =>xxxxxxxx xxxxxxxx xxxxxxxx xxxx1xxxxx
                a = a | (1<< 5);
            一个bit为与0进行“按位或”的操作,其结果保留其原值
            一个bit为与1进行“按位或”的操作,其结果1

            (按位异或):双目运算符
                异或:求异(相同位0,不同为1)
                    a   b   a^b
                    0   0    0
                    0   1    1
                    1   0    1
                    1   1    0
                eg:
                    int a = 3 ^ 5;
                    3:00000000 00000000 00000000 00000011
                    5:00000000 00000000 00000000 00000101
                    ^:-----------------------------------
                    a:00000000 00000000 00000000 00000110

             假设一个整型变量a,把a的第bit5位置1,
                a: xxxxxxxx xxxxxxxx xxxxxxxx xxxXxxxxx
                x ^ 0 =>x
                x ^ 1 =>~x
                ^: 111111111 11111111 11111111 111011111  =>……(~(1<<5))
                =>~(xxxxxxxx xxxxxxxx xxxxxxxx xxxx)X~(xxxxx)
                a=a ^ (~(1<<5))
            一个bit为与0进行“按位或”的操作,其结果保留其原值
            一个bit为与1进行“按位或”的操作,其结果其值取反

交换两个整数a和b的值,不使用临时变量
    #includeint main(){
        int a = 1, b = 2;
        a = a^b;
        b = b^a;
        a = a^b;

        a= a+b;
        b = a-b;
        a = a-b;
        printf("%d  %d", a, b);
        return 0;
    }

        a:00000000 00000000 00000000 00000001
        b:00000000 00000000 00000000 00000010
        a^b:  00000000 00000000 00000000 00000011 
        a:00000000 00000000 00000000 00000011
        b^a:00000000 00000000 00000000 00000001
        b:00000000 00000000 00000000 00000001
        a^b:00000000 00000000 00000000 00000010 
        a:00000000 00000000 00000000 00000010

 << (按位左移) :双目运算符
                按bit位整体往左移
                a<< n 把a按bit位形式整体往左移n个bit位
                    高位左移后,舍弃。
                    低位会空出n个bit位,直接补0

                如果左移后舍弃的高位都是0,左移n位,(这个数必须是无五号是)表示原值乘以2的n次幂4
                    1<<8
                    00000000 00000000 000000000 00000001 1
                    00000000 00000000 000000001 00000000 1<<8 =>1 * 2^8
                    10000000 00000000 000000000 00000000 1<<32 是个负数
            
            >>(按位右移) :
                按bit位整体往右移
                x >>n 把x按bit位形式整体往右移n个bit位
                    低位多出n位舍弃
                    高位空出n位,无符号数,高位补0;有符号数补符号位。

            汇编中 逻辑位移 算数位移 循环位移
                逻辑位移:无符号位,逻辑左移和逻辑右移都补0
                算数位移:有符号位,算数右移补符号位,算数左移补0
                循环位移:移除的bit位补到空缺的bit位

            eg:
                int a = -1;
                a = a >>31;
                printf("%d\n", a);// -1
                printf("%u\n", a);// 2^32 - 1

                    |-1|:   000000000 00000000 000000000 00000001
                    取反:   11111111 11111111 11111111 11111110
                    +1:     11111111 11111111 11111111 11111111
                    -1:   11111111 11111111 11111111 11111111 在计算机中的存储形式
                    a:     11111111 11111111 11111111 11111111
                    a>>31: 11111111 11111111 11111111 11111111
                    %d: 
                        符号位为 1
                        -1: 11111111 11111111 11111111 11111110
                        取反:000000000 00000000 000000000 00000001
                        |-1|:000000000 00000000 000000000 00000001
                    %u:11111111 11111111 11111111 11111111

                unsigned int a = -1;
                a = a >>31;
                printf("%d\n", a);// 1
                printf("%u\n", a);// 1

                    |-1|:   000000000 00000000 000000000 00000001
                    取反:   11111111 11111111 11111111 11111110
                    +1:     11111111 11111111 11111111 11111111
                    -1:   11111111 11111111 11111111 11111111 在计算机中的存储形式
                    a:     11111111 11111111 11111111 11111111
                    a>>31: 0000000  00000000 00000000 00000001
                    %d: 000000000 00000000 000000000 00000001
                    %u:`000000000 00000000 000000000 00000001

                char a = -1;
                a = a >>31;
                printf("%d\n", a);// -1
                printf("%u\n", a);// 2^32 - 1
                    |-1|:   000000000 00000000 000000000 00000001
                    取反:   11111111 11111111 11111111 11111110
                    +1:     11111111 11111111 11111111 11111111
                    -1:   11111111 11111111 11111111 11111111 在计算机中的存储形式
                    a:     11111111
                    a >>31 短变长 11111111 11111111 11111111 11111111
                    %d: int
                        11111111 11111111 11111111 11111111
                        |-1|:000000000 00000000 000000000 00000001
                    %u:11111111 11111111 11111111 11111111

                unsigned char a = -1;
                a = a >>31;
                printf("%d\n", a);// 0
                printf("%u\n", a);// 0
                    |-1|:   000000000 00000000 000000000 00000001
                    取反:   11111111 11111111 11111111 11111110
                    +1:     11111111 11111111 11111111 11111111
                    -1:   11111111 11111111 11111111 11111111 在计算机中的存储形式
                    a:     11111111
                    a >>31 短变长 00000000 00000000 000000000 00000000 11111111
                                00000000 000000000 00000000 00000000 00000000
                    %d:00000000 000000000 00000000 00000000 00000000
                    %u:00000000 000000000 00000000 00000000 00000000


        (5) 赋值运算符
            双目运算符,结合性从右至左
            优先级排倒数第二,仅比都好运算符的优先级要高
            eg:
                a = x; 把表达式x的值赋值给a
                5 = 5; ERROR
                赋值运算符要求左边的操作数必须为一个"可写的地址" lvalue
                if(i = 0){

                }
                错误,等价于if(0)逻辑错误,运行不会错

            赋值表达式:由赋值运算符连接起来的式子
            赋值表达式的值:就是最后赋值给左边变量(左边可写地址)的那个值
            eg:
                表达式      表达式的值
                a = 6           6
                b = a = 6       6     把表达式(a = 6)的值,赋值给b
            
            复合赋值运算符:
                赋值运算符可以和算数运算符、位运算符组合成一个复合运算符
                    +=  -=  *=  /=  %=
         <<= >>= |= ^\   &\
                eg:
                    a += 5;<==>a = a + 5;
                    a += 5 + 6;<==>a = a + (5 + 6);
                    a >>= 5;<==>a = a>>5;

        (6) 条件运算符 :三目运算符
            条件表达式:expression ? a:b
                如果expression值为真,那么表达式的值为a
                如果expression值为假,那么表达式的值为b
                eg:
                    a = 5 >4 ? 1 : 0; //1

        (7) 逗号运算符 :双目运算符,优先级最低,结合性从左至右
            表达式1,表达式2
                逗号表达式的值,求值顺序:
                    先求表达式1的值,然后再求表达式2的值,
                    最后整个逗号表达式的值就是表达式2的值
                eg:
                    int a = 5, b = 6;
                    a = (a = 6, a + b)
                        先算a = 6
                        再说a+b的值12
                        整个逗号表达式为12

                    a = 6, b = 7, c = 8, d = 9
                逗号表达式扩展形式
                    表达式1,表达式2,……,表达式n
                        先算表达式1的值,
                        再算表达式2的值,
                        ...
                        最后求表达式n的值
                        整个逗号表达式的值就是表达式n的值

        (8) 指针运算符
            *
            &(取值符)
                &对象 : 取这个对象的地址,就表示是对象的指针
                输入:scanf("%d", &b);

        (9) 分量运算符
            求结构体中的成员变量(分量)
                .
                ->struct test
            {
                int a;
                char b;
                short c;
            };

            struct test t;

            t.a;
            t.b;
            t.c;

        (10) 下标运算符
            [下标] 
            int a[10];
                下标范围:[0,9]
                    a[0]
                    a[1]
                    ...
                    a[9]

        (11) 强制类型转换运算符
            (类型)
            (unsigned char)255
            (double)3 / 2<==>1.5 3.0/2
            (double)(3 / 2)<==>1  

        (12)求字节运算符
            sizeof 单目运算符,求一个对象或类型所占空间的字节数
                typeof(x)求类型     sizeof(typeof(x))   
                sizeof(x)
                    sizeof 不要求x存在,但是要求x的类型是确定的,因为类型确定,就可以知道所占内存的大小。
                sizeof(int);//4字节
                int a[10];
                sizeof(typeof(a[0]));//4字节

2. 表达式
    表达式:用来表达某个含义的式子
    在C语言中,表达式一般是用运算符连接起来的式子
    只要是一个合法的表达式,那么它就一定会有一个值,这个值就是该表达式需要表达的含义

总结:
1. 运算符
    a、几目运算符
    b、结合性
    c、优先级
        单目运算符 >算数运算符 >关系运算符 >逻辑运算符 >条件运算符 >赋值运算符 >逗号运算符
    1. 算数运算符
        /   %   ++  --
                表达式的值      做完表达式之后i的值
            i++     i               i = i+1
            ++i     i+1             i = i+1
            i--     i               i = i-1
            --i     i-1             i = i-1
    2. 关系运算符
        ><   >=<=  ==  !=
    3. 逻辑运算符
        &&  ||  !
    4. 位运算符
        &   |   ^   ~   >><<
        x & 0 =>0      x & 1 = x
        x | 0 =>x      x | 1 = 1
        x ^ 0 =>x      x ^ 1 = ~x
    5. 条件运算符
        ? :
    6. 赋值运算符
        =
        赋值表达式的值是赋值符号右边的表达式的值,即最终赋值给左边变量的值
    7. 逗号运算符
    8. sizeof(typeof(x))
    9. 其他

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧

为夏津等地区用户提供了全套网页设计制作服务,及夏津网站建设行业解决方案。主营业务为网站制作、成都网站设计、夏津网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
分享名称:嵌入式LinuxC语言运算符与表达式-创新互联
分享地址:http://scjbc.cn/article/pjsci.html

其他资讯