C语言------------运算符与表达式

目录

# 运算符与表达式

## 什么是运算符

## 什么是表达式

## 运算符的分类

### 算术运算符

### 左值 和 右值

### 关系运算符

### 逻辑运算符

#### 例题:

### 位运算符

#### 按位取反 ~

##### 例题

#### 按位与 &

##### 例题

#### 按位或 |

#####例题:

#### 按位异或 ^

#####例题:

#### 按位右移

#### 按位左移

##### 例题:

### 赋值运算符 =

### 条件运算符 ? :

### 逗号表达式

### sizeof()求字节运算符

### 分量运算符

### 下标运算符

### 强制类型转换的运算符

### 其他运算符

## 总结

### 运算符的优先级和结合性

### 运算符优先级


# 运算符与表达式

    C语言提供了所有你希望编程语言应该拥有的操作符,他甚至提供一些你意想不到的操作符。

    事实上,C语言之所以被很多人认为它很难精通就是因为它品种繁多的操作符。

    它的这个特点也是其他语言无法抗衡价值

## 什么是运算符

    顾名思义,就是说运算符用来表示某种运算的符号

    几目运算符?表示这个运算符要带几个操作数

        单目运算符: 该运算符只需要一个操作数 eg:++ --

        双目运算符: 该运算符只需要两个操作数 eg:+ - *

        三目运算符: 该运算符只需要三个操作数 eg:a>b?a:b

    结合性:  决定先算哪个操作数的问题

        从左到右 还有 从右到左

        eg:

            a+b

            b+a

             在C语言中,含义是不一样的

            + 结合性: 从左到右

        eg:

    int i =5 , j = 6;

            int a;

            a = (i++) + (i+j); //17

    int i =5 , j = 6;

            int b;

            b = (i+j) + (i++); //16

    int i =5 , j = 6;

            int a;

            int b;

            a = (i++) + (i+j); //17

            b = (i+j) + (i++); //18

    int i =5 , j = 6;

            int a;

            int b;

            a = (++i) + (i+j); //18

            b = (i+j) + (++i); //19

    i++ ====> i = i+1

    运算符的优先级:

                在含有多个运算符的表达式中,决定先算哪个运算符,后算哪个运算符的问题

                eg:

                    a+b*c

            单目运算符 > 算术运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符

## 什么是表达式

    表达式就是表达某个意思的式子

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

        3+5

    eg:

        sb250

        i love you

        520

    合法的表达式就一定会有一个值,因为任何表达式都需要表达某个意思

## 运算符的分类

### 算术运算符

    算术运算符:进行算术运算的运算符

    ++ -- : 单目运算符

    + - * / % : 双目运算符

        + - * / : 只需要你的操作数是一个数(整数或者小数都可以)

        % : 要求操作数必须是整数

        ++ -- : 小数,浮点型

    eg:

        3+5 = 8

        double + int ===》 double

        3.0 + 5 = 8.0

    int a,b;

        a + b;

    double f1 , f2;

        f1+f2;

    3.5 % 3 ==== error

        % 表示取余

    5/4 == 1

    5.0 / 4 = 1.25

    double / int   ===> double / double = double

    (double)(3/2) = 1.0

        (double)3/2 = 1.5

        3/2.0 = 1.5

    用C语言的表达式来表达数学表达式 a/b

            (double) a/b

            1.0*a / b

    % 求余数

            5 % 4 === 1

            6 % 7 === 6

        ++(自增)运算符,单目运算符,要求操作必须是一个左值

        --(自减)运算符,单目运算符,要求操作必须是一个左值

### 左值 和 右值

    在这里介绍一下

        为了理解一些操作数存在的限制,你必须要理解左边和右值之间区别。

    左值就是赋符号(=)左边的东西,右值就是赋值符号右边的东西

    eg:

        a = b + 25;

        a 就是 左值, b+25 就是右值

        他们两个可以互换吗??

        b + 25 = a;

        原先用作左边的a此时变成了右值,因为每个位置它是不是肯定包含一个值,然后 b+25 不能作为一个左值,

        因为它没有表示一个特定位置,因此,这个语句是非法!

            注意当计算机去计算 b+25 的时候,它的结果必然保存在机器的某个位置,但是我们作为程序员没有办法来预测到这个位置在什么地方!

    5++;    error    i++ === > i = i+1

    (a+b)++;    error

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

    i++         i               i+1

    ++i        i+1             i+1

    i--         i               i-1

    --i        i-1               i-1

### 关系运算符

    这一类运算符用于测试操作数之间的各种关系的,c语言提供所有常见的关系运算符

    不过,这一组操作符里面有一个大大的陷阱

    这一组操作符:

        >  >=  <  <=  !=  ==

    前面四个操作符的功能你一看就知道是什么意思??

    != 操作符用来测试 ”不等于“

    而== 操作符用于测试”等于“

    关系表达式:用关系运算符连接起来的式子,如: a < b    8 < 7

        关系表达式的值:

            关系成立 : 1

            关系不成立 : 0

    eg:

        5 > 4   1

        3 <= 4  1

        5 > 7  0

        3+5 < 7*8

    (3+5) < (7*8)

    8 < 56  ----> 1

    5 > 4 > 3  这个东西是一个合法的关系表达式

            1 > 3  ----> 0

    在C语言中, 5>4>3 这个表达式和数学5>4>3的表达式不一样

        (1)、在C语言中,5>4>3 ===》 1>3

        (2)、数学上,5>4>3

                5>3 并且 4>3

    ps:

        绝大部分其他的语言使用 = 操作符来进行比较 相等性 。在C语言中,你必须要用== 来进行比较,单个= 是赋值

        这个的陷阱在于: 在测试相等性的时候出现赋值符号也是合法的!! 它不是一个语法错误

            if(a==b)

            if(a=b)

### 逻辑运算符

    !     逻辑非       单目运算符          ”取反“

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

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

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

        逻辑表达式的值:

            逻辑为真: 1 (非0)

            逻辑为假: 0

    eg:

        int a = 4 , b = 5;

            a&&b; ===== 1

            a||b; ===== 1

            !a||b; ===== 1

            !a&&b; ===== 0

        5>3 && 8 < 4 - !0

        5>3 && 8 < 3

        1 && 0     =====> 0

     ps.   C语言运算符是”惰性运算“

        (1)、a&&b&&c

            只有当a为真的时候,才会去判断b

            同时a和b都为真的时候,才会去判断c

        (2)a||b||c

            只要当a为真的时候,那么就不会再去判断b和c的值了

            只有当a 为假的时候,才需要去判断b 的值

            当b 为假的时候,才需要去判断c 的值

### 位运算符

    位运算符是按bit为展开来进行运算,位运算符要求操作数必须是一个整数(兼容的整数),因为在进行位运算时,需要把操作数按bit展开。”按每一个bit位来进行操作的“

    &  按位与

    |  按位或

    ^  按位异或

    ~  按位取反

    >> 按位右移

    << 按位左移

    除了 ~ 是单目运算符之外,其他的位运算符全部是双目运算符,结合性是从左到右的,位运算的操作数只能是整型。所有的位运算都需要把操作数变成bit位序列,然后进行操作

#### 按位取反 ~

    1 ---》 0

    0 ---》 1

~3:

    0000 0011

    1111 1100

##### 例题

    int a = ~(-3);

    -3:

        0000 0011

        1111 1100

        1111 1101

    ~   0000 0010  ====>2

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

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

    int a = !(-3)

    printf("%d\n",a); //0

    printf("%u\n",a); //0

    !(非0) ==== 0

    NOTE:

        要注意 ~(按位取反) 和 !(逻辑非) 的区别

            !(3+5) ==== 0

            ~ (3+5) ==== ~8

#### 按位与 &

a   &   b

a   b   a&b

1   1   1

1   0   0

0   1   0

0   0   0

& 如果两个bit位都为1,结果才为1,否则为0

eg:

    3 & 5

    00000000    00000000    00000000    00000011

    00000000    00000000    00000000    00000101

    00000000    00000000    00000000    00000001 =====》1

    3 & 7

    00000000    00000000    00000000    00000011

    00000000    00000000    00000000    00000111

    00000000    00000000    00000000    00000011 ======》3

    3&&5 ====》 1

    5&&7 ====》1

NOTE:

    注意&(按位与)与&&(逻辑与)的区别

ps.

    一个bit位 与 0 进行按位与&操作,结果为0

        X & 0 ==== 0

        when x == 1  , 1&0 == 0

        when x == 0  , 0&0 == 0

    一个bit位 与 1 进行按位与&操作,结果保留原来的值

        X & 1 == X

        when x ==1 , 1 & 1 == 1;

        when x ==0 , 0 & 1 == 0;

#### 按位或 |

a | b

a   b   a|b

1   1   1

1   0   1

0   1   1

0   0   0

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

    3|5 === 7

    00000000    00000000    00000000    00000011

    00000000    00000000    00000000    00000101

    00000000    00000000    00000000    00000111 ====》7

    3||5 == 1

