Linux系统下的C语言学习笔记(四)
1.C语言常用操作符
这个分类有许多种,这个是按其中一种分的类
1.1 算数操作符
假设x = 7;y = 5
符号 名称 例子 结果 结合性 优先级
- 取反 -x -7 从右向左 最高
* 乘法运算符 x * y 35 从左向右 较低
/ 除法运算符 x / y 1 同上
% 求余运算符 x % y 2 同上
+ 加法运算符 x + y 12 同上 最低
- 减法运算符 x - y 2 同上
注:
如果参与除法计算的两个数字都是整数则计算结果只保留整数部分,“%”只能用于整型。
1.2赋值操作符
= 赋值 a = b
+= 加法运算 a += b ==> a = a + b
-= 减法运算 a -= b ==> a = a - b
*= 乘法运算 a *= b ==> a = a * b
/= 除法运算 a /= b ==> a = a / b
%= 求余运算 a %= b ==> a = a % b
赋值语句本身也可以作为数字使用,这个数字就是赋值以后存储区里的数字。
可以在一个表达式里多次使用赋值操作符,这个时候优先计算右边的赋值操作符
val = ch = 100;//val和ch的值都是100
1.3自增自减运算符
1.3.1 自增操作符可以把存储区的内容加一,自减操作符可以把存储区的内容减一
它们各有两种使用方法:
前操作(操作符写在存储区的前面)
++a;
--a;
后操作(操作符写在存储区的后面)
a++;
a--;
1.3.2 后操作表达式作为数字使用的时候是修改前的数字,前操作表达式作为数字使用的时候是修改后的数字
//后操作符
int val1 = 0,val = 10;
val1 = val++;
printf("%d,%d\n",val1,val);
其结果是:val1 = 10;val = 11;
//前操作符
int val1 = 0,val = 10;
val1 = ++val;
printf("%d,%d\n",val1,val);
其结果是:val1 = 11;val = 11;
1.4关系操作符
! 取非 结果是布尔值,为0则是假,为1则是真
== 等于
>= 大于等于
<= 小于等于
< 小于
> 大于
!= 不等于
上述符号常用于条件判断
这里说一种很坑人的写法(做题的时候常遇到):
printf("%d\n",3<7<5);
//从左向右算,3<7为真,结果是1,1<5结果为真,所以结果是1,但一般程序中没有这样写的。
1.5逻辑运算符
&& 与表达式 两边结果都为真时结果为真
|| 或表达式 两边结果有一边为真时,结果为真
与(&&)和或(||)都具有短路特征:如果前面表达式的结果可以决定合并后表达式的结果就忽略后面的表达式。(可以说与中有假则为假,或中有真则为真)
与(&&)和或(||)都具有短路特征
,如果前面表达式的结果可以决定合并后表达式的结果就忽略后面的表达式。
1 /*
2 * 逻辑操作符演示
3 * */
4 #include <stdio.h>
5 int main() {
6 int val = 0;
7 printf("!8是%d\n", !8);
8 printf("3 < 7 < 5是%d\n", 3 < 7 < 5);
9 1 || ++val;
10 printf("val是%d\n", val);
11 0 && ++val;
12 printf("val是%d\n", val);
13 return 0;
14 }
1.6位操作符
位操作符用来操作二进制数位的内容。
单目位操作符
~
是一个单目位操作符这个操作符可以根据一个数字计算出另外一个数字,这两个数字所有二进制数位的内容都不一样,这个操作叫按位求反。
char 0x93 1001 0011
char ~0x93(0x6c) 0110 1100
双目位操作符
按位与(&)
按位或(|)
按位异或(^)
上述它们都是把两个数字对应二进制数位的内容互相进行计算。
左移位<<
右移位>>
左边的数字将要进行移位操作,右边的数字是移动的位数。
3 << 2 对3进行向左移动2位的操作
按位与(&)可以把对应数位的内容做与计算,只要一个数位内容是0则与计算以后结果就是0。
3 0000 0011
& 5 0000 0101
0000 0001
任何数位内容和0做按位与结果一定是0,任何数位内容和1做按位与结果保持不变
可以利用按位与从一个数字里单独获得某些数位的内容
0010 1011 & 0000 0001 结果是1(利用按位与用来判断一个数字是否是奇数)
可以利用按位与把一个数字的某些数位内容设置成0
0110 1011 & 1101 1111 结果是0100 1011
按位或(|)可以把对应数位的内容做或计算,只要一个数位的内容是1则或计算以后结果就是1。
3 0000 0011
| 5 0000 0101
0000 0111
任何数位内容和0做按位或保持不变,任何数位内容和1做按位或结果是1
可以利用按位或把某些数位内容设置成1
0110 1011 | 0000 0100 结果是0110 1111
按位异或(^)可以把对应数位的内容做异或计算如果两个数位内容一样则异或以后结果是0,否则结果是1
3 0000 0011
^ 5 0000 0101
0000 0110
任何数位内容和0做按位异或结果保持不变,任何数位内容和1做按位异或结果变成相反数。
可以利用按位异或把某些数位内容变成相反数
0110 1001 ^ 0000 1111 结果是 0110 0110
移位操作可以把一个数字的所有二进制数位内容统一向左或向右移动n个位置
********
00000011
00000011 向左移动2步
00001100 多余的数位内容被丢掉空的数位里填上新数字
向左移位后右边空出来的数位里固定填充0,无符号类型数字右移时左边空出来的数位里填充0(无符号类型)
1000 0101 >> 2 0010 0001
有符号类型数字右移时左边空出来的数位里填充符号位的内容(有符号类型)
1000 0101 >> 2 1110 0001
向左移动n位通常相当于乘以2的n次方,向右移动n位通常相当于除以2的n次方。
位操作符不会修改存储区内容
&
也可以作为单目操作符使用,它可以用来计算一个存储区的地址。(类似从电话号码本里查找某个人的电话号码)。可以用%p做占位符
显示地址数据,我的计算机里所有地址数据都是由32个二进制数位构成的。
*
也可以做单目操作符使用。它可以根据地址找到一个存储区。(类似根据电话号码拨打电话)
1 /*
2 * 位操作符演示
3 * */
4 #include <stdio.h>
5 int main() {
6 char ch = ~0x93;
7 int val = ch;
8 printf("val是0x%x\n", val);
9 printf("3 & 5是%d\n", 3 & 5);
10 printf("3 | 5是%d\n", 3 | 5);
11 printf("3 ^ 5是%d\n", 3 ^ 5);
12 printf("3 << 2是%d\n", 3 << 2);
13 return 0;
14 }
1 /*
2 * 操作符练习(交换val与val1的值,注释的部分也是两种方法,可以结合以前所讲的试试)
3 * */
4 #include <stdio.h>
5 int main() {
6 int val = 3, val1 = 7, tmp = 0;
7 /*tmp = val;
8 val = val1;
9 val1 = tmp;*/
10 /*val = val + val1;
11 val1 = val - val1;
12 val = val - val1;*/
13 val ^= val1;
14 val1 ^= val;
15 val ^= val1;
16 printf("val是%d,val1是%d\n", val, val1);
17 return 0;
18 }
19
1 /*
2 * 地址相关操作符演示
3 * */
4 #include <stdio.h>
5 int main() {
6 int val = 0;
7 printf("&val是%p\n", &val);
8 *(&val) = 10;
9 printf("val是%d\n", val);
10 return 0;
11 }
1.7三目运算符
三目操作符可以从两种计算规则里选择一个(类似于工具箱,可以从多个工具里选择)。
三目操作符格式如下
布尔值 ? 表达式一 : 表达式二
布尔值为真就用表达式一进行计算,布尔值为假就用表达式二进行计算
计算绝对值的表格
- 非负数 * 本身 *
- 负数 * 相反数*
如果表达式里不同数字的类型不同就必须首先转换成同一个类型然后再进行计算,这个转换过程叫隐式类型转换。隐式类型转换过程中必须把占地小的类型转换成占地大的类型
如果既有整数类型数字也有单精度浮点类型数字,隐式类型转换时就把整数类型转换成单精度浮点类型。如果既有无符号类型数字也有有符号类型数字,隐式类型转换的时候就把有符号类型转换成无符号类型。
1 /*
2 * 三目表达式演示
3 * */
4 #include <stdio.h>
5 int main() {
6 int val = 0, result = 0;
7 printf("请输入一个数字:");
8 scanf("%d", &val);
9 result = val >= 0 ? val : 0 - val;
10 //val >= 0 ? result = val : result = 0 - val; 错
误
11 printf("绝对值是%d\n", result);
12 return 0;
13 }
14
可以在程序里临时给数字指定一个类型这叫做强制类型转换
强制类型转换格式如下
(char)300 // 把300当做字符类型数字使用
强制类型转换有可能导致数据内容丢失,类型转换不会修改存储区内容
printf("%d\n",(int)7.4f);
1 /*
2 * 类型转换演示
3 * */
4 #include <stdio.h>
5 int main() {
6 int val = 0;
7 printf("sizeof(1 ? 1 : 0.9)是%d\n", sizeof(1 ? 1 : 0 .9));
8 printf("-7 + 3 > 0是%d\n", -7 + 3 > 0);
9 printf("-7 + 3u > 0是%d\n", -7 + 3u > 0);
10 val = (char)300;
11 printf("val是%d\n", val);
12 return 0;
13 }
2练习题
用位操作的方法计算一个大于0小于127的数:
1 /*
2 * 操作符练习
3 * */
4 #include <stdio.h>
5 int main() {
6 int val = 0;
7 unsigned char ch = 0x80;
8 printf("请输入一个数字:");
9 scanf("%d", &val);
10 printf("转换结果是");
11 printf("%d", (val & ch) != 0);
12 ch >>= 1; //得到下一个掩码并记录到ch变量里
13 printf("%d", (val & ch) != 0);
14 ch >>= 1; //得到下一个掩码并记录到ch变量里
15 printf("%d", (val & ch) != 0);
16 ch >>= 1; //得到下一个掩码并记录到ch变量里
17 printf("%d ", (val & ch) != 0);
18 ch >>= 1; //得到下一个掩码并记录到ch变量里
19 printf("%d", (val & ch) != 0);