C语言核心技术-运算符
3.1 运算符概述
计算机最核心的任务就是完成数据的计算,C语言提供了丰富(多达34种)的运算符来实现不同数据类型的各种运算,之前在求数据类型的大小时已经使用过的sizeof()就是一种运算符,最常用的运算符有算术,关系,逻辑以及比较和位运算符。
在介绍具体的运算符之前先要明确关于运算符的一些概念:操作数、运算符、表达式、优先级和结合性。
运算符:表示数据参与的运算类型,例如这里的"+"表示"+"左右两边的操作数执行加法运算。
操作数就是参与运算的数据,例如这里的5和8就是操作数
int result = 5 + 8;
优先级:计算的先后顺序,以算术运算符为例,其默认的顺序是先乘除,后加减。但是可以通过()来改变了运算的优先级
int result = (45 + 5) / 5 * 10;
结合性:表达式计算的方向,从右向左或者从左向右
例如赋值运算的结合性就是从右向左,
int left, middle, right;
left = middle = right = 10;
算术运算符的结合性是从左向右,结合性决定了优先级相等的情况下的计算顺序
int result = (45 + 5) / 5 * 10;
运算符不能相邻,此处编译会发生错误
1 + *3;
但是加(+)减(-)号例外 因为加减号作用于整数的时候,用来区分正负数
1 + +3;
1 - -2;
运算符和操作数组成了表达式,()可以嵌套使用
int result = ((4 * 5) + (20 - 10) - 12 * 3) + 12 - 2;
3.2 算术运算符
算术运算符就是数学意义上的加减乘除(+ - * /)以及取模运算(即求余数)。
其优先级是按照先乘除,后加减的计算顺序。结合性是从左到右的计算方向。
C语言规定:
两个整数相除结果是整数,小数部分被舍去。
两个整数执行求余运算时,运算结果的符号和被除数相同。
如果除法任意一边有浮点数,那么运算的结果一定是浮点数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
算术运算符
@author liuguanglei ittimelinedotnet@gmail.com
@wechat 18601767221
@website ittimeline.net
@version 2020/01/05
*/
int main(int argc, char* argv[])
{
int left = 20;
int right = 10;
//整数的加减乘除取模运算
printf("%d + %d = %d
",left,right,(left+right));
printf("%d - %d = %d
",left,right,(left-right));
printf("%d * %d = %d
",left,right,(left*right));
printf("%d / %d = %d
",left,right,(left/right));
//这里为了在控制台显示%,因此使用了两个%
printf("%d %% %d = %d
",left,right,(left%right));
//C语言规定:整数相除的结果是整数,小数部分会被舍去
printf("5 / 2 =%d
",(5/2));
// %即取模运算只能被整数运算,
//printf("7.0 %%2 = %d
",(7.0%2);
//运算结果的符号与被除数相同
printf("-17 %% 3 = %d
",(-17%3));
// 如果除号任何一边有浮点数参与运算,那么运算结果一定是浮点数
printf("4.0 * 5 =%.1lf
",(4.0*5));
//先运算出整数再自动类型转换为实数
float fl = 13 / 4;
printf("13 /4 = %f
",fl);
//整数和浮点数运算的结果是浮点数 13/4.0=3.25
fl = 13 / 4.0;
printf("13 /4.0 = %f
",fl);
system("pause");
return 0;
}
当除号两边都是整数,叫做整除,运算结果只保留整数部分。当除号任何一边有浮点数时,结果一定时浮点数,如果只想要保留整数部分,可以通过强制类型转换实现。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
算术运算之除法运算
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/12
*/
int main(int argc, char* argv[])
{
// 9/3 =3 但是这里的赋值运算会发生自动类型转换,将3转换为浮点型及3.0
// 但是printf输出浮点型,默认是保存小数点后六位
float flt = 9 / 3;
printf("flt = %f
", flt);
//整数和浮点数运算结果一定是浮点数
flt = 12 / 2.5;
printf("lt = %.2f
", flt);
//如果想要获得整数,必须使用强制类型转换实现
printf("5.0 / 2 = %d
", (int)(5.0 / 2));
system("pause");
return 0;
}
只有整数参与取模运算,取模运算的结果和被除数的符号一致,也就意味着如果被除数是正数,那么取模的结果就是正数,反之亦然。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
算术运算之求模运算
求模运算就是两个整数相除,求余数
求模的结果类型和被除数的符号一致
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/12
*/
int main(int argc, char* argv[])
{
//为了控制台输出%,这里需要使用%%
printf("8 %% 3 = %d
",8%3);
//取模的结果类型和被除数的符号一致,因为被除数(-8)是负数,因此取模的结果也是负数
printf("-8 %% 3 = %d
",-8%3);
printf("8 %% -3 = %d
",8%-3);
/*************************求模的案例***********************************/
printf("3%%5 = %d
", 3 %5); //3
printf("3%%-5 = %d
", 3 %-5);//3
printf("-3%%5 = %d
", -3 %5);//-3
printf("-3%%-5 = %d
", -3 %-5);//-3
printf("5%%3 = %d
", 5 % 3); //2
printf("-5%%3 = %d
", -5 % 3);//-2
printf("5%%-3 = %d
", 5 % -3);//2
printf("-5%%-3 = %d
", -5 % -3);//-2
system("pause");
return 0;
}
求模运算的案例:输入一个整数,输出颠倒后的结果。例如输入95,输出59。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
取模运算的案例
将一个两位整数实现颠倒
例如输入95 输出59
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/12
*/
int main(int argc, char* argv[])
{
int number = 0;
printf("请输入一个整数,按回车键结束
");
scanf("%d",&number);
//获取输入整数的个位和十位
int unit = number % 10;
int decade = number / 10;
//计算颠倒之后的结果
int reversal = unit * 10 + decade;
printf("输入整数%d颠倒之后的结果是%d
",number,reversal);
system("pause");
return 0;
}
取模运算案例:输入一个三位数,将三位数颠倒后输出,例如输入123,输出321。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
取模案例
将一个三位数颠倒
例如输入123,输出321
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/12
*/
int main(int argc, char* argv[])
{
int number = 0;
printf("请输入一个三位整数,按回车键结束
");
scanf("%d",&number);
int unit = number % 10 ;
int decade = number / 10 % 10;
int hundred = number / 100;
int reserval = unit * 100 + decade * 10 + hundred;
printf("%d颠倒之后的结果是%d
",number,reserval);
system("pause");
return 0;
}
3.3 赋值运算符
在学习变量赋值时用到的等号(=)实际上就是赋值运算符,它的作用就是用来将一个常量或者表达式赋值给一个变量,其赋值的格式为 数据类型 变量标识符=常量值或者表达式
。
优先级:所有运算符中仅高于逗号运算符,
结合性:当表达式中有多个变量同时赋值时按照从右往左的结合性进行赋值
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
赋值运算符的基本使用
赋值是将常量或者表达式赋值给变量
优先级:仅仅高于逗号运算符
结合性:从右向左
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/12
*/
int main(int argc, char* argv[])
{
//常量赋值给变量
int number = 10;
number = 18;
printf("number = %d
",number);
printf("number = %d
", number = 20); //num=20 赋值表达式整体的值就是num被赋值的变量,即num=20
int left;
int right;
//结合性:从右向左进行赋值
left = right = 88;
printf("left = %d
", left);
printf("right = %d
", right);
system("pause");
return 0;
}
在赋值时,赋值运算符左边被赋值的值叫做左值,就是有内存实体的变量。右值就是能放在赋值号右边,并且能够赋值给其他变量的值,左值可以当作右值赋值给其他变量,但是右值不能当作左值使用。
在赋值时会进行自动类型转换。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
赋值时的左值和右值
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/12
*/
int main(int argc, char* argv[])
{
//左值就是number 左值是有内存实体的变量,并且能被赋值
//右值就是10,也就是能放在赋值号右边给其他变量赋值的值
int number = 10;
//左值能当作右值使用
int newNumber = number;
printf("number = %d
",number);
printf("newNumber = %d
", newNumber);
//赋值时会发生类型转换,这里会将19.2的小数部分舍去,输出结果是19
int value = 19.2;
printf("value = %d
",value);
system("pause");
return 0;
}
在日常开发中,为了简化表达式,赋值运算还可以和算术运算结合使用
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
赋值运算符和算术运算符结合使用
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/12
*/
int main(int argc, char* argv[])
{
int number = 10;
//此处等价于 number=number+10
number += 10;
printf("number = %d
",number);
//此处等价于number=number-5
number -= 5;
printf("number = %d
", number);
//此处等价于number=number*5
number *= 2;
printf("number = %d
", number);
//此处等价于number=number/5
number /= 5;
printf("number = %d
", number);
system("pause");
return 0;
}
3.4 自增自减运算符
自增、自减运算符的作用是将变量的值增加1或者减少1,。自增运算符是++。自减运算符是--。
在使用时需要注意自增、自减运算符只能作用域变量,不能作用在常量或者表达式。
而前置++、--和后置++、--的区别是当自增、自减运算符放置在变量前面时会先自增、自减1,再参与运算,当自增、自减运算符放在变量后面时会先参与运算,再自增、自减1。
自增、自减运算符和算术运算符同时参与运算时,自增、自减运算符优先级高于算术运算符。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
自增自减运算符
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
int age = 26;
//自增运算符作用于变量
age++;
printf("age++ = %d
",age);
age = 26;
//如果单独一行语句 age++ 和++age的作用是一样的,都是将变量增加1
++age;
printf("++age = %d
",age);
int number = 20;
//先输出number的值然后自增1
printf("number++ =%d
"+ number++);
printf("number = %d
", number);
//当自增运算符和算术运算符进行运算时,自增运算符的优先级高于算术运算符
number = 5;
printf("number++ +3 = %d
",(number++ + 3));
//自增运算符只能作用于变量
//5++;
system("pause");
return 0;
}
3.5 三元运算符
三元运算符也被称为条件运算符,其表现形式为表达式1?表达式2:表达式3,其中如果表达式1的条件成立,那么表达式的计算结果就是表达式2,否则计算结果就是表达式3。
三元运算符和if/else的作用是等价的。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
三元运算符之类型转换
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
int num = 20;
float fl = 10.9;
//这里发生了自动类型转换
//因为float表示数据的范围大于int,三元运算符在运算时会自动类型转换,将结果转换为浮点类型,因此结果是20.000000
printf("(fl > num ? fl : num) = %f
", (fl > num ? fl : num));
system("pause");
return 0;
}
使用条三元算符结合关系运算符实现求两个整数的最大值
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
三元运算符之获取两个整数之间的最大值
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
int left = 10;
int right = 20;
//使用条件运算符结合三元运算符实现获取最大值
int max = left > right ? left : right;
printf("max = %d
",max);
system("pause");
return 0;
}
使用三元运算符结合关系运算符求三个整数的最大值
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
三元运算符之获取三个整数之间的最大值
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
//初始化三个整数变量
int left = 0;
int middle = 0;
int right = 0;
//使用printf函数提示用户输入并使用scanf函数接收用户输入的整数
printf("请输入第一个整数,按回车键结束
");
scanf("%d",&left);
printf("请输入第二个整数,按回车键结束
");
scanf("%d", &middle);
printf("请输入第三个整数,按回车键结束
");
scanf("%d", &right);
//首先比较left和right
//然后拿比较的结果和middle比较
int max =(left > right ? left : right) > middle ? (left > right ? left : right) : middle;
printf("你输入的三个整数分别是%d %d %d
",left,middle,right );
printf("三个整数之中最大的值是%d
",max);
system("pause");
return 0;
}
三元运算符优先级仅仅高于赋值运算符,结合性是从左向右
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
三元运算符优先级与结合性
三元运算符优先级仅仅高于赋值运算符
三元运算符的结合性是从左向右
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
int a = 5, b = 6, c = 7, d = 8;
/*
计算流程
首先判断a>b 即5>6 明显是fasle 因此结果为7
7>8 明显是false,因此结果是8
最后将8赋值给result
*/
int result = a > b ? a : c > d ? c : d;
printf("result =%d
", result);
system("pause");
return 0;
}
三元运算符结合关系运算符实现计算四个整数中的最大值
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
三元运算符之获取四个整数之间的最大值
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
int a, b, c, d;
a = 666;
b = 777;
c = 999;
d = 888;
int max = (a > b ? a : b) > (c > d ? c : d) ? (a > b ? a : b) : (c > d ? c : d);
printf("四个整数的最大值是%d
",max);
system("pause");
return 0;
}
3.6 关系运算符
关系运算符用于计算数值之间的关系,其运算的结果是bool类型,如果表达式成立则返回1,否则返回为0。C语言中用1表示true,用0表示false。
日常常用的关系运算符有大于(>)、小于(<)、等于(==)、不等于(!=),大于等于(>=),小于等于(<=)。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
关系运算符
关系运算符的运算结果是bool类型,如果成立结果是1,否则是0
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
bool flag = 88 <99;
//使用整数输出flag的值
printf("88 <99=%d
",flag);
flag = 88 > 99;
printf("88 >99=%d
", flag);
system("pause");
return 0;
}
而关系运算符的结合性是从左向右依次运算
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
关系运算符
关系运算符的结合性:从左向右
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
//5>4 结果是1
// 1>3 结果是0
//因此计算结果是0
printf("5>4>3 = %d
",(5>4>3));
system("pause");
return 0;
}
在使用关系运算符进行相等性判断时,如果数据类型是浮点数,还要注意浮点数的精度问题
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
关系运算符
浮点数的相等性判断
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
float left = 10.00000000001;
float right = 10.00000000000001;
//因为超过了float精确范围,所以是相等,即结果为1
printf(" left == right ? %d
", (left == right));
system("pause");
return 0;
}
关系运算符案例:模拟面试场景
#define _CRT_SECURE_NO_WARNINGS
#define INTERVIEW_SCORE 90
#include <stdio.h>
#include <stdlib.h>
/*
关系运算模拟面试场景
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
printf("请输入笔试的分数
");
int score = 0;
scanf("%d",&score);
score > INTERVIEW_SCORE ? printf("你通过了面试
") : printf("回家等电话
");
system("pause");
return 0;
}
关系运算案例:检查是否满足结婚条件
#define _CRT_SECURE_NO_WARNINGS
#define MAN_AGE 22
#define WOMEN_AGE 20
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
关系运算实现是否符合结婚的条件
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
char boy[2] = "男";
char girl[2] = "女";
printf("请输入你的性别
");
char gender[3] = { 0 };
scanf("%s", gender);
printf("请输入你的年龄
");
int age = 0;
scanf("%d", &age);
printf("你的性别是%s 你的年龄是%d", gender, age);
//strcmp表示两个字符串的比较,如果返回0则为相等,需要引入<string.h>头文件
// //判断要么满足年龄大于等于22周岁并且性别为男性,或则年龄大于等于20周岁并且性别为女性的才能结婚
strcmp(gender, boy)==0 && age >= 22 || strcmp(gender, girl)==0 && age >= 20 ? printf("你已经到了法定的结婚年龄
") : printf("你还没有到结婚的年龄,好好学习吧
");
system("pause");
return 0;
}
关系运算符案例:根据不同的性别销售不同的商品
#define _CRT_SECURE_NO_WARNINGS
#define MEN "男"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
关系运算实现根据不同的性别销售不同的商品
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
printf("请输入你的性别
");
char gender[3] = { 0 };
scanf("%s", gender);
strcmp(gender, MEN) == 0 ? printf("销售刮胡刀
") : printf("销售化妆品
");
system("pause");
return 0;
}
3.7 逻辑运算符
逻辑运算是根据数据的逻辑关系,生成一个0或者1的值,常用的逻辑运算符有逻辑与(&&),逻辑或(||)和逻辑非(!)
- 逻辑与(&&):表达式左右两边都是1,逻辑与的结果为1,否则为0
- 逻辑或(||):表达式左右两边只要有1边为1,逻辑或为1,否则为0
- 逻辑非(!):表达式结果1,逻辑非为0,否则为1
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
逻辑运算符
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
//逻辑与:&&两边结果为1,逻辑与为1
printf("1 && 1 =%d
", (1 && 1));
//&&两边有一个为0,结果为0
printf("1 && 0 =%d
", (1 && 0));
//逻辑或: ||两边有一边为1 结果为1
printf("1 || 1 =%d
", (1 || 1));
//||两边同时为0,结果为0
printf("0 || 0 = %d
", (0 || 0));
//逻辑非 !0 就是1 反之就是0
printf("!1= %d
", (!1));
printf("!0 = %d
", (!0));
system("pause");
return 0;
}
逻辑与和逻辑或还存在短路特性:一旦明确整个表达式的值,就不再计算表达式余下的部分
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
逻辑运算符之短路特性
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
int left = 5;
int right = 8;
//逻辑与左边已经是0,因此整个表达式的结果就是0,不再计算++left
0 && ++left;
printf("0 && ++left = %d
",(0 && ++left));
//逻辑或左边已经是1,因此整个表达式的结果就是1,不再计算++right
1 || ++right;
printf("1 || ++right = %d
", (1 || ++right));
printf("left =%d
", left);
printf("right =%d
", right);
system("pause");
return 0;
}
3.8 位运算符
位(bit)是计算机底层最基本的数据单位,使用二进制的0或则1来表示,而位运算就是基于二进制的运算。常用的运算符及其规则
按位与(&):如果&两边都是1,运算结果为1,否则为0
按位或(|):如果|两边都是0,结果为0,否则为1
按位异或():如果两边都是0或者都是1,结果为0,否则为1
按位左移(<<):移动1位表示乘以2,依次类推
按位右移(>>):移动1位表示除以2,依次类推
按位取反(~):1变成0,0变成1
按位与
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
按位与(&):如果&两边都是1,运算结果为1,否则为0
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
unsigned char ch = 255; // 无符号的255的二进制表示为 1111 1111
unsigned char nch = 15; // 无符号的15的二进制表示为 0000 1111
//将1111 1111和0000 1111 进行按位与运算 结果是1111 转换为十进制结果输出就是15
printf("255 & 15 = %d
", (255 & 15));
system("pause");
return 0;
}
按位或
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
按位或:如果|两边都是0,结果为0,否则为1
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
unsigned char ch = 255; // 无符号的255的二进制表示为 1111 1111
unsigned char nch = 15; // 无符号的15的二进制表示为 0000 1111
//将1111 1111和0000 1111 进行按位与运算 结果是11111111 转换为十进制结果输出就是255
printf("255 & 15 = %d
", (255 | 15));
system("pause");
return 0;
}
按位异或实现变量交换
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
按位异或实现变量交换
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
int left = 10;
int right = 20;
printf("swap before left = %d right =%d
", left, right);
//异或运算实现变量交换
left = left ^ right;
right = left ^ right;
left = left ^ right;
printf("swap after left = %d right =%d
", left, right);
system("pause");
return 0;
}
按位取反
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
按位取反运算
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
//二进制表现形式为 0000 0001
unsigned char ch = 1;
//取反之后的二进制是 1111 1110
unsigned char not_ch = ~ch;
printf("无符号字符1取反的结果是%d
", not_ch);
// 整数1的二进制是 0000 0000 0000 0000 0000 0000 0000 0001
unsigned int num = 1;
//取反后的结果是 1111 1111 1111 1111 1111 1111 1111 1110
unsigned int not_num = ~num;
printf("无符号整数1取反的结果是%u
", not_num);
system("pause");
return 0;
}
按位左移运算
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
按位左移
左移运算符 就是乘以2的N次方,例如左移1位,就是乘以2的1次方,左移2位,就是乘以2的2次方 依次类推
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
//10的二进制是0000 0000 0000 0000 0000 0000 0000 1010
//左边移一位是0000 0000 0000 0000 0000 0000 0001 0100
printf("10左移动1位的结果是%d
", 10 << 1);
printf("10左移动2位的结果是%d
", 10 << 2);
system("pause");
return 0;
}
按位右移运算
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
按位右移
按位右移运算符 就是除以2的N次方 例如右边移动1位,就是除以2的1次方,右移动2位,就是除以2的2次方
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
int num = 10;
//10的二进制是0000 0000 0000 0000 0000 0000 0000 1010
//右移动一位是0000 0000 0000 0000 0000 0000 0000 0101
printf("10 右移1位的结果是%d
", num >> 1);
system("pause");
return 0;
}
在日常开发中,位运算同时还可以和赋值运算符使用简化表达式,完成数据的计算
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
按位运算与赋值运算结合使用
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@wechat 18601767221
@version 2019/11/15
*/
int main(int argc, char* argv[])
{
unsigned char ch1 = 10;
unsigned char ch2 = 20;
printf("ch1 = %d
",ch1);
printf("ch2 = %d
",ch2);
ch1 &= ch2;
printf("ch1 &= ch2 =%d
",ch1&=ch2);
ch1 |= ch2;
printf("ch1 |= ch2 =%d
", ch1 |= ch2);
ch1 ^= ch2;
printf("ch1 ^= ch2 =%d
", ch1 ^= ch2);
ch1 <<= ch2;
printf("ch1 <<= ch2 =%d
", ch1 <<= ch2);
ch1 >>= ch2;
printf("ch1 >>= ch2 =%d
", ch1 >>= ch2);
system("pause");
return 0;
}