C语言、操作符
我们经常能够听见二进制、八进制、十进制、16进制这样的讲法,那他们到底是什么意思呢? 在讲操作符之前首先我们得明白二进制和进制的转换。 ``` 5的2进制:111115的8进制:1715的10进制:1515的16进制:F ``` > **二进制:** 在我们生活中见到最多的就是十进制了,在我们的脑子里已经有了对十进制的刻板的印象了,满10进1。 十进制的每一位数字都是由0~9组合而成的。 其实二进制也是像这样,都是由0、1组合而成。满二进一。 > **⼆进制转10进制:** 就比如我们的123是十进制的,为什么是123呢? 其实每一位都是有权重的,,10 进制的数字从右向左是个位、⼗位、百位....,分别每⼀位的权重是 10零次方 ,10一次方 ,10二次方 以此 类 推。  二进制的权重和10进制类似,只不过二进制的权重为2,从右向左是个位、十位、百位…… 每一位的权重分别为2的次方数,从0开始跟十进制的相似,以此类推。 图片 > **十进制转二进制数:**  剩余的二进制转8、16进制的方法都类似。 8进制的数字每⼀位是0~7的,0~7的数字,各⾃写成2进制,最多有3个2进制位就⾜够了,⽐如7的⼆ 进制是111,所以在2进制转8进制数的时候,从2进制序列中右边低位开始向左每3个2进制位会换算⼀ 个8进制位,剩余不够3个2进制位的直接换算。  16进制的数字每⼀位是0~9,a~f的,0~9,a~f的数字,各⾃写成2进制,最多有4个2进制位就⾜够了, ⽐如f的⼆进制是1111,所以在2进制转16进制数的时候,从2进制序列中右边低位开始向左每4个2进 制位会换算⼀个16进制位,剩余不够4个⼆进制位的直接换算。  > **原码、反码、补码:** 整数二进制的形式有3种,原码反码补码这三种形式。 有符号整数的分有符号位和数值位两部分,2进制序列中,最⾼位的1位是被当做符号 位,剩余的都是数值位。 符号位都是用0表示“正”,用1表示“负”。 原码:就是二进制序列的形式。 反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。 补码:反码+1的操作。 补码转换源码:可以按照之前的方法返回去,也可以直接对补码取反+1d操作。  正数的原码反码补码都相同,负数的各不相同。 对于整型的数据来说,在计算机中我们存放的都是按照补码的形式来存放。 ## 操作符: > **1、赋值操作符: = 、 += 、 -= 、 *********= 、 /= 、 %= 、 >>= 、int main() {int a = 10; a += 5; printf("a += 5 后:%d\n", a); a -= 3; printf("a -= 3 后:%d\n", a); a *= 2; printf("a *= 2 后:%d\n", a); a /= 2; printf("a /= 2 后:%d\n", a); a %= 3; printf("a %%= 3 后:%d\n", a); a = 8; a >>= 1; printf("a >>= 1 后:%d\n", a); a >=`=`、 **2、关系操作符: > 、 >= 、 int main(){int a = 10, b = 5;printf("a > b :%d\n", a > b); printf("a >= b :%d\n", a >= b); printf("a b) {printf("a比b大\n"); }return 0;} ``` > **3、算数操作符: + 、- 、 ********* 、 / 、 %** 这类操作符就相当于我们数学中的 加减乘除 和取余。  代码的实列: ``` #include int main() {int a = 10, b = 3;float c = 10.0, d = 3.0;printf("===== 整数运算 =====\n");printf("a + b = %d\n", a + b); printf("a - b = %d\n", a - b); printf("a * b = %d\n", a * b); printf("a / b = %d\n", a / b); printf("a %% b = %d\n", a % b); printf("\n===== 浮点运算 =====\n");printf("c + d = %.2f\n", c + d); printf("c - d = %.2f\n", c - d); printf("c * d = %.2f\n", c * d); printf("c / d = %.2f\n", c / d); printf("\n===== 单目+/-用法 =====\n");int num = 8;printf("+num = %d\n", +num); printf("-num = %d\n", -num); printf("\n===== 取模符号规则 =====\n");printf("(-10) %% 3 = %d\n", -10 % 3); printf("10 %% (-3) = %d\n", 10 % -3); return 0;} ``` > **4、移位操作符: > 注意:>这两个操作符的操作数只能是整数**。 我们了解完二进制的形式,就能学习>操作符了。 > **左移:int main(){int num = 10;int n = num **右移:>>** 移位规则:首先右移运算分两种: 1. 逻辑右移:左边用0填充,右边丢弃 2. 算术右移:左边用原该值的符号位填充,右边丢弃 ``` #includeint main(){int num = 10;int n = num>>1;printf("%d\n",n);printf("%d\n",num);return 0;} ``` VS编译器演示:  在我们的VS编译器中采用的是逻辑右移而不是算数右移。  > 5、单⽬操作符:!、 ++ 、-- 、 & 、 * 、 + 、 、 ~ 、 sizeof 、 ( 类型 )  > 6、逻辑操作符: && 、 || 图片  我们可以用在循环中,或者条件判断中: ``` #includeint main(){int n = 0;int m = 0;scanf("%d %d",&n,&m);if( n>0 && m>0) {printf("haha\n"); }if(n **6、位操作符: & | ^** ``` & | ^ ~ ``` 注意:他们的操作数必须为整数。 例如: ``` #include int main(){int num1 = -3;int num2 = 5;printf("%d\n", num1 & num2);printf("%d\n", num1 | num2);printf("%d\n", num1 ^ num2);printf("%d\n", ~0);return 0;} ```  > 7**、条件操作符: ? :** ``` 条件表达式 ? 表达式1 : 表达式2 ``` 执行逻辑:条件表达式判断,为真执行表达式1,为假执行表达式2。 ``` #include int main() {int num1 = 25, num2 = 18;int max_num = (num1 > num2) ? num1 : num2;printf("%d\n",max_num);return 0;} ```  > **8、逗号表达式: ,** ``` 表达式1,表达式2,表达式3,……表达式n ``` 逗号表达式:就是用逗号隔开的表达式。 执行规则:从左向右依次执行。整个表达式的结果是最后一个表达式的结果。 例如: ``` #includeint main(){int a = 1;int b = 2;int c =(a>b,a = b+1,b = a+1);printf("%d\n",c);return 0;} ```  > **9、下标引⽤: ****[**** ****]** 这个操作符是使用在数组当中。 操作数:⼀个数组名+⼀个索引值(下标) ``` int arr[10]={0};arr[9]=10; ``` [ ]的操作数是arr和9。 > **10、函数调⽤: ()** 接受⼀个或者多个操作数:第⼀个操作数是函数名,剩余的操作数就是传递给函数的参数。 ``` #includevoid test(){printf("haha\n");}int main(){test();return 0} ``` > **11、结构体成员访问操作符:. 、 ->** 结构体成员的直接访问: ``` #include struct Point{int x;int y;}p = {1,2};int main(){printf("x: %d y: %d\n", p.x, p.y);return 0;} ``` 使用方式:结构体变量 **.** 成员名 结构体成员的间接访问: ``` struct Point { int x; int y; };Point p1;p1.x = 10; ``` ``` #include struct Point{int x;int y;};int main(){struct Point p = {3, 4};struct Point *ptr = &p; ptr->x = 10; ptr->y = 20;printf("x = %d y = %d\n", ptr->x, ptr->y);return 0;} ``` 使用方式:结构体指针->成员名 > **操作符的优先级和结合性:** ### 优先级: 优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是 不⼀样的。 ### 结合性: 如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符 是左结合,还是右结合,决定执行顺序。⼤部分运算符是左结合(从左到右执行),少数运算符是右 结合(从右到左执⾏),比如赋值运算符( = ) 运算符的优先级顺序很多,下⾯是部分运算符的优先级顺序(按照优先级从⾼到低排列),建议⼤概 记住这些操作符的优先级就⾏,其他操作符在使用的时候查看下⾯表格就可以了。 图片 完