NOTE:

    要区分 | 按位或 和 || 逻辑或的区别

    一个bit位 与 1 进行 ”按位或|“的一个操作,结果为1

        X | 1 ==== 1

    一个bit位 与 0 进行 ”按位或|“的一个操作,结果保留原来的值

        X | 0 ==== X



 

#### 按位异或 ^

    "异或":求异,不同为1 ,相同就为0

a ^ b

a   b   a^b

1   1   0

1   0   1

0   1   1

0   0   0

eg:

    3^5 === 6

    00000000    00000000    00000000    00000011

    00000000    00000000    00000000    00000101

    00000000    00000000    00000000    00000110    ===>6

ps:

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

        x ^ 0 === x

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

        x ^ 1 === ~x

#### 按位右移

    X >> N 把 x 按照bit位整体往右边移动n位!

        低位右移后,舍弃  

            0000 1111 ----> xxxx 0000   (右移四位)

                高位补什么??  xxxx是什么??

                对于无符号数,高位就全部补0

                对于有符号数,高位就全部补原来的符号位

#### 按位左移

    双目运算符,按bit位左移

        2 << 1 ===> 4   0000 0010 ===> 0000 0100

        高位左移,舍弃,低位就补0

        如果左移动舍弃的高位是0,那么左移n位,表示的结果就乘以2的n次方

### 赋值运算符 =

    双目运算符 , 结合性从右到左

        x = y;

    把表达式y的值,赋值给x(隐含了一个条件 x必须是一个可写的地址,具备左值,一般来说,X为一个可变的数据对象 ”变量“)

    赋值表达式的左边(左操作数)必须为一个”可写的地址“  左值

    5 = 5; error

    2 + 3 = 5; error

    int i = 5;

    i++ = 6; error

    i = 6;

    赋值表达式:是由赋值运算符连接起来的式子,赋值表达式

    赋值表达式的值:就是你赋值后左边那个操作数的值

    i = 5;

    a = i = 5;

        ====>

    a = (i = 5);

    复合的赋值运算符 : 赋值运算符可以和算术运算符,位运算符复合的赋值运算符

     += -= *= /= %= >>= <<= != |= &= ^=

     a+=b ====> a = a + b;

     a >>= 2 ====> a = a >> 2;

     a = a+b ; ===> a+=b;

### 条件运算符 ? :

    三目运算符 结合性从右到左

    experion ? a : b

    上面这个是一个条件表达式

        如果experion的值是为真,则整个条件表达式的值就为a

        如果experion的值是为假,则整个条件表达式的值就为b

    eg:

        if(a>b)

        {

            a = 250;

        }

        else

        {

            a = 520;

        }

         a = (a>b) ? 250 :   520

         a = (a>b) ? (a = 250) : (a = 520)

### 逗号表达式

    双目运算符,优先级就是最低的,结合性从左到右

   

    表达式1 ,表达式2 ,表达式3 ......

    逗号表达式的求值顺序:先求表达式1的值,再求表达式2的值,再求表达式3的值

        整个逗号表达式的值就是表达式3的值

   

    eg:

        int a = 5 , b =6;

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

        逗号表达式的扩展形式:

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

            求值顺序:  

                先求1,2,3,4,5,最后整个逗号表达式的值,是不是就是表达式n的值

### sizeof()求字节运算符

    sizeof(类型); 求出这个类型的字节数

    sizeof(typeof(1));

    sizeof(typeof(1.0));

### 分量运算符

    求结构体的成员变量  .  ->

    等后面结构体的专题再讲

### 下标运算符

    int a[10];

    a[0];

    a[1];

    a[2];

    []

    .....

    后面数组的时候也会涉及

### 强制类型转换的运算符

语法:(类型)值

    eg:

        (int)3.5 ===>3

        typeof((int)3.5) ===> int

### 其他运算符

    如:

        函数调用符()

## 总结

### 运算符的优先级和结合性

     = 不同于 ==

    由Algol派生而来的大多数程序设计语言,例如:Ada,使用:== 作为赋值运算符,但是符号 = 作为比较运算符,而我们的C使用了另外一种表示方法,符号 = 作为赋值,== 作为比较!

    一般来说,赋值运算符肯定是比 比较运算符,出现次数更加多,因此字符较少的 = 作为了赋值运算符

        该语句的本意应该是检查x是否等于y

        if(x = y)

        {

            ...

            break;

        }

        实际上将 y赋值给了x

         &和| 不同于 && 和 ||

### 运算符优先级

    我们需要记住两句话:

        1、任何一个逻辑运算符的优先级低于任何一个关系运算符

        2、移位运算符的优先级要比算术运算符要低,但是要比关系运算符要高

你可能感兴趣的:(c语言,算法,开发语言)