当前位置 : 主页 > 编程语言 > c语言 >

C语言操作符全家桶

来源:互联网 收集:自由互联 发布时间:2023-09-06
各式各样的操作符详解 现在打下的所有基础,都在为你未来的能力上限做准备 1.算术操作符 2.原码,反码,补码 3.移位操作符(移(2进制)位操作符) 4.位操作符 (针对整数且为2进制

各式各样的操作符详解

现在打下的所有基础,都在为你未来的能力上限做准备


C语言操作符全家桶_整型

1.算术操作符

2.原码,反码,补码

3.移位操作符(移(2进制)位操作符)

4.位操作符 (针对整数且为2进制位,均为补码计算)

5.赋值操作符

6.单目操作符

7.关系操作符

8.逻辑操作符

9.条件操作符

10.逗号表达式

11.下标引用,一个数组名,一个索引值

12.表达式求值---重点

1.算术操作符 对于除法操作符,两边的操作数都是整数,执行的是整数除,若想得到小数,除号两端至少有一个为浮点数/取模(取余),计算的是整除之后的余数 取模操作符(%),计算的是整除之后的余数,只能用整型类型的操作

2.原码,反码,补码 例如: a = 1000000000000000000000000000001010-原码 00000000000000000000000000001010-反码 00000000000000000000000000001010-补码正数的原码反码补码相同如b= -10 ,下面写出b的原码,反码,补码10000000000000000000000000001010-原码--按照一个数的正负,直接写出它的二进制表示形式 11111111111111111111111111110101-反码--原码的符号位不变,其它位取反(第一位是符号位) 11111111111111111111111111110110-补码-反码加1补码变原码:先符号位不变,其它位按位取反,再+1下图可以清晰总结原反补:

3.移位操作符(移(2进制)位操作符) 左移操作符:左边丢掉,右边补0计算机在存储中存储的永远都是补码,所以在移位时,移动的是补码。符号位(0是正数,1是负数) 整型占4个字节(32bit) 内存中存储的其实是:补码的二进制 所以在参与移位时,移动的都是补码--所以移位操作符的用法可以理解了例如:a =10; a << 1;//2进制移位 先写出10的补码: 00000000000000000000000000001010 00000000000000000000000000010100 (左移一位后的结果)但是这个过程a不变,变的是a向左移动的表达式这个结果变,a本身不变 比如: a=10;b=a+2;b=12,但是a本身不变,还是10 若想让a变化,可以写成 a>>=1;(a = a>>1)又比如:int a = -10; int b = a << 1;先写出a的原反补:10000000000000000000000000001010--原码 11111111111111111111111111110101--反码 11111111111111111111111111110110--补码左移操作符:(补码)左边丢掉,右边补0 11111111111111111111111111101100--补码左移后的结果,是b的补码 10000000000000000000000000010011--计算过程 10000000000000000000000000010100--b的原码 由于打印(肉眼可见的)出来的都是原码,但是计算机存储的是补码,所以计算机要转换成原码再打印出来 总结,左移1位有×2的效果 右移操作符(看完左移操作符,就懂右移操作符了) 1)算术右移(平常见到)--也是计算机计算的方法 算数右移-右边丢弃,左边补原来的符号位如 a =-1 100000000000000000000000000000001--a的原码 111111111111111111111111111111110--a的反码 111111111111111111111111111111111--a的补码b= a>>1 11111111111111111111111111111111--a右移的结果,也就是b,但是a本身不变2)逻辑右移(不怎么用) 逻辑右移-右边丢弃,左边直接补0

4.位操作符 (针对整数且为2进制位,均为补码计算) & | ^ 按位与,按位或,按位异或 & -- 对应的2进制位有0则为0,两个同时为1,才为1按位或 对应的二进制位,有1则为1,两个同时为0才为0按(二进制)位异或 对应的2进制位,相同为0,相异为1下面有一道面试题:面试题:不能创建临时变量(第三个变量),实现两个正数的交换使用异或操作符求解先清楚两条计算规则: 1)a^a = 0 2)0^a = aa = a^b; //此时a相当于 a^b b = a^b; //等价于 a^b^b == a^0 ==a ,所以b =a a = a^b; //等价于a^b^a == a^a^b == 0^b ==b 即a=b 即可完成两个正数的交换结论 :异或支持交换律异或虽好,不要贪杯 1.可读性差 2.效率不如使用临时变量的方法 3.只能针对整数的交换

5.赋值操作符 赋值操作符是一个很棒的操作符,它可以让你得到一个你之前不满意的值, 也就是你可以重新赋值好处:可以连续赋值a= x = y+1 ; 也是从右到左开始赋值 但这种方法不易于理解,不易于调试 等同于: x = y+1; a = x;

6.单目操作符 1.+= 2. -=3. *= 4. /= 5. %= 6. >>= 7. <<= 易于理解

7.关系操作符 操作符有两个操作数,叫双目操作符,比如 1+3,+号为双目操作符,同理,只有一个操作数,叫单目操作符!:逻辑反操作 -:负值 +:正值 &:取地址 &地址 > >= < <= != ==一个等号叫赋值,两个等号叫判断

