C语言【运算符、分支控制语句】1、运算符分类

  • 按照操作个数分类:

    一元运算符(一目运算符):只有一个操作数。如 负号 -1。

    二元运算符(二目运算符):有两个操作数。如 加号 1+2。

    三元运算符(三目运算符):有三个操作数。如 ?: a>b?1:2。

  • 按功能分类:

    算数运算符:正(+)、负(-)、加(+)、减(-)、乘(*)、除(/)、取模(%)、自增(++)、自减(–)。

    赋值运算符:赋值(=)、相加赋值(+=)、相减赋值(-=)、相乘赋值(*=)、相除赋值(/=)、取余赋值(%=)、左移赋值(<>=)、按位与赋值(&=)、按位异或赋值(^=)、按位或赋值(|=)。

    int te = 0;// if里是赋值if(te = 0){     // te=0 的结果为所赋的0printf("abcdefg");// 不会执行}
    // 连续赋值int a = b = c = 6;// 从右往左赋值,a、b、c都为6
    // 相乘赋值+连续赋值int a = 2;int c; // 下面中间那个c得提前定义。int b = c = a*=3;  // a、b、c都为6

    ​赋值运算符一般是从右往左运算。运算方向是当表达式中出现多个该运算符时每个运算符的操作顺序。

    关系运算符:相等(==)、不等(!=)、小于()、小于等于(=)。

    ​关系运算符的结果为0或1

    逻辑运算符:逻辑与(&&)、逻辑或(||)、逻辑非(!)

    ​逻辑与(&&)也叫短路与,如果&&前面的表达式为0时,后面的表达式不作运算,直接返回为0;

    ​逻辑或(||)也叫短路或,如果||前面的表达式为1时,后面的表达式不作运算,直接返回1。

    ​在表达式前加逻辑非时记得给表达式加括号。

    ​逻辑运算符的结果为0或1

    位运算符:按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、按位左移(<>)

    左移n位就相当于乘2的n次方右移n位就相当于除以2的n次方

    int a = 10; a >> 3;// a不发生改变,因为没有再赋值给a
    int b = 10;b = b >> 3; // b在原来的基础上缩小了2的3次方。 10 / 3 = 1
    int y = -10;y = y >> 2;printf("%d\n", y);// -3        //   -10 / 4 = -2...-2     把商的-2退为-3, 即 -10 / 4 = -3...2

    负整数的除法和右移操作结果并不一样,如下:

    int z = -10 / 4;printf("%d\n", z);// -2

    左移时出现的溢出问题:左移时,会出现结果大过所接收值类型范围导致溢出。

    // 第一种情况,如果只关心输出结果,而不关心是不是在类型范围内,可以在输出时使用大格式,把超出的看作有效int num_max = 0x7fffffff;num_max  = num_max<<2;   // 乘4,已经超过了int能表示的范围printf("%lld", num_max);  // 输出时使用 %lld 把超出的范围也视作有效
    // 第二种情况,就是想知道溢出后在有效范围内为多少,也就是这个数的实际值,可以看作对类型能表示的个数取余int num_max = 0x7fffffff;num_max  = num_max<<2;   // 实际结果8589934588,超了。 8589934588 % int能表示的个数(4294967296) = 4294967292。   num_max类型为有符号int, 4294967292最高位为1,转换为原码为-4,所以num_max为-4。在内存种这32位里存的就是4294967292的二进制形式。printf("%d", num_max);  //  %d 表示有符号int, 4294967292最高位为1,转换为原码为-4,输出-4

    有符号数右移时,对于负数,前面空出来的位全补1;对于正数,前面空出来的位全补0。

    遗留问题:按位异或可以实现交换两个变量的值,如何实现的?原理是什么?

2、运算符的优先级

​具体的不作了解,使用时不确定就用括号。

​总体来说:一元运算符 > 算数运算符 > 关系运算符 > 逻辑运算符 > 三元运算符 > 赋值运算符

从右到左运算是指同一表达式出现多次同一运算符时,运算的方向。

​右到左的运算符有: todo

3、记几个整型和浮点型之间的运算。

// 整型的除法运算int num01 = 10;int num02 = 3;int num03 = num01 / num02;// 3
// 浮点型接收整型的运算float num04 = 10 / 3;// 断点调试此处为3, printf用%f输出时记得补6位小数

问题:上行代码的num04如果用%f输出是3.000000,如果用%d输出呢?我试了试是0。为什么?

// 浮点型与整型的运算float num05 = (float)10 / 3;// 3.33333325printf("%f\n", num05);// printf用%f输出时保留6位小数为3.333333
// 浮点数参与的运算其实是四舍五入的,手动保留小数时也是四舍五入float num06 = (float)20 / 3; //     6.66666651printf("%f\n", num05);// 6.666667

4、取余(%)操作时,余数的符号跟着被除数(前面的数)的符号。5、关于自增(++)和 自减(–)

​不多解释,举个特别的例子。

/**i=i++时第一步:将i的值放到临时空间,作为后续运算的依据第二步:将i的值+1第三步:将临时空间里存进去的值拿出来赋给i (如果是j=i++时这一步就是赋给j)*/int i = 1;i = i++;printf("%d\n", i); // 1
/**i = ++i时不多解释,上面步骤 二、一、三*/int i = 1;i = ++i;printf("%d\n", i);// 2

注意:以上这两种情况在gcc可以编译通过,在clang编译器编译时就会报错。