C语言核心技术-数据运算

C语言核心技术-数据运算

4.1 运算符概述

计算机最核心的任务就是完成数据的计算,C语言提供了丰富(多达34种)的运算符来实现不同数据类型的各种运算,之前在求数据类型的大小时已经使用过的sizeof()就是一种运算符,最常用的运算符有算术,关系,逻辑以及比较和位运算符,在介绍具体的运算符之前先要明确关于运算符的一些概念。

  • 操作数:就是参与运算的数据,例如2,(3+2)都是一个操作数
  • 运算符:指定数据执行的运算类型,例如算术,逻辑,关系,比较,位运算等等
  • 表达式:由操作数和运算符组成,通常都是完成某种业务数据计算而设计的,例如计算圆的面积等等。
  • 优先级:在各种运算符参与运算时,有不同的执行顺序,由它们的优先级决定,可以使用()来改变执行的顺序。
  • 结合性:执行运算的方向,例如从左到右或者从右到左。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    关于数据计算中的几个概念

    操作数:就是参与运算的数据,例如2,(3+2)都是一个操作数
    运算符:指定数据执行的运算类型,例如算术,逻辑,关系,比较,位运算等等
    表达式:由操作数和运算符组成,通常都是完成某种业务数据计算而设计的,例如计算圆的面积等等。
    优先级:在各种运算符参与运算时,有不同的执行顺序,由它们的优先级决定,可以使用()来改变执行的顺序。
    结合性:执行运算的方向,例如从左到右或者从右到左。
    @author liuguanglei [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/11
*/
int main(int argc, char* argv[])
{

    //运算符: 表示参与数据的运算方式,这里的加号(+)就是运算符
    //5和10表示操作数,即参与运算的数据
    int value = 5 + 10;
    printf("5 + 10 = %d \n",value);

    //优先级:计算的先后顺序,算术运算中是先乘除,后加减,可以通过()改变优先级
    //结合性:计算的方向,从左向右。 优先级相等的情况下计算的顺序
    int precedence = (45 + 5) / 5 * 10;
    printf("(45 + 5) / 5 * 10 = %d\n",precedence);

    //运算符不能相邻
    //此处会发生编译错误
    //1 + *3;

    //但是在执行加减法运算时,编译器会+ -法当作正负数,例如+8表示正数8
    int val  = 2+ +8;
    printf("2+ +8 = %d \n",val  );

    //运算符和操作数组成了表达式
    //()可以嵌套使用
    int result= ((4 * 5) + (20 - 10) - 12 * 3) + 12 - 2;

    system("pause");
    return 0;
}

4.2 算术运算符

算术运算符就是数学意义上的加减乘除(+ - * /)以及取模运算(即求余数)。
其优先级是按照先乘除,后加减的计算顺序。结合性是从左到右的计算方向。

C语言规定,两个整数相除结果是整数,小数部分被舍去。
两个整数执行求余运算时,运算结果的符号和被除数相同。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    算术运算符的基本使用
    算术运算的加减乘除等同于数学意义的加减乘除
    但是C语言规定整数和整数相除,结果是整数,小数部分被舍去
    整数求余时,求余结果的符号类型和被除数一致
    @author liuguanglei [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/11
*/
int main(int argc, char* argv[]){

    

    //声明两个整数变量
    int left = 10;
    int right = 5;

    //常见的算术运算
    printf("10 +5 = %d \n",left+right);
    printf("10 -5 = %d \n",left-right);
    printf("10 *5 = %d \n",left*right);
    printf("10 /5 = %d \n",left/right);
    //求模运算就是求余数,这里为了正确显示%,特意使用了两个%
    printf("10 %% 5 = %d \n",left%right);
    //这里会发生编译错误,只有整数才能够取模
    //printf(5%2.0);

     //取模结果的符号和被除数相同,例如这里的被除数就是5 因此取模的结果是正数
    printf("5 %% -3 = %d\n", (5 % -3));
    //取模结果的符号和被除数相同,例如这里的被除数就是-5 因此取模的结果是负数
    printf("-5 %% 3 = %d\n", (-5 % 3));


    //算术运算结果的类型是参与运算中的最大数据类型, 整数和整数运算的结果是整数
    printf("5 / 2 = %d \n",(5/2));
    // 2.5 *2的结果是浮点数,%d无法解析浮点数,这里通过强制类型转换将浮点数转换为整数,以便获取正确的运算结果
    printf("2.5 * 2 = %d \n",(int)(2.5*2));

    system("pause");
    return 0;
}

当除号两边都是整数,叫做整除,运算结果只保留整数部分。当除号任何一边有浮点数时,结果一定时浮点数,如果只想要保留整数部分,可以通过强制类型转换实现。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

 算术运算之除法运算
 @author liuguanglei [email protected]
 @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 \n", flt);

    //整数和浮点数运算结果一定是浮点数
    flt = 12 / 2.5;
    printf("lt = %.2f \n", flt);

    //如果想要获得整数,必须使用强制类型转换实现
    printf("5.0 / 2 = %d\n", (int)(5.0 / 2));
    system("pause");
    return 0;
}

只有整数参与取模运算,取模运算的结果和被除数的符号一致,也就意味着如果被除数是正数,那么取模的结果就是正数,反之亦然。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    算术运算之求模运算
    求模运算就是两个整数相除,求余数
    求模的结果类型和被除数的符号一致

    @author liuguanglei [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/12
*/
int main(int argc, char* argv[])
{
    //为了控制台输出%,这里需要使用%%
    printf("8 %% 3 = %d\n",8%3);
    //取模的结果类型和被除数的符号一致,因为被除数(-8)是负数,因此取模的结果也是负数
    printf("-8 %% 3 = %d\n",-8%3);
    printf("8 %% -3 = %d\n",8%-3);

    /*************************求模的案例***********************************/
    printf("3%%5 = %d\n", 3 %5); //3
    printf("3%%-5 = %d\n", 3 %-5);//3
    printf("-3%%5 = %d\n", -3 %5);//-3
    printf("-3%%-5 = %d\n", -3 %-5);//-3

    printf("5%%3 = %d\n", 5 % 3); //2
    printf("-5%%3 = %d\n", -5 % 3);//-2
    printf("5%%-3 = %d\n", 5 % -3);//2
    printf("-5%%-3 = %d\n", -5 % -3);//-2


    system("pause");
    return 0;
}

求模运算的案例:输入一个整数,输出颠倒后的结果。例如输入95,输出59。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
    取模运算的案例
    将一个两位整数实现颠倒
    例如输入95 输出59
    @author liuguanglei [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/12
*/
int main(int argc, char* argv[])
{
    
    int number = 0;
    printf("请输入一个整数,按回车键结束\n");
    scanf("%d",&number);

    //获取输入整数的个位和十位
    int unit = number % 10;
    int decade = number / 10;
    //计算颠倒之后的结果
    int reversal = unit * 10 + decade;

    printf("输入整数%d颠倒之后的结果是%d\n",number,reversal);
    system("pause");
    return 0;
}

取模运算案例:输入一个三位数,将三位数颠倒后输出,例如输入123,输出321。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
    
    取模案例
    将一个三位数颠倒
    例如输入123,输出321

    @author liuguanglei [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/12
*/
int main(int argc, char* argv[])
{
    int number = 0;
    printf("请输入一个三位整数,按回车键结束\n");
    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\n",number,reserval);
    system("pause");
    return 0;
}

4.3 赋值运算符

在学习变量赋值时用到的等号(=)实际上就是赋值运算符,它的作用就是用来将一个常量或者表达式赋值给一个变量,其赋值的格式为 数据类型 变量标识符=常量值或者表达式
优先级:所有运算符中仅高于逗号运算符,
结合性:当表达式中有多个变量同时赋值时按照从右往左的结合性进行赋值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    赋值运算符的基本使用
    赋值是将常量或者表达式赋值给变量
    优先级:仅仅高于逗号运算符
    结合性:从右向左
    @author liuguanglei [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/12
*/
int main(int argc, char* argv[])
{

    //常量赋值给变量
    int number = 10;
    number = 18;
    printf("number = %d \n",number);

    printf("number = %d\n", number = 20); //num=20 赋值表达式整体的值就是num被赋值的变量,即num=20

    int left;
    int right;
    //结合性:从右向左进行赋值
    left = right = 88;
    printf("left = %d  \n", left);
    printf("right = %d  \n", right);


    system("pause");
    return 0;
}

在赋值时,赋值运算符左边被赋值的值叫做左值,就是有内存实体的变量。右值就是能放在赋值号右边,并且能够赋值给其他变量的值,左值可以当作右值赋值给其他变量,但是右值不能当作左值使用。
在赋值时会进行自动类型转换。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    赋值时的左值和右值
    @author liuguanglei [email protected]
    @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\n",number);
    printf("newNumber = %d\n", newNumber);

    //赋值时会发生类型转换,这里会将19.2的小数部分舍去,输出结果是19
    int value = 19.2;
    printf("value = %d \n",value);
    system("pause");
    return 0;
}

在日常开发中,为了简化表达式,赋值运算还可以和算术运算结合使用

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
    赋值运算符和算术运算符结合使用
    @author liuguanglei [email protected]
    @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 \n",number);
    //此处等价于number=number-5
    number -= 5;
    printf("number = %d \n", number);

    //此处等价于number=number*5
    number *= 2;
    printf("number = %d \n", number);

    //此处等价于number=number/5
    number /= 5;
    printf("number = %d \n", number);

    system("pause");
    return 0;
}

4.4 自增自减运算符

自增、自减运算符的作用是将变量的值增加1或者减少1,。自增运算符是++。自减运算符是--。
在使用时需要注意自增、自减运算符只能作用域变量,不能作用在常量或者表达式。
而前置++、--和后置++、--的区别是当自增、自减运算符放置在变量前面时会先自增、自减1,再参与运算,当自增、自减运算符放在变量后面时会先参与运算,再自增、自减1。

自增、自减运算符和算术运算符同时参与运算时,自增、自减运算符优先级高于算术运算符。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    自增自减运算符
    @author liuguanglei [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/15
*/
int main(int argc, char* argv[])
{
    int age = 26;
    //自增运算符作用于变量
    age++;
    printf("age++ = %d\n",age);

     age = 26;
    //如果单独一行语句 age++ 和++age的作用是一样的,都是将变量增加1

    ++age;
    printf("++age = %d\n",age);

    int number = 20;
    //先输出number的值然后自增1
    printf("number++ =%d\n "+ number++);
    printf("number = %d\n", number);

    //当自增运算符和算术运算符进行运算时,自增运算符的优先级高于算术运算符
    number = 5;
    printf("number++ +3 = %d\n",(number++ + 3));

    //自增运算符只能作用于变量
    //5++;

    system("pause");
    return 0;
}

4.5 三元运算符

三元运算符也被称为条件运算符,其表现形式为表达式1?表达式2:表达式3,其中如果表达式1的条件成立,那么表达式的计算结果就是表达式2,否则计算结果就是表达式3。
三元运算符和if/else的作用是等价的。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    三元运算符之类型转换
    @author liuguanglei [email protected]
    @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\n", (fl > num ? fl : num));
    system("pause");
    return 0;
}

使用条三元算符结合关系运算符实现求两个整数的最大值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    三元运算符之获取两个整数之间的最大值
    @author liuguanglei [email protected]
    @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 \n",max);
    system("pause");
    return 0;
}

使用三元运算符结合关系运算符求三个整数的最大值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    三元运算符之获取三个整数之间的最大值
    @author liuguanglei [email protected]
    @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("请输入第一个整数,按回车键结束\n");
    scanf("%d",&left);

    printf("请输入第二个整数,按回车键结束\n");
    scanf("%d", &middle);

    printf("请输入第三个整数,按回车键结束\n");
    scanf("%d", &right);

    //首先比较left和right
    //然后拿比较的结果和middle比较
    int max =(left > right ? left : right) > middle ? (left > right ? left : right) : middle;

    printf("你输入的三个整数分别是%d \t %d \t %d \n",left,middle,right );
    printf("三个整数之中最大的值是%d\n",max);
     

    system("pause");
    return 0;
}

三元运算符优先级仅仅高于赋值运算符,结合性是从左向右

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
    
    三元运算符优先级与结合性

    三元运算符优先级仅仅高于赋值运算符
    三元运算符的结合性是从左向右

    @author liuguanglei [email protected]
    @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 \n", result);

    system("pause");
    return 0;
}

