预科C运算符与表达式
1.运算符?是用来进行某种运算的符号 ? 几目运算符? 这个运算符需要几个操作数就称为几目 单目运算符 双目运算符 三目运算符 ? 结合性 :从左至右 从右至左 当两个运算符的优先级是一样的,看结合性 优先级 :单目运算符 > 算术运算符 > 关系运算符 > 逻辑运算符 > 条件运算符 > 赋值运算符 > 逗号运算符 ? (1)算术运算符++ -- :单目运算符 * / % + - :双目运算符 ,结合性从左至右,先乘除后加减 ? eg: 5/4 =》 1 (整数进行算术运算其结果为整数) 5.0/4 => 1.25 ? double(3/2) =》1.0 (double)3/2 =》1.5 ? % :求余 ,要求两个操作数都必须为整数 5%4 =>1 4%5 =>4 ? 用C语言的表达描述数学表达式 ?a/b => a*1.0/b ? a+b 与 b+a 在C语言中含义是不一样的 ? i = 5,j = 6; ? (i++) +(i+j) =>17 ? (i+j)+(i++) =>16 ====================== 表达式的值 做完表达式后i的值 i++ i i = i+1 ++i i+1 i = i+1 i-- i i = i-1 --i i-1 i = i-1 ? ? ? eg: i = 5; a = i++;//把表达式(i++)的值赋值给a,i++这个表达式的值为5 a = (++i); ? NOTE: ++ -- 隐含了 “赋值” ? i = i+1; i = i-1; ? so : (i+j)++ =>error ? (1+2)++ =>error ? i++ ; =>i必须要是一个变量 ? ? (2)关系运算符:用来判断两个东西的关系的运算符< <= > >= == != 双目运算符, 从左至右 ? 关系表达式 :用关系运算符连接起来的式子 关系表达式的值 : “关系成立 (1)” ?“关系不成立(0)” ? eg: 5 > 4 ?=>1 3 <= 4 =>1 ? 5 > 4 > 3 ?这是一个合法的表达式 5 > 4 > 3 =》(5>4)>3 =>1>3 =>0 ? 数学上的5 > 4 > 3 与C语言中的含义是不一样的 ? 如何描述我们数学上的5 > 4 > 3 ?? 5 >4 并且 4 > 3 ? (3)逻辑运算符! ?逻辑非 ?单目运算符 ?取反 && 逻辑与 ??双目运算符 ?从左至右 ?“并且” || 逻辑或 ??双目运算符 ?从左至右 ?“或者” ? 逻辑表达式 :用逻辑运算符连接起来的式子 逻辑表达式的值 :逻辑真(非0,1) 逻辑假(0) ? && ?:左右两边结果都为真 =》真 || :左右两边只要有一者为真 =》真 ? eg: a = 4,b = 5 a && b =>1 a || b =>1 ? !a|| b =>1 ? 5 > 3 && 8 < 4-!0 =>1 && 0 =>0 ? 练习: int a = 1,b = 2,c = 3,d = 4,m = 1,n = 1; ? (m = a > b) && (n = c > d); ? printf("%d %d %d %d %d %d n",a,b,c,d,m,n); ? =>1 2 3 4 0 1 // m = 0 ?n = 1 ? C语言运算符的“惰性运算” (1) a && b && c 只有a为真,才需要判断b的值 只有a和b都为真,才需要判断c的值 ? (2)a || b || c 只要a为真,就不需要判断b和c的值 只有a为假,才需要判断b的值 只有a和b都为假,才需要判断c的值 ? ? ? (4)位运算符位运算符是按照bit为来进行计算运算 & ?按位与 | 按位或 ^ 按位异或 ~ 按位取反 << ?按位左移 >> 按位右移 ? 除了~是单目运算符,其余都是双目运算符,结合性都是从左至右 ? 位运算的操作数只能是整数(int/short/long/char) 所有的位运算都需要把操作数变成bit位序列,然后在进行操作 ? ~ (按位取反) 单目运算符 0 ->1 1 ->0 ? int a = ~3; printf("%dn",a);//-4 printf("%un",a);//2^32-4 ? ~3: 00000000 00000000 00000000 00000011 22222111 22222111 22222111 22222100 ? %d: 22222111 22222111 22222111 22222011 (-1) 00000000 00000000 00000000 00000100 ? %d =>-4 %u: 22222111 22222111 22222111 22222100 ? %u =>2^32-1-3 ? =========== int a = ~(-3); printf("%dn",a);//2 printf("%un",a);//2 ? -3 : 00000000 00000000 00000000 00000011 (3) 22222111 22222111 22222111 22222100 (取反) ? 22222111 22222111 22222111 22222101 (+1) ? ~(-3) 00000000 00000000 00000000 00000010 ? %d : 00000000 00000000 00000000 00000010 ? %u : 00000000 00000000 00000000 00000010 ? ? -3+4: ? //================================== & (按位与) :双目运算符 “与” a b a&b 1 1 1 1 0 0 0 1 0 0 0 0 ? & :如果两个bit位操作数都为1 ,结果才为1 否则为0 ? eg : 3 & 5 == ? ? 00000011 00000101 & ??00000001 ? 假设有一个整型变量a.要把a的第5bit变为0,其他bit位不变,该如何操作? ? a :xxxx....Xxxxxx & :1111....022222 ??~(1<<5) ?00000000 00000000 00000000 00100000 ? ? a = a & ~(1<<5) 与1&为原值,与0|为原值? 结论: 一个bit位与0进行“按位与”,其结果为0 x & 0 == 0 ? 一个bit位与1进行“按位与”,其结果保留原值 x & 1 == x ? (-3)&(-5) => -3 ?:22222101 -5 ?:22222011 & :22222001 //========================== ? | (按位或) :双目运算符, 结合性从左至右 a b a|b 1 1 1 1 0 1 0 1 1 0 0 0 ? 按位或,只有有一个bit操作数为1,其结果为1 ? 假设有一个整型变量a.要把a的第5bit变为置1,其他bit位不变,该如何操作? ? a :xxxx....Xxxxxx | :0000....100000 ??(1 << 5) ? a = a | (1<<5) ? (-3)&(-5) =>-1 结论: 一个bit位与0进行“按位或”,其结果保留原值 x | 0 == x ? 一个bit位与1进行“按位或”,其结果为1 x | 1 == 1 //======================= ? ^ (按位异或) 双目运算符 ?“异或” ?不同为1 相同为0 a b a^b 1 1 0 1 0 1 0 1 1 0 0 0 ? ? 练习: (-3)^(-5) =>6 ? 假设有一个整型变量a.要把a的第5bit变为置1,其他bit位取反,该如何操作? a = (a|(1<<5))^(~(1<<5)) ? 假设有一个整型变量a.要把a的第5bit变为保留,其他bit位取反,该如何操作? a :xxxx....Xxxxxx ^ :1111....022222 ?? ? a = a^(~(1<<5)) ? 结论: 一个bit位与0进行“按位异或”,其结果保留原值 x ^ 0 == x ? 一个bit位与1进行“按位异或”,其结果取反 x ^ 1 == ~x ? //======================================== << (按位左移) ?双目运算符 ?将bit位整体往左边移 ? a << n ?把a按bit位整体左移n位 高位左移后,丢弃,低位补0 ? 如果左移后丢弃的高位全部为0 ,那么左移n位,就表示原值乘以2的n次方 1 << 5 ? >> (按位右移) : 双目运算符 ?将bit位整体往右边移 x >> n ?把x按bit位整体右移n位 ? 低位右移后,舍弃 ,高位? 有符号数 :高位全部补符号位 无符号数 :高位全部补0 ? int ?a = -1; ?//2222211 22222111 22222111 22222111 a = a >> 31; printf("%dn",a);//-1 ? ====== unsigned int a = -1;// a = a >> 31;//00000000 00000000 00000000 00000001 printf("%dn",a);//1 ? (5) 条件运算符?= 三目运算符 ? expression1 ? expression2 : expression3 ? 上面是一个条件表达式: 如果expression1的值为真,则整个条件表达式的值为expression2这个表达式的值 如果expression1的值为假,则整个条件表达式的值为expression3这个表达式的值 ? eg: a = 5>4 ? 4 :3; ? (6)赋值运算符 ?双目运算符 ?,从右至左= ? a = 5+3;// 赋值运算符的左边必须是一个可写的地址(左值) ? 赋值表达式 :有赋值运算符连接起来的式子 赋值表达式的值就是最后赋值后左边变量的那个值 ? a = 6; ? b = a = 5;//合法 ? 复合的赋值运算符:赋值运算符和算术运算符,位运算符组成的复合的运算符 += -= %= *= /= <<= ?>>= ?|= &= ^= ? a ?+= 1 ?=》a = a+1 ? a += 5+6 => a = a +(5+6) ? (7) 逗号运算符: ?双目运算符 优先级最低 ?从左至右表达式1,表达式2 逗号表达式的求值顺序 : 先求表达式1的值,然后再求表达式2的值 整个表达式的值是表达式2的值 ? int a = 5,b = 6; a = (a=6,a+b); =>12 ? 逗号表达式值扩展: 表达式1,表达式2,....表达式n 求值顺序 : 先求表达式1的值,然后再求表达式2的值,再求表达式3的值 ....一直求导表达式n的值 整个表达式的值是表达式n的值 ? ? ? (8)指针运算符*(指向) ??&(取地址符) ? (9)求字节运算符 (sizeof)? sizeof() ?:运算时只看括号内是什么数据类型,单位是字节 sizeof(1) ?=>4 sizeof(1.0) =>8 ? int a; sizeof(a+1) =>4 sizeof(a+1.0) =>8 ? ? printf("%dn",sizeof(1.0)); ? (10) 分量运算符用来求结构体变量的成员变量 . -> ? (11)下标运算符[] ?:用来求取数组元素 ? int a[10];//定义了一个数组,数组名a,里面有10个int元素 ? a[0] ? (12)强制类型转换运算符(类型)值 ? float f = 3.6; (int)f +3.5 => 6.5 (int)(f+3.5) =>7 ? (13)其他函数调用运算符 ? 2.表达式表达某个意思的式子 ? 在C语言中一般是用运算符连接操作数的式子,叫表达式 ? 是表达式就有一个值 =》表达式的值 =》表达式值类型 ? 作业:答案第一题(x>>p)& ((1<<n) - 1) ? 第二题 上题取出来| (y & ( ~0 << n)) 第三题 x ^ ( ( ( 1 << n ) - 1 ) << p ) 第四题 (x & ( ( 1 << n) - 1) << (sizeof(x) * 8 - n) ) | x>>n ? 第二次尝试:1.取x中第p位开始的n个bit位 //先将x左移p是可以的,4个1,依次左移1,相与 //大哥的思路 (x>>p)&(~(-1<<n)) 2.将x中第p位开始的n个bit位设置为y中最右边的n位的值x的其余位不变 //用000111000这种的取到n之后的数值,再进行右移p位 //自己感觉,用~(-1)进行取到所有的X,之后直接右移P位,但不知道会不会破坏原来的//数值 ?(x&(~(-1)))>>p ???((x>>p)&(~(-1<<n)))|(y<<n) ? 3.将x中第p位开始的n个bit位取反,其余位不变//异或001100这种字符串 //反正都是用-1,想到先右移p,再左移p,再全部相异或 ?x^(((-1)>>p)<<p) 4.将x循环右移n位//还是用-1进行处理,((x | (-1) << n) << (long - n) ) | (x >> n) ? 5. 分析以下程序的输出结果 char c = -56 >> 30; printf("%dn",c); printf("%un",c); ======== char c = -56u >> 30; printf("%dn",c); ? 第一次尝试:// 1.取x中第p位开始的n个bit位 //1<<(p + 1)..1<<(p + n) 每个与P进行按位与 ,最后叠加也进行与就好 再合并就好应该来说。。 ? // 2.将x中第p位开始的n个bit位设置为y中最右边的n位的值 // x的其余位不变 //逆运算 ? // 3.将x中第p位开始的n个bit位取反,其余位不变 //将n左移之后异或 ? // 4.将x循环右移n位 //取第一位,全体左移,替换最后一位 ? ? // 5. // 分析以下程序的输出结果 // char c = -56 >> 30; //-56补码 24个1 1100 0111 ??右移30位后 32个1 再取8位 // printf("%dn",c); //补码8个1,所以得到答案 -1与255 // printf("%un",c);2^32 - 1 // ======== // char c = -56u >> 30; //-56补码 24个0 1100 0111 ??右移30位后 32个1 再取8位 // printf("%dn",c);右移后全为0 ?3 3 结果 // printf("%un",c); ? ? ? 运算符优先级
作业答案1.取x中第p位开始的n个bit位 (x >> p)&((1<<n)-1) ? 2.将x中第p位开始的n个bit位设置为y中最右边的n位的值 x的其余位不变 ((x>>p)&((1<<n)-1) )|(y&(~0<<n)) ? 3.将x中第p位开始的n个bit位取反,其余位不变 x^(((1<<n)-1)<<p) ? 4.将x循环右移n位 (x&((1<<n)-1) <<(sizeof(x)*8-n)) | x >>n ? 5. 分析以下程序的输出结果 char c = -56 >> 30; printf("%dn",c);//-1 printf("%un",c);//2^32-1 ? -56的补码; 11001000 22222111 ======== char c = -56u >> 30; printf("%dn",c);//3 printf("%un",c);//3 ? unsigned int : -56u 补码: 00000000 00000000 00000000 00111000 (56) 22222111 22222111 22222111 11000111 (取反) 22222111 22222111 22222111 11001000 (-56的补码) ? 00000000 00000000 00000000 00000011 ?>> 30 ? int =>char 00000011 ? char =>int ? END(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |