初始C语言——详细讲解操作符以及操作符的易错点
系列文章目录
第一章 “C“浒传——初识C语言(更适合初学者体质哦!)
第二章 详细认识分支语句和循环语句以及他们的易错点
第三章 初阶C语言——特别详细地介绍函数
第四章 初始C语言——详细地讲解数组的内容以及易错点
第五章 初始C语言——详细讲解操作符以及操作符的易错点
目录
系列文章目录
前言
一、操作符分类
二、算术操作符(两个操作数)
三、移位操作符(两个操作数)
3.1 左移操作符 <<
3.2 右移操作符 >>
3.3 警告
四、位操作符(两个操作数)
4.1 按位与 &
按位与的具体应用:
4.2 按位或 |
4.3 按位异或 ^
按位异或的具体应用:
4.4 有关二进制位的练习
五、赋值操作符
复合赋值符
六、单目操作符(一个操作数)
6.1 单目操作符介绍
6.2 逻辑反操作符 !
6.3 取地址操作符 & 和解引用操作符 *
6.4 计算操作数的类型长度 sizeof
6.5 ++ 和 -- 操作符
七、关系操作符(两个操作符)
八、逻辑操作符(两个操作符)
8.1 逻辑与操作符 &&
8.2 逻辑或操作符 ||
8.3 逻辑短路
九、条件操作符(三目操作符)
十、逗号表达式
十一、下标引用、函数调用和结构成员
11.1 [ ]下标引用操作符(两个操作数)
11.2 ( )函数调用操作符(至少一个操作数)
11.3 访问一个结构的成员
总结
前言
在上一章内,小编带领大家详细地学习了有关数组的相关内容,学习了一维数组和二维数组的创建与初始化,一维数组和二维数组在内存中如何存储,数组越界,数组作为函数参数怎么办?
而在这一章内,小编将要带领大家进行学习操作符的内容,大家从目录也不难看出这章内容也是很多,已经囊括了所有操作符,希望大家也能有耐心地将这一章看完。
一、操作符分类
为什么要学习操作符?是为了进行表达式求值。在学习操作符之前,先跟着小编进行学习操作符的分类吧!
- 算术操作符:+、-、*、/、%
- 移位操作符:<<、>>
- 位操作符:&、|、^
- 赋值操作符:=、+=、-=、/=、*=、%=……
- 单目操作符:!、-、+、sizeof、~、(类型)
- 关系操作符:>、<、>=、<=、!=、==
- 逻辑操作符:&&、||
- 条件操作符:exp1?exp2:exp3
- 逗号表达式:exp1,exp2,exp3,……expN
- 下标引用、函数调用和结构成员:[ ]、()、.、->
二、算术操作符(两个操作数)
在这一部分,小编认为没什么可以讲的,但是这篇博客是详细讲解操作符,所以还是要讲解一下易错点吧!算术操作符,顾名思义就是数学上的一些运算:+、-、*、/、%。+、-、*这三个运算符没有什么可以讲的,接下来,小编重点讲解:/、%。
- 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
- 对于 / 操作符,如果两个操作数都为整数,执行整数除法。而两个数中只要有浮点数执行的就是浮点数除法。
- % 操作符的两个操作数必须为整数,返回的是整除之后的余数。
三、移位操作符(两个操作数)
小编在讲之前先提一嘴,移位操作符移动的是二进制的位。在这里,我们先来讲一下C语言的二进制。
对于一个整数来说是四个字节,也就是==32bit位。一个整数写成二进制序列的时候,就是32个bit位。下面看图理解:
1)对于有符号的整数来说,最高位的一位是符号位:符号位是1,表示负数;符号位是0,表示正数。
2)对于无符号整数来说,没有符号位,所有位都是有效位。
整数的二进制表示形式有三种:原码、反码、补码。
原码:按照数值的正负,直接写出的二进制序列就是原码。
反码:原码的符号位不变,其他位按位取反。
补码:反码的二进制 +1 就是补码。
从例子中,我们可以看出对于正的整数原码,反码,补码是相同的,无需计算;对于负的整数原码,反码,补码是需要进行计算的。
整数在内存中存放的都是补码,整数在计算的时候也是用二进制进行计算。
3.1 左移操作符 <<
移位规则:左边抛弃,右边补0。
在常规的数字里面是不会出现特殊情况的,一般地,在效果上,左移一位相当于乘2。对于正数来说,还是对于负数来说,其实都一样,只是在一些特别大的数是不一样的,基本都遵循:丢弃符号位,不管左边高位是什么,后面补的数字成为符号位。
下面举个例子:
3.2 右移操作符 >>
小编先说一句:右移操作符比较难。首先右移运算分为两种:1.逻辑右移;2.算术右移。这两种主要的区别是:关键看左边补什么。
移位规则:1.逻辑移位:左边用0填充,右边丢弃;2.算术移位:左边用原该值的符号位填充,右边丢弃。
同样地,在常规的数字里面是不会出现特殊情况的,一般地,在效果上,右移一位相当于除以2。对于正数来说,遵循:丢弃右边一位,左边直接补0。而对于负数来说,有两种情况,所以一般请先了解你所使用的编译器是哪种右移运算,方法在下面。遵循:如果是算术右移:左边用原改制的符号位填充;如果是逻辑右移:左边补0。
下面举个例子:
对于正整数来说,这两种右移操作都一样;而对于负整数来说,这两种右移操作不太一样,所以要重点来看负整数。我们可以根据这个差异,编写一个代码看你们所使用的编译器支持哪种右移操作。vs用的是算术右移,大部分编译器用的都是算术右移。下面看代码:
#include <stdio.h>
int main()
{int a = -10 >> 1;if (a < 0)printf("该编译器用的是算术右移!\n");elseprintf("该编译器用的是逻辑右移!\n");return 0;
}
3.3 警告
对于移位操作符,不要移动负数位,这个是标准未定义的。看下图:
四、位操作符(两个操作数)
在初学C语言时,老师应该是不会讲这一部分的,起码我们老师没有讲,但这一部分是非常重要的, 他在二进制的一些题目中有大作用。但大家不要将位操作符与逻辑操作符搞混!下面,就由小编我来带领大家进行分开学习吧!
4.1 按位与 &
运算规则:同时为1,才为1;一旦有0,则为0。
我们记住这个运算规则后进行计算即可,下面进行代码讲解:
int main()
{int a = 7;int b = -10;int c = a & b;//按二进制的位与//00000000 00000000 00000000 00000111 ----- 7的补码//10000000 00000000 00000000 00001010//11111111 11111111 11111111 11110101//*************************************//*11111111 11111111 11111111 11110110*----- -10的补码//*00000000 00000000 00000000 00000111*----- 7的补码//*************************************//同1为1,有0则0//00000000 00000000 00000000 00000110 ----- 6printf("%d", c);return 0;
}
按位与的具体应用:
如果我想得到某个数的二进制补码上某一位到底是1还是0,我们可以使用按位与运算进行得到。为什么呢?
基本思路是:因为按位与的运算规则是:同1为1,有0则0。假如你想要求某个数的二进制补码上最后一位的数,你只需按位与上1(2^0),则可以得出某个数的二进制补码上最后一位的数是什么,如果按位与上1等于1的话,最后一个数是1,如果是0,则最后一个数是0。同理,如果你想要求某个数的二进制补码上倒数第二位的数,你只需按位与上2(2^1)。
题目一:求某个数的二进制补码上某一位的数是什么?
********************************************************************************************************
方法:由上面的基本思路可以总结出一个公式:如果你想要求某个数的二进制补码上倒数第N位的数,你只需要用某个数按位与上2的(N-1)次方(2^(N-1))即可。
********************************************************************************************************
代码:
int main() {int num = 10;//如果想要求10的二进制补码中最后一位数int ans = num & 1;printf("ans = %d\n", ans);return 0; }
题目二: 求出某一个数的二进制补码的最后一个为1的位置的数。
********************************************************************************************************
方法:
********************************************************************************************************
代码:
int onlyone = eor & (~eor + 1);
4.2 按位或 |
运算规则:同时为0,才为0;一旦有1,则为1。
这种运算是不需要进行讲解的,只要记住运算规则就会做运算,下面进行代码讲解:
int main()
{int a = 7;int b = -10;int c = a | b;//按二进制的位或//00000000 00000000 00000000 00000111 ----- 7的补码//10000000 00000000 00000000 00001010//11111111 11111111 11111111 11110101//*************************************//*11111111 11111111 11111111 11110110*----- -10的补码//*00000000 00000000 00000000 00000111*----- 7的补码//*************************************//同0为0,有1则1// 11111111 11111111 11111111 11110111 补码// 11111111 11111111 11111111 11110110 反码// 10000000 00000000 00000000 00001001 原码 --- -9printf("%d", c);return 0;
}
4.3 按位异或 ^
运算规则:相同为0,不同为1。在这里提两个式子要记住:a ^ a = 0;a ^ 0 = a。
性质:按位运算遵循交换律和结合律。
虽然,按位异或的运算规则比较简单,但是以后还要学习一个按位同或的运算规则:相同为1,不同为0。所以,这两种运算容易搞混。
那怎么记按位异或呢?按位异或——就是无进制相加。怎么理解无进制相加呢?看下图:
int main()
{int a = 7;int b = -10;int c = a ^ b;//按二进制的位异或//00000000 00000000 00000000 00000111 ----- 7的补码//10000000 00000000 00000000 00001010//11111111 11111111 11111111 11110101//*************************************//*11111111 11111111 11111111 11110110*----- -10的补码//*00000000 00000000 00000000 00000111*----- 7的补码//*************************************//相同为0,不同为1// 11111111 11111111 11111111 11110001 补码// 11111111 11111111 11111111 11110000 反码// 10000000 00000000 00000000 00001111 原码 --- -15printf("%d", c);return 0;
}
按位异或的具体应用:
一道很变态的面试题:
题目一:不能创建临时变量(第三个变量),实现两个数的交换。
********************************************************************************************************
方法1:先将a,b两个数进行相加赋给a,然后用a减去b赋给b,这样b中存的就是a,然后再用a减去b(b的值此时是a)赋给a,则a的值就是b的值了。
********************************************************************************************************
代码:
int main() {int a = 10;int b = 90;printf("交换前:a = %d, b = %d\n", a, b);//方法一:a = a + b;b = a - b;a = a - b;printf("交换后:a = %d, b = %d\n", a, b);return 0; }
缺陷:如果变量的值非常大的话,就会出现数据截断。
********************************************************************************************************
方法2:用按位异或,根据a ^ a = 0,a ^ 0 = a,就可以得出。在这个过程中不会产生进位,则数据不会溢出。
********************************************************************************************************
代码:
int main() {int a = 10;int b = 90;printf("交换前:a = %d, b = %d\n", a, b);//方法二:a = a ^ b;b = a ^ b;a = a ^ b;printf("交换后:a = %d, b = %d\n", a, b);return 0; }
缺陷:这个代码可读性不高,效率也不高。
题目二: 给定一个数字arr,其中只有两个数字出现了奇数次,其它数字都出现了偶数次,按照从小到大顺序输出这两个数。
********************************************************************************************************
方法:先将这些数全部异或一下,可以得到出现奇数次的两个数的异或结果赋给eor,说明这两个数一定不相等,而且eor的二进制中一定有一个位置是1,求出此位置为1的数(看4.1 按位与的具体应用),然后将数组里的数分成两个部分,一个部分是此位置为1的数,另一部分是此位置为0的数。那么这两个数就分开了,随便挑一组数据进行异或就可以求出一个数,再用eor异或就求出了另一个数。
********************************************************************************************************
代码:
#include <stdio.h> int main() {int n = 0;int eor = 0, eor1 = 0;int temp = 0, ans = 0;scanf("%d", &n);int arr[100000];for(int i = 0; i < n; i++){scanf("%d", &arr[i]);}for(int i = 0; i < n; i++){eor ^= arr[i];}int onlyone = eor & (~eor + 1);for(int i = 0; i < n; i++){if((onlyone & arr[i]) != 0)eor1 ^= arr[i];}ans = eor ^ eor1;if(eor1 > ans){temp = eor1;eor1 = ans;ans = temp;}printf("%d %d\n", eor1, ans);return 0; }
4.4 有关二进制位的练习
题目:编写代码实现:求一个整数存储在内存中的二进制中1的个数。
五、赋值操作符
赋值操作符是一个很棒的操作符,如果之前的值你不满意,使用这个操作符你可以给自己重新赋值。
举个例子:
int weight = 120;//体重 weight = 80;//不满意就赋值 double salary = 100000.0; salary = 200000.0; //使用赋值操作符赋值
赋值操作符可以连续使用,不过要从右向左依次执行。
int a = 10;int x = 0;int y = 20;a = x = y + 1; //连续赋值,可读性不高//改进x = y + 1;a = x;//这样写更加清晰爽朗而且便于调试
复合赋值符
+= -= *= /= %= >>= <<= &= |= ^=
这些运算符都可以写成复合的效果,使代码更加整洁。
举个例子:
int x = 10;x = x + 10;x += 10; //这样写比较整洁
六、单目操作符(一个操作数)
6.1 单目操作符介绍
6.2 逻辑反操作符 !
运算规则:将真的变成假的,将假的变成真的。
下面看使用场景:
int main()
{int a = 0;if(!a)printf("hehe\n");return 0;
}
6.3 取地址操作符 & 和解引用操作符 *
取地址操作符是将一个变量的地址取出来存放在p中,解引用操作符是通过p所存放的地址找到p所指向的对象。
6.4 计算操作数的类型长度 sizeof
int main()
{int a = 10;printf("%d\n", sizeof(a));printf("%d\n", sizeof a); //这种写法是正确的,证明了sizeof不是函数,函数后的括号省略不了printf("%d\n", sizeof(int));return 0;
}
由上图代码可知,sizeof既能计算变量的长度,也能计算类型长度。此代码运行后,为什么会出现下图情况:
因为sizeof计算的结果是size_t类型的,size_t是无符号整形的,对size_t类型的数据进行打印,可以使用%zd。 在一些古老的编译器是不支持%zd的,也可以使用%u。
6.5 ++ 和 -- 操作符
运算规则:前置++(--):先+(-)1,后使用;后置++(--):先使用,后+(-)1。
七、关系操作符(两个操作符)
这些操作符比较简单,没有什么可以讲的,但是我们要注意一些运算符使用时候的陷阱。
警告:在编程的过程中 == 和 = 不小心写错,导致的错误。
八、逻辑操作符(两个操作符)
8.1 逻辑与操作符 &&
运算规则: 逻辑与就是并且,全真为真,有假即假。
区分逻辑与和按位与
1 & 2 -------->0
1 && 2 -------->1
8.2 逻辑或操作符 ||
运算规则:逻辑或就是或者,全假为假,有真即真。
区分逻辑或和按位或
1 | 2 -------->3
1 || 2 ------->1
8.3 逻辑短路
运算规则:&& 左边操作数如果为假,右边的运算式可以不算;|| 右边操作数如果为真,右边的运算式可以不算 。
学到这个操作符后,我突然想到了我同学问我的一道题目:
我刚看到这个题是有疑惑的,因为b和c选项感觉都是错的,其实并不是。因为c选项是涉及一些知识点是我不知道的,因为有逻辑短路,在C语言中,我们进行运算的时候,我们需要进行优化代码,不让这个程序进行超负荷的运算。在程序中,因为,a||(b = c)是这个逻辑运算,为什么会有逻辑短路呢?为了减少程序的计算量,在进行这个逻辑运算的时候,C语言采用了在保持原逻辑运算正确的同时,通过已确定表达式的确切值的情况下,不计算后面的运算来简化运算。
在或运算中,如果a为真,后面的值不管是什么,我们都不需要进行计算,因为程序的结果已经知道了,就应该进行逻辑短路,然后就不计算b = c,所以没有将c赋值给b, b还是等于原值。如果a为假,说明后面的结果可能会影响整个结果,所以就不能进行逻辑短路。
下面有一道笔试题:
题目:
int main() {int i = 0, a = 0, b = 2, c = 3, d = 4;i = a++ && ++b && d++;printf(" a = %d\n b = %d\n c = %d\n d = %d\n", a, b, c, d);return 0; }
答案:
九、条件操作符(三目操作符)
我感觉这个操作符是用来简化代码的,具体看下面代码:
if (a > 5)b = 3;
elseb = -3;
//等价于
b = a > 5 ? 3 : -3;
具体应用:
题目:使用条件表达式实现找两个数中的较大值
方法:利用条件表达式
代码:
int main() {int a = 90, b = 78;int ans = a > b ? a : b;printf("%d\n", ans);return 0; }
十、逗号表达式
运算规则:从左向右依次执行计算,整个表达式的结果是最后一个表达式的结果,前面的计算可能会影响后面的结果。
下面看使用场景:
a = get_val();couny_val(a);while (a > 0){//业务处理a = get_val();couny_val(a);}//如果使用逗号表达式,改写:while (a = get_val(), couny_val(a), a > 0){//业务处理}
十一、下标引用、函数调用和结构成员
11.1 [ ]下标引用操作符(两个操作数)
操作数:一个数组名 + 一个索引值
int arr[10]; //创建数组
arr[9] = 10; //使用下标引用操作符
[ ]的两个操作数是arr和9。
11.2 ( )函数调用操作符(至少一个操作数)
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
11.3 访问一个结构的成员
. 结构体.成员名
-> 结构体指针->成员名
总结
在这一部分,小编详细地编写了有关操作符详解的一篇博客。希望大家看完以后,进行点评,谢谢大家!
相关文章:

初始C语言——详细讲解操作符以及操作符的易错点
系列文章目录 第一章 “C“浒传——初识C语言(更适合初学者体质哦!) 第二章 详细认识分支语句和循环语句以及他们的易错点 第三章 初阶C语言——特别详细地介绍函数 第四章 初始C语言——详细地讲解数组的内容以及易错点 第五章 初始C语言—…...
论文写作常用词句积累
X 连接词 表目的To this end/Toward that endto do soto this aimso as toTo tackle these issuesfor the sake ofaiming to do表转折howeverNevertheless表递进moreverFurthermore表对比on the other hand/On the contraryAlternativelyas in the case ofwhereas表顺序in a f…...

伺服系统::编码器
一、主要分类 二、组成与原理 光电编码器 磁编码器:N-->磁感元件(0);S-->磁感元件(1)》脉冲 增量编码器的分辨率、倍频与细分技术 (99 封私信 / 81 条消息) 编码器有什么分类? - 知乎 (z…...

Git全栈体系(五)
第八章 IDEA 集成 GitHub 一、设置 GitHub 账号 如果出现 401 等情况连接不上的,是因为网络原因,可以使用以下方式连接: 然后去 GitHub 账户上设置 token。 点击生成 token。 复制红框中的字符串到 idea 中。 点击登录。 二、分享工程…...

spring-boot webservice的例子
webservice发布服务 源码下载地址 spring-boot-webservice例子资源-CSDN文库 webservice cilent调用 源码下载地址 spring-boot-clintwebservice调用服务的例子资源-CSDN文库...
第八章 SpringBoot @ConfigurationProperties配置绑定
原始做法:读取到文件内容,再进行bean的绑定 public static void readProperties(String propertiesPath) throws IOException {Properties pps new Properties();pps.load(MainApplication.class.getClassLoader().getResourceAsStream("applicat…...
【SpringBoot】88、SpringBoot中使用Undertow替代Tomcat容器
SpringBoot 中我们既可以使用 Tomcat 作为 Http 服务,也可以用 Undertow 来代替。Undertow 在高并发业务场景中,性能优于 Tomcat。所以,如果我们的系统是高并发请求,不妨使用一下 Undertow,你会发现你的系统性能会得到很大的提升。 1、Tomcat 介绍 Tomcat是一个开源的Ja…...
java8 求和
1.BigDecimal求和 对象字段求和 List<Car> listnew ArrayList<>(); BigDecimal sumOfBigDecimals list.stream().filter(Objects::nonNull).filter(c -> c.getMiles() ! null).map(Car::getMiles).reduce(BigDecimal.ZERO, BigDecimal::add);BigDecimal集合求…...

手眼标定眼在手上
1、为什么要用手眼标定 参考手眼标定特别是眼在手上在网上的文章很多,但很多在实际中调试不通。在定位时候,往往希望相机能返回的是机械的世界坐标,而不是相机的的图像坐标。从而间接计算出相机坐标系与机械坐标世界坐标转换矩阵,…...
【数据结构】初始二叉树
满二叉树 每个结点都有左右子树的二叉树。 完全二叉树 从上到下、从左到右排列,不落下一个结点进行排列的二叉树。 二叉树的性质 第i层最多有2(i-1)个结点深度为k的二叉树最多有 2k-1 个结点因为一颗深度为k的满二叉树的结点有2k-1,即nk-1ÿ…...

创建和使用角色(RHCE)
题目: 创建和使用角色 根据下列要求,在 /home/curtis/ansible/roles 中创建名为 apache 的角色: httpd 软件包已安装,设为在系统启动时启用并启动 防火墙已启用并正在运行,并使用允许访问 Web 服务器的规则 模板文件 i…...
Leetcode 583 两个字符串的删除操作(经典)
【问题描述】 给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 示例 1: 输入: word1 "sea", word2 "eat" 输出: 2 解释: 第一步将 "sea" 变为…...
c#实现工厂模式
可以使用以下代码实现C#中的工厂模式: 首先,定义一个接口作为产品的抽象: public interface IProduct {void Operation(); }然后,创建具体的产品类: public class ConcreteProductA : IProduct {public void Operat…...

c#在设计时调试自定义 Windows 窗体控件
private string demoStringValue null; [Browsable(true)] public string DemoString {get{return this.demoStringValue;}set{demoStringValue value;} } 参考链接 在设计时调试自定义控件 - Windows Forms .NET Framework | Microsoft Learnhttps://learn.microsoft.com/z…...

Ajax 笔记(二)—— Ajax 案例
笔记目录 2. Ajax 综合案例2.1 案例一-图书管理2.1.1 渲染列表2.1.2 新增图书2.1.3 删除图书2.1.4 编辑图书 2.2 案例二-背景图的上传和更换2.2.1 上传2.2.2 更换 2.3 案例三-个人信息设置2.3.1 信息渲染2.3.2 头像修改2.2.3 信息修改2.3.4 提示框 Ajax 笔记: Ajax…...

微信小程序隐私协议模板
在 设置 中找到 用户隐私保护 进行更新,如下图: 具体协议补充可参考如下: 为了分辨用户,开发者将在获取你的明示同意后,收集你的微信昵称、头像 为了显示距离,开发者将在获取你的明示同意后,收…...

Three.js WebXR沉浸式渲染简明教程
在前面文章中,我们了解了 VR 概念以及它们如何在 WebXR 中映射。 这使你可以考虑想要为用户提供的体验。 在本文中,我们将介绍如何将 WebXR 与 Three.JS 结合使用来创建针对大型异构用户群的沉浸式体验。 警告:WebXR API 仍在完善中…...

flask使用cookie (设置cookie与查看cookie内容)
1.flask包cookie的使用 设置cookie app.route(/set_cookie) def set_cookie():resp make_response(Setting cookie)resp.set_cookie(username, John)return resp查看cookie: app.route(/get_cookie) def get_cookie():username request.cookies.get(username)return Welco…...
信息学奥赛一本通——1281:最长上升子序列
文章目录 题目【题目描述】【输入】【输出】【输入样例】【输出样例】 AC代码 题目 【题目描述】 一个数的序列 b i b_i bi,当 b 1 < b 2 < . . . < b S b_1<b_2<...<b_S b1<b2<...<bS的时候,我们称这个序列是上升…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...