当前位置: 首页 > news >正文

05-1基于vs2022的c语言笔记——运算符

目录

前言

5.运算符和表达式

5-1-1 加减乘除运算符

1.把变量进行加减乘除运算

2.把常量进行加减乘除运算

3.对于比较大的数(往数轴正方向或者负方向),要注意占位符的选取

4.浮点数的加减乘除 

5-1-2取余/取模运算符

1.基本规则

2.c语言中,取余与除法规则的区分

5-1-3 字符的加减法

1.基本规则和原理

2. 可以输出一下‘X’,‘Z’对应的ASCII码值,加以验证 

3.字符加减法的应用

1.输入小写字母,输出大写字母

2.输入大写字母,输出小写字母

5-2递增递减运算符

1.前缀自增与后缀自增含义相同的情况

2前缀自增和后缀自增的区别 

3.前缀自减和后缀自减同理

4.++i和i++在循环语句里经常用 

5-3赋值运算符

1.简单赋值运算符

1-0 赋值语句的写法与读法

 1-1把常量赋值给变量

1-2把变量赋值给变量

1-3把计算结果赋值给变量 

2.复合赋值运算符

2-0.复合赋值运算符都有些什么

 2-1.复合赋值运算符的作用

2-2详细演示

5-4关系运算符/比较运算符(别名)

 1.关系运算符都有什么?

2.实际应用举例

2-1输出结果显示0或1 如果满足该关系运算符,则输出1,不满足该关系运算符 输出0

5-5逻辑运算符

1.逻辑运算符都有什么?

2.计算机与人脑是不一样的!下方举例说明,这也就是为什么要引进逻辑运算符的原因 

3.逻辑运算符具体情况分析 

4.短路原则

5-6逗号运算符

 1.应用1:作为分隔符使用

 补充一个坑点

​编辑 2.应用2,便于记忆变量值的互换

5-7位运算符概览

铺垫 1.十进制数与二进制数举例对比

铺垫2.如何定义一个二进制数的变量?

 铺垫3.二进制加减法竖式运算

铺垫4.二进制与十进制之间的转化 

1.位运算是什么?

2.位运算符都有什么?

5-7-1位与运算符

1-1.基本原则

1-2基本原则的实际演示

2-1位与运算符应用1——判断一个数的奇偶 

2-2位与运算符应用2——获取任意一个二进制数的低4位 

2-3位与运算符应用3——把一个二进制数末尾连续的1变成0

 5-7-2位或运算符

 1-1基本原则

 2-1位或运算符应用1——设置标记位,即把特定位的0变成1,如果原来是1则不变

2-2位或运算符应用2——置空标记位,即把特定位的1变成0,如果原来是0则不变

2-3位或运算符应用3——低位连续的0变成1 

5-7-3异或运算符

 1-1基本原则

 1-2基本原则演示

2-1异或运算符应用1——标记位取反

 2-2异或运算符应用2——变量交换

先回顾利用逗号运算符实现变量交换

 下面利用异或运算符 优点:只需要两个变量

 5-7-4按位取反运算符

 1-1写法读法

1-2利用-1巧妙解释补码的概念 

2-1按位取反的应用1——1的按位取反 

2-2按位取反的应用2——0的按位取反 

补充 

2-3按位取反的应用3——求一个数的相反数

 5-7-5左移运算符

 1-1基本原则

1-2基本原则的演示 

2左移的十进制含义 

3-1负数的左移 

 3-2左移负数位,也就是y位负数的情况,同时左移一个很大的数也不行,即y很大

 4-1左移运算符的应用——配合其他位运算符,对标记位进行操作

 5-7-6右移运算符

 1-1基本原则

1-2基本原则演示 

1-3右移运算符的十进制含义 

2-1负数的右移位 

2-2移负数位,是不合法的,不能用

3-1右移运算符的应用——去掉k位


前言

本套笔记是基于英雄哪里出来c语言入门到精通课程整理的笔记

包含代码,代码演示结果,以及便于理解的插图

对于想要c语言入门,嵌入式c语言的入门的朋友来说,这是一套不可多得的教程

此教程分几篇文章发布,初步计划更新到函数,未来时间允许会继续更新

5.运算符和表达式

5-1-1 加减乘除运算符

1.把变量进行加减乘除运算

#include <stdio.h>
int main(){
    int a=7, b=6;//注意两个变量的中间用英文的逗号隔开
    printf("a+b=%d\n",a+b);
    printf("a-b=%d\n",a-b);
    printf("a*b=%d\n",a*b);//注意乘号在键盘数字8的上面
    printf("a/b=%d\n",a/b);
    return 0;
}

 

2.把常量进行加减乘除运算

#include <stdio.h>
int main(){
    printf("%d\n",7+6);
    printf("%d\n",7-6);
    printf("%d\n",7*6);
    printf("%d\n",7/6);
    return 0;
}

 

3.对于比较大的数(往数轴正方向或者负方向),要注意占位符的选取

4.浮点数的加减乘除 

#include <stdio.h>
int main(){
    double a=3.1415, b=6.21;
    printf("a+b=%lf\n",a+b);
    printf("a-b=%lf\n",a-b);
    printf("a*b=%lf\n",a*b);
    printf("a/b=%lf\n",a/b);
    return 0;
}

 

5-1-2取余/取模运算符

1.基本规则

#include <stdio.h>
int main(){
/*取余运算符  % 
注意事项:
1.被除数和除数都必须为整数
2.取余结果的正负只由被除数决定   
*/
    int a=100,b=9;
    printf("%d\n",a%b);

    printf("%d\n",100%9);
    printf("%d\n",100%-9);
    printf("%d\n",-100%9);
    printf("%d\n",-100%-9);
    return 0;
}

 

2.c语言中,取余与除法规则的区分

1.取余输出结果为余数,除法输出结果为商

2.取余只能用于两个整数,除法可以用于整数和浮点数

3.除法结果的正负由被除数和除数共同决定,也就是和数学中一致;取余结果的正负只由被除数的正负决定

5-1-3 字符的加减法

1.基本规则和原理

#include <stdio.h>
int main(){
    char ch='Y';
    printf("%c\n",ch+1);
    printf("%c\n",ch-1);

    return 0;
}

 

2. 可以输出一下‘X’,‘Z’对应的ASCII码值,加以验证 

#include <stdio.h>
int main(){
    char ch='Y';
    printf("%d\n",ch+1);
    printf("%d\n",ch-1);

    return 0;
}

3.字符加减法的应用

1.输入小写字母,输出大写字母

首先肯定有定义变量ch;并且让我们可以在黑框输入一个变量,也就是任意一个小写字母

char ch;

scanf("%c\n",ch);

 接着分析小写字母和大写字母的联系:

举例分析,比如b在小写字母表排第二位,而B在大写字母表里也排第二位

小写字母和大写字母都有26个

所以可以利用排位一致的特点进行方程的构造

设小写字母为ch(上面已经设了)

设大写字母为y

到这里还毫无头绪,没法把排位的特点用上

下一步就是拆,把变量拆成常量+变量的形式,利于分析关系

任意一个大写字母都可以写成 'A'+一个数字

B=A+1 C=A+2.....Z=A+25

1到25其实就是大写字母在字母表中的排位概念的变形

下一步就是小写字母也构造出排位,方法也是拆

b=a+1 c=a+2........z=a+25

其中等号左边是定义的变量ch

等号右边是‘a’+x

ch='a'+x

而B=A+1 C=A+2.....Z=A+25 等号左边是定义的变量y,等号右边是 'A'+x

y='A'+x

下面开始写代码看看构造出可解的方程

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
    char ch, x, y;
    scanf("%c", &ch);
    //这一步不可能马上想出来,可以先在下面构造方程时用上变量,最后再来补充定义变量的操作
    x = ch - 'a';
    y = 'A' + x;
    printf("%c\n", y);
    return 0;
}

2.输入大写字母,输出小写字母

B=A+1 C=A+2.....Z=A+25 ch='a'+x

b=a+1 c=a+2........z=a+25 y='A'+x

按照上面的分析列方程如下

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
    char y,x,ch; 
    scanf("%c",&y);
    x=y-'A';
    ch='a'+x;
    printf("%c\n",ch);

    return 0;
}

5-2递增递减运算符

递增递减又叫自增自减

1.前缀自增与后缀自增含义相同的情况

#include <stdio.h>
int main(){
    int i=1;
    i++; //后缀自增
    printf("%d\n",i);
    ++i;//前缀自增
    printf("%d\n",i);
    return 0;
}

 

2前缀自增和后缀自增的区别 

#include <stdio.h>
int main() {
    int a = 1,b = 1;
    int c = a++;
    int d = ++b;
    printf("c = %d , d = %d\n", c,d);

    printf("a = %d , b = %d\n", a,b);

    return 0;
}

 

你会发现d加1了,但是c没有加一

而a和b都加一了
这是因为除了自增自减运算符以外还有赋值符的参与
一般只要没有其他种类运算符以及赋值符号参与时,前缀和后缀自增(减)没有区别

这时候就得引出i++(后缀自增)和++i(前缀自增)的区别了

后缀自增是 先把a的数值给c用,再自增即a的数值加一(如上图)

前缀自增是 先把b的数值加一,再把自增后的值给d(如上图)

3.前缀自减和后缀自减同理

#include <stdio.h>
int main() {
    int a = 2,b = 2;
    int c = a--;
    int d = --b;
    printf("c = %d , d = %d\n", c,d);

    printf("a = %d , b = %d\n", a,b);

    return 0;
}

后缀自减是 先把a的数值给c用,再自减即a的数值减1(如上图)

前缀自减是 先把b的数值减1,再把自减后的值给d(如上图)

4.++i和i++在循环语句里经常用 

for(int i=0;i<10;++i ){}

在这里用i++和++i效果一样,只不过++i运行效率更高一点

5-3赋值运算符

1.简单赋值运算符

1-0 赋值语句的写法与读法

举例:
写法:a=6    从左往右;      读法:把常量6赋值给变量a        从右往左
写法:a=b    从左往右;      读法:把变量b赋值给变量a        从右往左
写法:a=a+b  从左往右;      读法:把a+b的计算结果赋值给变量a 从右往左

 1-1把常量赋值给变量
#include <stdio.h>
int main(){
    int a;
    a=6;//把常量6赋值给变量a
    printf("%d\n",a);

    return 0;
}

 

1-2把变量赋值给变量
#include <stdio.h>
int main(){
    int a,b;
    a=6;
    b=a;//把变量a的值赋值给变量b
    printf("%d\n",b);

    return 0;
}

 

1-3把计算结果赋值给变量 
#include <stdio.h>
int main() {
    int a, b;
    a = 6;
    b = a;     //把变量a的值赋值给变量b        b=6
    a = a + b; //把a+b的计算结果赋值给a       a=12
    printf("%d\n", b);
    printf("%d\n", a);

    return 0;
}

 

2.复合赋值运算符

2-0.复合赋值运算符都有些什么

a+=b 加等于  a把b的值加上再输出 等于a的新值    也就是a=a+b的意思
a-=b 减等于  a把b的值减掉再输出 等于a的新值    也就是a=a-b的意思
a*=b 乘等于  a把b的值乘上再输出 等于a的新值    也就是a=a*b的意思
a/=b 除等于  a把b的值除掉再输出 等于a的新值    也就是a=a/b的意思
a%=b 模等于  a除b取模再输出    等于a的新值    也就是a=a%b的意思

 2-1.复合赋值运算符的作用

缩短代码的长度 增加可读性 利于理解 特别是当变量名很长的时候
int longlonglongname =6;
longlonglongname +=6 //longlonglongname=longlonglongname+6 也就是12

2-2详细演示
#include <stdio.h>
int main() {
    int a, b;
    a = 6;
    b = 6;
    a += b;
    printf("%d %d\n", a, b);  //a=12 b=6
    a -= b;
    printf("%d %d\n", a, b);  //a=6  b=6
    a *= b;
    printf("%d %d\n", a, b);  //a=36 b=6
    a /= b;
    printf("%d %d\n", a, b);  //a=6 b=6
    a %= b;
    printf("%d %d\n", a, b);  //a=0 b=6  a是6除以6后得到的余数 也就是0
    return 0;
}

 

5-4关系运算符/比较运算符(别名)

 1.关系运算符都有什么?

a == b  == 等于
a != b  !=  不等于
a >  b  >  大于
a >= b  >=   大于等于 即大于或者等于满足其一即可
a <= b  <=   小于等于 即小于或者等于满足其一即可
a <  b  <    小于

2.实际应用举例

2-1输出结果显示0或1 如果满足该关系运算符,则输出1,不满足该关系运算符 输出0
#include <stdio.h>
int main() {
    int a = 1, b = 2;
    printf("a==b-->%d\n", a == b);
    printf("a!=b-->%d\n", a != b);
    printf("a >b-->%d\n", a > b);
    printf("a>=b-->%d\n", a >= b);
    printf("a <b-->%d\n", a < b);
    printf("a<=b-->%d\n", a <= b);

    return 0;
}

