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赋值给变量aprintf("%d\n",a);return 0;
}

 

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

 

1-3把计算结果赋值给变量 
#include <stdio.h>
int main() {int a, b;a = 6;b = a;     //把变量a的值赋值给变量b        b=6a = a + b; //把a+b的计算结果赋值给a       a=12printf("%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=6a -= b;printf("%d %d\n", a, b);  //a=6  b=6a *= b;printf("%d %d\n", a, b);  //a=36 b=6a /= b;printf("%d %d\n", a, b);  //a=6 b=6a %= b;printf("%d %d\n", a, b);  //a=0 b=6  a是6除以6后得到的余数 也就是0return 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的值,也就是2return 0;
}

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

#include <stdio.h>
int main() {int a = 1, b = 2, r;r = a;//把a的值1转移给r 现在r=1 a=1a = b;//把b的值2转移给a 现在a=2 b=2b = r;//把r的值1转移给b 现在b=1 r=1printf("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 其十进制数是10int y = 0b0110;//定义二进制数0110 其十进制数是6//1010(为了方便下面的计算这里高位要补0与上面的1010对齐)printf("%d\n", (x & y));//我们来列个竖式看看最终会输出什么结果/*利用前面讲的位与的基本原则 0或1,位于上1,结果都是它本身0或1,位与上0,结果都是00b1010&  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 = 0b101100000printf("%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
//结果是    0b1110int a = 0b0100;printf("%d %d\n", x ^ a, 0b1110);
//我们同样可以让y异或上a达到从低往高数第三位取反的目的 y第三位取反0b1001printf("%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 ^ yy = 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 -2printf("%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位

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/70824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu:换源安装docker-ce和docker-compose

更新apt源 apt换源&#xff1a;ubuntu&#xff1a;更新阿里云apt源-CSDN博客 安装docker-ce 1、更新软件源 sudo apt update2、安装基本软件 sudo apt-get install apt-transport-https ca-certificates curl software-properties-common lrzsz -y3、指定使用阿里云镜像 su…

0—QT ui界面一览

2025.2.26&#xff0c;感谢gpt4 1.控件盒子 1. Layouts&#xff08;布局&#xff09; 布局控件用于组织界面上的控件&#xff0c;确保它们的位置和排列方式合理。 Vertical Layout&#xff08;垂直布局&#xff09; &#xff1a;将控件按垂直方向排列。 建议&#xff1a;适…

Apache Doris 索引的全面剖析与使用指南

搞大数据开发的都知道&#xff0c;想要在海量数据里快速查数据&#xff0c;就像在星图里找一颗特定的星星&#xff0c;贼费劲。不过别慌&#xff0c;数据库索引就是咱们的 “定位神器”&#xff0c;能让查询效率直接起飞&#xff01;就拿 Apache Doris 这个超火的分析型数据库来…

docker file中ADD命令的介绍

在 Docker 的世界里&#xff0c;Dockerfile 是一个用于定义镜像内容和行为的脚本文件。其中&#xff0c;ADD 指令是 Dockerfile 中一个非常重要的命令&#xff0c;用于将文件或目录从主机文件系统复制到容器的文件系统中。本文将详细介绍 ADD 指令的作用、使用方式以及一些最佳…

从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?

本文首发&#xff1a;从零到一&#xff1a;如何用阿里云百炼和火山引擎搭建专属 AI 助手&#xff08;DeepSeek&#xff09;&#xff1f; 阿里云百炼和火山引擎都推出了免费的 DeepSeek 模型体验额度&#xff0c;今天我和大家一起搭建一个本地的专属 AI 助手。  阿里云百炼为 …

cpp中的继承

一、继承概念 在cpp中&#xff0c;封装、继承、多态是面向对象的三大特性。这里的继承就是允许已经存在的类&#xff08;也就是基类&#xff09;的基础上创建新类&#xff08;派生类或者子类&#xff09;&#xff0c;从而实现代码的复用。 如上图所示&#xff0c;Person是基类&…

【QT】QLinearGradient 线性渐变类简单使用教程

目录 0.简介 1&#xff09;qtDesigner中 2&#xff09;实际执行 1.功能详述 3.举一反三的样式 0.简介 QLinearGradient 是 Qt 框架中的一个类&#xff0c;用于定义线性渐变效果&#xff08;通过样式表设置&#xff09;。它可以用来填充形状、背景或其他图形元素&#xff0…

前端项目配置 Nginx 全攻略

在前端开发中&#xff0c;项目开发完成后&#xff0c;如何高效、稳定地将其部署到生产环境是至关重要的一步。Nginx 作为一款轻量级、高性能的 Web 服务器和反向代理服务器&#xff0c;凭借其出色的性能和丰富的功能&#xff0c;成为了前端项目部署的首选方案。本文将详细介绍在…

网络安全学习-常见web漏洞的渗xxx透以及防护方法

渗XX透测试 弱口令漏洞 漏洞描述 目标网站管理入口&#xff08;或数据库等组件的外部连接&#xff09;使用了容易被猜测的简单字符口令、或者是默认系统账号口令。 渗XX透测试 如果不存在验证码&#xff0c;则直接使用相对应的弱口令字典使用burpsuite 进行爆破如果存在验证…

网络安全 机器学习算法 计算机网络安全机制

&#xff08;一&#xff09;网络操作系统 安全 网络操作系统安全是整个网络系统安全的基础。操作系统安全机制主要包括访问控制和隔离控制。 访问控制系统一般包括主体、客体和安全访问政策 访问控制类型&#xff1a; 自主访问控制强制访问控制 访问控制措施&#xff1a; 入…

2025网络安全等级测评报告,信息安全风险评估报告(Word模板)

一、概述 1.1工作方法 1.2评估依据 1.3评估范围 1.4评估方法 1.5基本信息 二、资产分析 2.1 信息资产识别概述 2.2 信息资产识别 三、评估说明 3.1无线网络安全检查项目评估 3.2无线网络与系统安全评估 3.3 ip管理与补丁管理 3.4防火墙 四、威胁细类分析 4.1威胁…

Ubuntu22.04系统安装Anaconda、CUDA和CUDNN

之前一直在Windows系统下使用Anaconda和CUDA加速&#xff0c;最近需要复现一个算法&#xff0c;文档里面有Linux系统conda构建环境的教程。 本篇博文参考博文&#xff0c;记录自己安装的过程&#xff0c;便于以后需要。 目录 1.Anaconda1.1 安装包下载1.2 安装软件1.3 更新cond…

微信小程序调用火山方舟(字节跳动火山引擎)中的DeepSeek大模型

一、注册火山引擎账号&#xff0c;创建API Key和model&#xff08;接入点ID&#xff09; 1.注册并登陆火山引擎账号&#xff0c;网址为&#xff1a;https://console.volcengine.com/ 2.根据登陆后的页面提示进行实名认证&#xff0c;实名认证后才能创建API Keyt和创建接入点。…

蓝桥杯之日期题

文章目录 1.蓝桥杯必备知识点2. 题型13.需求2 1.蓝桥杯必备知识点 蓝桥杯是一个面向全国高校计算机相关专业学生的学科竞赛&#xff0c;涵盖多个赛道&#xff0c;常见的有软件类&#xff08;如 C/C 程序设计、Java 软件开发、Python 程序设计&#xff09;和电子类&#xff08;…

muduo网络库2

Muduo网络库&#xff1a;底层实质上为Linux的epoll pthread线程池&#xff0c;且依赖boost库。 muduo的网络设计核心为一个线程一个事件循环&#xff0c;有一个main Reactor负载accept连接&#xff0c;然后把连接分发到某个sub Reactor(采用轮询的方式来选择sub Reactor)&…

WinSCP 连接到 Ubuntu 虚拟机

要使用 WinSCP 连接到 Ubuntu 虚拟机&#xff0c;一般采用 SFTP 或 SCP 协议进行文件传输。以下是详细步骤&#xff1a; 1. 确保虚拟机网络可访问 首先&#xff0c;你的 Ubuntu 虚拟机需要允许外部访问&#xff1a; 如果使用 NAT 网络&#xff1a;需要设置端口转发&#xff0…

redis小记

redis小记 下载redis sudo apt-get install redis-server redis基本命令 ubuntu16下的redis没有protected-mode属性&#xff0c;就算sudo启动&#xff0c;也不能往/var/spool/cron/crontabs写计划任务&#xff0c;感觉很安全 #连接到redis redis-cli -h 127.0.0.1 -p 6379 …

Docker核心概念

容器介绍 Docker 是世界领先的软件容器平台&#xff0c;所以想要搞懂 Docker 的概念我们必须先从容器开始说起。 什么是容器? 先来看看容器较为官方的解释 一句话概括容器&#xff1a;容器就是将软件打包成标准化单元&#xff0c;以用于开发、交付和部署。 容器镜像是轻量…

阿里云可观测全面拥抱 OpenTelemetry 社区

作者&#xff1a;古琦 在云计算、微服务、容器化等技术重塑 IT 架构的今天&#xff0c;系统复杂度呈指数级增长。在此背景下&#xff0c;开源可观测性技术已从辅助工具演变为现代 IT 系统的"数字神经系统"&#xff0c;为企业提供故障预警、性能优化和成本治理的全方…

2025年2月科技热点深度解析:AI竞赛、量子突破与开源革命

引言 2025年的科技领域持续呈现爆发式增长&#xff0c;AI大模型竞争白热化、量子计算商业化加速、开源工具生态繁荣成为本月最受关注的议题。本文结合最新行业动态&#xff0c;从技术突破、商业布局到开发者生态&#xff0c;全面解析当前科技热点&#xff0c;为读者提供深度洞…