三元运算符结合关系运算符实现计算四个整数中的最大值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    三元运算符之获取四个整数之间的最大值
    @author liuguanglei [email protected]
    @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\n",max);
    system("pause");
    return 0;
}

4.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 [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/15
*/
int main(int argc, char* argv[])
{
    bool flag = 88 <99;
    //使用整数输出flag的值
    printf("88 <99=%d\n",flag);

    flag = 88 > 99;
    printf("88 >99=%d\n", flag);

    system("pause");
    return 0;
}

而关系运算符的结合性是从左向右依次运算

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*

    关系运算符
    关系运算符的结合性:从左向右
    @author liuguanglei [email protected]
    @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 \n",(5>4>3));
    system("pause");
    return 0;
}

在使用关系运算符进行相等性判断时,如果数据类型是浮点数,还要注意浮点数的精度问题

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*

    关系运算符
    浮点数的相等性判断
    @author liuguanglei [email protected]
    @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\n", (left == right));
    system("pause");
    return 0;
}

关系运算符案例:模拟面试场景

#define _CRT_SECURE_NO_WARNINGS
#define INTERVIEW_SCORE 90
#include <stdio.h>
#include <stdlib.h>
/*
    关系运算模拟面试场景
    @author liuguanglei [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/15
*/
int main(int argc, char* argv[])
{
    printf("请输入笔试的分数\n");
    int score = 0;
    scanf("%d",&score);

    score > INTERVIEW_SCORE ? printf("你通过了面试\n") : printf("回家等电话\n");

    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 [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/15
*/
int main(int argc, char* argv[])
{
    char boy[2] = "男";
    char girl[2] = "女";

    printf("请输入你的性别\n");
    char gender[3] = { 0 };
    scanf("%s", gender);

    printf("请输入你的年龄\n");
    int age = 0;
    scanf("%d", &age);

    printf("你的性别是%s\t你的年龄是%d", gender, age);


    //strcmp表示两个字符串的比较,如果返回0则为相等,需要引入<string.h>头文件
   //	//判断要么满足年龄大于等于22周岁并且性别为男性,或则年龄大于等于20周岁并且性别为女性的才能结婚

    strcmp(gender, boy)==0 && age >= 22 || strcmp(gender, girl)==0 && age >= 20 ? printf("你已经到了法定的结婚年龄\n") : printf("你还没有到结婚的年龄,好好学习吧\n");


    system("pause");
    return 0;
}

关系运算符案例:根据不同的性别销售不同的商品

#define _CRT_SECURE_NO_WARNINGS
#define MEN "男"

#include <stdio.h>
#include <stdlib.h>

#include <string.h>

/*

    关系运算实现根据不同的性别销售不同的商品
    @author liuguanglei [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/15
*/
int main(int argc, char* argv[])
{
    printf("请输入你的性别\n");
    char gender[3] = { 0 };
    scanf("%s", gender);
    strcmp(gender, MEN) == 0 ? printf("销售刮胡刀\n") : printf("销售化妆品\n");
    system("pause");
    return 0;
}

4.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 [email protected]
    @website ittimeline.net
    @wechat 18601767221
    @version 2019/11/15
*/
int main(int argc, char* argv[])
{
    //逻辑与:&&两边结果为1,逻辑与为1
    printf("1 && 1 =%d\n", (1 && 1));
    //&&两边有一个为0,结果为0
    printf("1 && 0 =%d\n", (1 && 0));

    //逻辑或: ||两边有一边为1 结果为1
    printf("1 || 1 =%d\n", (1 || 1));
    //||两边同时为0,结果为0
    printf("0 || 0 = %d\n", (0 || 0));
    //逻辑非 !0 就是1 反之就是0
    printf("!1= %d\n", (!1));
    printf("!0 = %d\n", (!0));
    system("pause");
    return 0;
}

逻辑与和逻辑或还存在短路特性:一旦明确整个表达式的值,就不再计算表达式余下的部分

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    逻辑运算符之短路特性
    @author liuguanglei [email protected]
    @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 \n ",(0 && ++left));
    //逻辑或左边已经是1,因此整个表达式的结果就是1,不再计算++right
    1 || ++right;
    printf("1 || ++right = %d \n ", (1 || ++right));


    printf("left =%d \n", left);
    printf("right =%d \n", right);
    system("pause");
    return 0;
}

4.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 [email protected]
    @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\n", (255 & 15));
    system("pause");
    return 0;
}