5-5逻辑运算符

1.逻辑运算符都有什么?

(1)逻辑与 又叫且   
写法: a && b     读法:a逻辑与上b  
原则:只有&&两边条件同时满足,打印时才输出1 
     也就是&&两边都为真 才输出1 
     也就是&&两边都为1才输出1 因为c语言中1为真 0为假
(2)逻辑或 
写法: a||b       读法:a逻辑或b
原则: 只要||两边条件满足其一,打印时就输出1
      也就是||两边只要有一个为真 就输出1
      也就是||两边只要有一个1,就输出1 
(3)逻辑非
写法   !a        读法:逻辑非a
原则:只要与a不同就输出1,反之如果与a相同则输出0
     !1输出0 !0输出1

2.计算机与人脑是不一样的!下方举例说明,这也就是为什么要引进逻辑运算符的原因 

因为计算机是这样判断的

先判断左边 -10<0显然正确 为真 所以输出1 然后1再和10比较 1<10明显也正确 为真 所以最终输出1

那么11也同理
先判断左边 -10<11 显然正确 为真 所以输出1 然后1在与10比较 1<10明显也正确 为真 所以最终输出1

所以计算机和人脑是不一样的,因此编程作为给计算机阅读的语言需要严格杜绝这种情况 因此引入了逻辑运算符

3.逻辑运算符具体情况分析 

#include <stdio.h>
int main() {
    printf("&& %d %d %d %d\n",(1 && 1),(1 && 0),(0 && 1),(0 && 0) );
    printf("|| %d %d %d %d\n", (1 || 1), (1 || 0), (0 || 1), (0 || 0));
    printf("! %d %d\n", !0, !1);
    return 0;
}

 

4.短路原则

为了提高程序运行效率,在是否满足逻辑运算符条件的判断中

如果通过计算逻辑运算符左边的内容就可以判断是否满足整个逻辑运算符的话

逻辑运算符右边的内容电脑则不需要计算

下面举个例子

5-6逗号运算符

 1.应用1:作为分隔符使用

#include <stdio.h>
int main() {
    int a = 1, b = 2, c = 3;//逗号用于分隔变量
    a++;
    ++b;
    --c; 
//如果直接输出 a=2,b=3,c=2 这里因为自增自减均为独立语句,
// 没有其他运算符和赋值符号的参与,
// 所以前缀和后缀自增,前缀自减和后缀自减效果一样 
// 下面我们可以验证一下
    printf("a = %d b = %d c = %d\n", a, b, c);
    return 0;
}

 

 当然
a++;
++b;
--c; 
写成
a++,++b,--c;
效果一样

 补充一个坑点

#include <stdio.h>
int main() {
    int a = 1, b = 2, c = 3;//逗号用于分隔变量
    printf("%d\n", (a++, ++b, --c));//这样就只会输出最后一个--c的值,也就是2
    return 0;
}

 2.应用2,便于记忆变量值的互换

#include <stdio.h>
int main() {
    int a = 1, b = 2, r;
    r = a;//把a的值1转移给r 现在r=1 a=1
    a = b;//把b的值2转移给a 现在a=2 b=2
    b = r;//把r的值1转移给b 现在b=1 r=1
    printf("a = %d b = %d r = %d\n", a, b, r);

    return 0;
}

 

但是这样下次在使用这种方法进行变量转换时,容易想不起来

因此可以利用逗号运算符,写成下面这样

#include <stdio.h>
int main() {
    int a = 1, b = 2, r;
    r = a, a = b, b = r; //非常的对称,容易记住
    printf("a = %d b = %d r = %d\n", a, b, r);

    return 0;
}

 

 

5-7位运算符概览

铺垫 1.十进制数与二进制数举例对比

十进制数            二进制数
    0                  0                        
    1                  1                                
    2                 10
    3                 11
    4                100
    5                101
    6                110
    7                111
    8               1000
    9               1001
   10               1010                
   11               1011
   12               1100
   13               1101
   14               1110
前14个可以简单记忆一下,后面更大的数的十进制和二进制转化的方法见下面

铺垫2.如何定义一个二进制数的变量?

#include <stdio.h>
int main() {
    int a = 0b1110;
    printf("%d\n", a);
    return 0;
}

 

 铺垫3.二进制加减法竖式运算