判断闰年的规则就很好地说明这两个操作符 1,能被4整除,并且不能被100整除 2.能被400整除int main() { int y = 2048; if ((y % 4 == 0 && y % 100 != 0) || (y %400 == 0)) { printf("yes\n"); } }sizeof:操作数的类型长度(以字节为单位) sizeof - 是关键字,也是操作符 功能是计算大小~:对一个数的二进制按位取反(包括符号位) ~ 按位取反(二进制数)(只能针对整数) a = 0; 11111111111111111111111111111111 -- ~a的补码 打印出来要变成原码,但是在计算机存储中仍然是补码 10000000000000000000000000000001 --~a的原码 打印出来就是 -1--:前置,后置-- ++:前置,后置++ *:间接访问操作符(解引用操作符) (类型):强制类型转化例如int main() { int a = (int)3.14; //强制将double类型转换成int类型,相当于只是拿了整数部分 printf("%d\n", a); return 0; }又如:int main() { srand((unsigned int)time(NULL)); //(unsigned int)--强制类型转换成无符号类型 //NULL空指针 } 强制类型转换是在万不得已的情况下才用的(强扭的瓜不甜)布尔类型:补充: 布尔类型: C99及以后引入的 布尔类型就是用来表示真假的类型 -- _Bool 只有true 和false 的赋值总体来说,逻辑操作符如下:

9.条件操作符 exp1 ? exp2 : exp3 -- 三目操作符 表达式1如果为真,表达式2计算,表达式2计算的就是整个表达式的结果 表达式1如果为假,表达式3计算,表达式3计算的就是整个表达式的结果 求两个数的较大值int main() { int a = 10; int b = 20; int c = a > b ? a:b;//(exp1 ? exp2 : exp3) printf("%d\n", c); 三目操作符用于实现逻辑比较简单的操作 return 0; }

10.逗号表达式 10.逗号表达式 exp1 ,exp2,exp3,exp4,......expN 从左向右依次计算,整个表达式的结果是最后一个表达式的结果int main() { int a = 1; int b = 2; int c = (a > b, a = b + 10, a, b = a + 1); 最后决定c的是最后一个式子,从左到右表达式一次执行,执行的结果 如果改变最后一个表达式,那么也会影响c的值 printf("%d\n", c); }

11.下标引用--一个数组名,一个索引值 一段代码搞定:理解透彻int main() { int arr[10] = { 1,2,3,4,5 }; printf("%d\n", arr[4]); //[] -- 下标引用操作符,操作数是 arr,4 两者缺一不可 return 0;

12.表达式求值---重点 表达式求值的顺序一部分是由操作符的优先级和结合性决定的 同样,有些表达式的操作数在求值的过程中可能要转换为其他类型12.1隐式类型转换整型提升--针对类型小于整型的:char short char short int long... 1 2 4 8 整型提升是按照变量的数据类型的符号位来提升!!! 由于char类型是一个字节,int类型是4个字节,所以用char类型无法完整表示int类型 故会自动发生截断,只读取最后一个字节的二进制为,即8个二进制位 现在讨论char类型的取值范围 最高位是符号位,符号位为0,表示整数,最大为011111111--127 符号位为1,表示负数,最小为 char类型中 0,1,2...127,-128,-127,-126,...0,1,2,...127,-128...是一个圆环 char类型中,127+1==-128 , -128+1=-127, -127+1= -126 所以打印出来是-126//short -32768~32767 char--有符号的char的取值范围是 -128~127 无符号位的char的取值范围是0~255(因为第一位不再是符号位) char -1字节-8比特位 有2^8次方种可能性//以下例子说明整型提升的存在 int main() { char c = 1; printf("%u\n",sizeof(c));//1-char类型是1个字节 //由于+c是一个表达式,-c也是一个表达式子,所以会发生整型提升,提升后变成4个字节 printf("%u\n", sizeof(+c));//4-整型提升后,整型类型是4个字节 printf("%u\n", sizeof(-c));//4-整型提升后,整型类型是4个字节 // %u打印无符号十进制 } //通俗的讲,整型提升是对字节不足的,进行字节补充,截断是字节超出范围的,把超出的高位截断 //12.2算数转换--大于int的都属于算数转换(隐式转换,也就是偷偷发生) //如果某个操作符的各个操作数属于不同类型, //那么除非其中一个操作数的转换为另一个操作数的类型, //否则操作就无法进行。//long double //double //float //unsigned long int //long int //unsigned int //int //以上转换级别都是从下往上递增,即如果发生算数转换,一定是从下往上转换 ////12.3操作符的属性 //1.操作符的优先级 //2.操作符的结合性 //3.是否控制求值顺序 //首先确定优先级,相邻操作按优先级高低计算 //优先级相同的情况下,考虑结合性//1.优先级:相邻操作符才讨论优先级 //int main() //{ // int a = 1; // int b = 2; // int c = 4; // int d = a * 4 + b / 3 + c; // // //相邻才讨论优先级,无法确定 * 和 / 谁先算 // //相邻操作符优先级相同的情况下,考虑2.结合性 // return 0; //}补充: 算术转换: long double double float unsigned long int long int unsigned int int 当连个不同类型的值比较或相加减时,默认从低到高转换,即向上转换关注我,给你更多你意想不到的惊喜

上一篇:格式化字符串漏洞-手动触发
下一篇:没有了
网友评论