按位或

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    按位或:如果|两边都是0,结果为0,否则为1
    @author liuguanglei [email protected]
    @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\n", (255 | 15));
    system("pause");
    return 0;
}

按位异或实现变量交换

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    按位异或实现变量交换
    @author liuguanglei [email protected]
    @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\n", left, right);
    //异或运算实现变量交换
    left = left ^ right;
    right = left ^ right;
    left = left ^ right;
    printf("swap after  left = %d  right =%d\n", left, right);
    
    system("pause");
    return 0;
}

按位取反

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    按位取反运算
    @author liuguanglei [email protected]
    @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\n", 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\n", 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 [email protected]
    @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\n", 10 << 1);
    printf("10左移动2位的结果是%d\n", 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 [email protected]
    @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\n", num >> 1);

    system("pause");
    return 0;
}

在日常开发中,位运算同时还可以和赋值运算符使用简化表达式,完成数据的计算

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    按位运算与赋值运算结合使用
    @author liuguanglei [email protected]
    @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\n",ch1);
    printf("ch2 =  %d\n",ch2);
    ch1 &= ch2;
    printf("ch1 &= ch2 =%d \n",ch1&=ch2);

    ch1 |= ch2;
    printf("ch1 |= ch2 =%d \n", ch1 |= ch2);

    ch1 ^= ch2;
    printf("ch1 ^= ch2 =%d \n", ch1 ^= ch2);


    ch1 <<= ch2;

    printf("ch1 <<= ch2 =%d \n", ch1 <<= ch2);

    ch1 >>= ch2;
    printf("ch1 >>= ch2 =%d \n", ch1 >>= ch2);

    system("pause");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ittimeline/p/11871676.html