铺垫4.二进制与十进制之间的转化 

 

1.位运算是什么?

位运算可以理解成对二进制数字上的每个位进行操作的运算

2.位运算符都有什么?

布尔位运算符:位与& 位或\| 异或^ 按位取反~

移位位运算符:左移<< 右移>>

5-7-1位与运算符

1-1.基本原则

先介绍基本原则,看不懂没关系,下面会有实例演示,看完你就懂了

位与运算符 &  
写法:a & b
读法:a位与上b
位与基本原则:      
0或者1,位与上1,结果还是他本身
0或者1,位与上0,结果都是0
与逻辑与联系  a与b只有两个都为1时,结果才为1,否则则为0
两个相等的二进制数位与,结果和它们两个数一样 11101 & 11101 = 11101

1-2基本原则的实际演示

#include <stdio.h>
int main() {
    int x = 0b1010;//定义二进制数1010 其十进制数是10
    int y = 0b0110;//定义二进制数0110 其十进制数是6
     //1010(为了方便下面的计算这里高位要补0与上面的1010对齐)
    printf("%d\n", (x & y));
    //我们来列个竖式看看最终会输出什么结果
    /*利用前面讲的位与的基本原则 
    0或1,位于上1,结果都是它本身
    0或1,位与上0,结果都是0
       0b1010
    &  0b0110
    ----------
       0b0010 ——>它对应的十进制数是2 所以下面输出结果为2
    */
    return 0;
}

2-1位与运算符应用1——判断一个数的奇偶 

#include <stdio.h>
int main() {
    printf("%d\n", (0 & 1));
    printf("%d\n", (2 & 1));
    printf("%d\n", (4 & 1));
    printf("%d\n", (6 & 1));

    printf("%d\n", (1 & 1));
    printf("%d\n", (3 & 1));
    printf("%d\n", (5 & 1));
    printf("%d\n", (7 & 1));
    return 0;
}

 

为什么偶数位与上1,都输出0;奇数位于上1,都输出1?

我们可以来任意拿一个偶数和奇数演示一下

6 二进制数是110 1二进制数是001(每一位对齐,那一位没有数的,补0)

     110
   & 001
 ——————————
     000
你会发现因为1的二进制数的高位都用0补齐了,所有和任何偶数的高位进行位与,结果都是0
而1的二进制数的低位是1,1位与上0或者1,结果都是0或1本身 而偶数的二进制数表示的最低位永远是0


5的二进制数是101 1二进制数是001

    101
 &  001
 —————————
    001
你会发现因为1的二进制数的高位都用0补齐了,所有和任何偶奇数的高位进行位与,结果都是0
而1的二进制数的低位是1,1位与上0或者1,结果都是0或1本身 而奇数的二进制数表示的最低位永远是1


所以记住结论:
任意一个偶数位与上1,结果都为0
任意一个奇数位与上1,结果都为1
以此可以判断一个数的奇偶

2-2位与运算符应用2——获取任意一个二进制数的低4位 

#include <stdio.h>
int main() {
    int m = 0b101010101101;//这里是随便写的模拟任意一个二进制数变量
    int k = 0B000000001111;//因为要获取最低4位数字,所以构造二进制数1111,高位补0
    //根据位与运算符的基本原则,我们可以知道 (m & k)结刚好是二进制数m的低4位
    //所以只要我们同时输出 (m & k)和0b1101 如果结果一样 则证明我们这种方法是对的
    printf("%d %d\n", (m & k), 0b1101);
    return 0;
}

 

2-3位与运算符应用3——把一个二进制数末尾连续的1变成0

#include <stdio.h>
int main() {
    int z = 0b101101111;//任意构造一个二进制数,结尾4位是1,
                        //来模拟一个结尾有很多1的二进制数
    //要想最后几个位变成0,我们想到利用z+1进位变成0来解决这个问题
    //  z+1=0b101110000      从低位开始进位 最后4个1全因为进位变成0,
    // 第7位变成1,进位完成,前面剩下的高位保持不变
    // z & z+1 = 0b101100000
    printf("%d %d\n", (z & (z + 1)), 0b101100000);//如果这两个数一样,则证明我们的方法正确
    return 0;
}

 5-7-2位或运算符

 1-1基本原则

位或 |
写法:a|b
读法:a位或b
基本原则:
与逻辑或联系
只要a或者b其中一个为1,输出结果为1
如果a和b都为0,输出结果为0

 2-1位或运算符应用1——设置标记位,即把特定位的0变成1,如果原来是1则不变

以下设置的标记位为从低往高数第三位

#include <stdio.h>
int main() {
	int x = 0b1011;
	int y = 0b0100;
	/*模拟一下输出结果
	  0b1011
	| 0b0100
	---------
	  0b1111
	*/
	printf("%d %d\n", (x | y), 0b1111);//如果这两个的结果相同则证明我们的模拟正确
	return 0;
}

 

2-2位或运算符应用2——置空标记位,即把特定位的1变成0,如果原来是0则不变

#include <stdio.h>
int main() {
	int x = 0b1101;
	int y = 0b0100;
	//下面我们把从低往高数第三位进行置空,变成0
	//这里好像只要x-y即可,我们输出一下
	printf("%d %d\n", (x - y), 0b1001);
	printf("%d %d\n", (x | y) - y, 0b1001);
	
	//但如果本身第三位就是0呢?这种方法显然不具有普适性
	int m = 0b1001;
	int n = 0b0100;
	//所以第一步 我们先让m与n位或 使第三位不管是0或1都变成1 m|n=0b1101
	//第二步位或以后再与n相减 (m|n)-n=0b1001
	//上面x,y我们同样可以用此方法试验一下
	printf("%d %d\n", (m | n) - n, 0b1001);
	return 0;
}

 

2-3位或运算符应用3——低位连续的0变成1 

#include <stdio.h>
int main() {
	int x = 0b11001100000;
	//先让x-1把后面的0都变成1,但是第六位的1因为借位变成了0
	//  x-1=0b11001011111
	//在让x和x-1位或 
 // x|(x-1)=0b11001111111
	// 前7位x与(x-1)相同,位或了也相同 后面全部变成了1,达到了效果
	printf("%d %d\n", x | (x - 1), 0b11001111111);
	return 0;
}

 

5-7-3异或运算符

 1-1基本原则

异或 ^
写法:a^b
读法:a异或b
基本原则:
两个相同的数(0和0,1和1)异或,结果都为0
两个不同的数(0和1,1和0)异或,结果都为1
任何一个数和0异或,结果是它本身
异或满足交换律和结合律

 1-2基本原则演示

#include <stdio.h>
int main() {
    int x = 0b1010;
    int y = 0b1101;
    /*模拟一下
        0b1010
        0b1101
    ^
       ---------
        0b0111
    */
    printf("%d %d\n", (x ^ y), 0b0111);
    return 0;
}

 

2-1异或运算符应用1——标记位取反

#include <stdio.h>
int main() {
	int x = 0b1010;
	int y = 0b1101;
	//假设我们现在要让x的从低往高数第三位取反
//可以异或上0b0100
//结果是    0b1110
	int a = 0b0100;
	printf("%d %d\n", x ^ a, 0b1110);
//我们同样可以让y异或上a达到从低往高数第三位取反的目的 y第三位取反0b1001
	printf("%d %d\n", (y ^ a), 0b1001);
	return 0;
}

 

 2-2异或运算符应用2——变量交换

先回顾利用逗号运算符实现变量交换
#include <stdio.h>
int main() {
//我们先来回顾一下之前讲过的利用逗号运算符实现变量的交换
	int a = 1, b = 2,r;
	r = a, a = b, b = r;
	printf("a = %d b = %d\n", a, b);
	return 0;
}

 

 下面利用异或运算符 优点:只需要两个变量
#include <stdio.h>
int main() {
	int x = 1, y = 2;
	x = x ^ y; //x1 = x ^ y
	y = x ^ y;// y1 = x1 ^ y = (x ^ y)^y = x^(y ^ y)= x ^ 0 = x 
	x = x ^ y;//  x = x1 ^ y1 = (x ^ y)^x=(x ^ x)^y=0^y = y
	//自此实现变量的交换
	printf("%d %d\n", x, y);
	return 0;
}

 

 5-7-4按位取反运算符

 1-1写法读法

按位取反 ~
~x 读作对a按位取反

1-2利用-1巧妙解释补码的概念 

2-1按位取反的应用1——1的按位取反 

#include <stdio.h>
int main() {
	int a = 0b1;//1的按位取反是-2
//  00000000 00000000 00000000 00000001
//~ 11111111 11111111 11111111 11111110 -2
	printf("%d\n", ~a);
	return 0;
}

 

2-2按位取反的应用2——0的按位取反 

#include <stdio.h>
int main() {
	int a = 0b0;
	printf("%d\n", ~a);
	return 0;
}

补充 

 

2-3按位取反的应用3——求一个数的相反数

方法1:一个数加负号就是它的相反数
方法2:
x=0b0; ~x=11111111 11111111 11111111 11111111 也就是十进制里的-1
所以x + ~x = 11111111 11111111 11111111 11111111   也就是用unsigned int里的2`32-1 也就是十进制里的-1
所以x + ~x = -1
-x=~x+1
这样就表示出了x的相反数

 

 5-7-5左移运算符

 1-1基本原则

左移运算符 <<
x<<y 读作 将x左移y位 其中x和y都是整数
下面是左移3位的演示
0b1110 ——> 0b1110000

1-2基本原则的演示 

2左移的十进制含义 

x<<1 ——> x*2
x<<2 ——> x*4
x<<3 ——> x*8
x<<y ——> x*2`y 2的y次
重要结论
1<<y ——> 1左移y位是2的y次
10 ——> 可以看成1左移1位 2`1=2
100 ——> 可以看成1左移2位 2`2=4
以此类推

3-1负数的左移 

 3-2左移负数位,也就是y位负数的情况,同时左移一个很大的数也不行,即y很大

这样做和上面一样 都是未定义行为,也就是c标准里没有规定的行为,不合法,务必避免这样瞎搞

 

 4-1左移运算符的应用——配合其他位运算符,对标记位进行操作

其中左移运算符用于生成标记位

我们都知道位与,位或,异或只能对固定的位进行操作

引入左移运算符,可以利用y对任意一位进行操作,只需要scanf一个y即可

具体演示见下面

下面我们来说明一下
printf("%d %d\n", x & (1 << y), 0b00100);
printf("%d %d\n", x | (1 << y), 0b10110);
printf("%d %d\n", x ^ (1 << y), 0b10010);
首先这样写是为了看看我们在上面注释里演示的结果和最后输出的结果一样吗 

 

 

 5-7-6右移运算符

 1-1基本原则

右移运算符 >>
a>>y 读作:a右移y位
a=0b1110 y=2 a>>y输出的是0b11 也就是去掉最后两位

1-2基本原则演示 

1-3右移运算符的十进制含义 

 x>>1 --> x/2`1
 x>>2 --> x/2`2
 x>>y --> x/2`y

2-1负数的右移位 

2-2移负数位,是不合法的,不能用

3-1右移运算符的应用——去掉k位

相关文章:

  • sklearn中的决策树-分类树:实例-分类树在合成数据集上的表现
  • NVIDIA DLI引领创新课程:基于提示工程的LLM应用开发探索
  • Bybit最大资金盗窃事件技术分析 by CertiK
  • 递归(典型算法思想)—— OJ例题算法解析思路
  • R-INLA实现绿地与狐狸寄生虫数据空间建模:含BYM、SPDE模型及PC先验应用可视化...
  • Java使用EasyExcel实现异步导出
  • JavaScript web APIs第一天——04-code——06-随机抽奖案例.html
  • 爱普生汽车用显示控制器IC:ScalerIC,汽车接口IC,相机接口IC
  • 如何使用tushare pro获取股票数据——附爬虫代码以及tushare积分获取方式
  • 编写一个程序,输入一个字符串并输出其长度(Python版)
  • 网络安全 机器学习算法 计算机网络安全机制
  • MySQL高阶操作的详细步骤说明,结合了索引优化、事务管理、存储过程、触发器等核心功能
  • Spring源码分析の循环依赖
  • 如何通过提示词更好地利用AI
  • A Large Recurrent Action Model: xLSTM Enables Fast Inference for Robotics Tasks
  • 基于C++“简单且有效”的“数据库连接池”
  • C++之vector和list辨析
  • 是德科技keysight N5173B信号发生器,是一款经济高效的仪器
  • MongoDB 数据库简介
  • nnUNet V2代码——nnUNetv2_train命令
  • 福建泉州曾明军的网站/信息检索关键词提取方法
  • 西安网站制作开发/著名的营销成功的案例
  • 建站之星导出网站/北京seo
  • 如何做网站动态图标/高清免费观看电视网站
  • 柘城县网站建设/关键词优化排名工具
  • 石岩附近做网站公司/好用搜索引擎排名