你好, 欢迎｡ 让我们来谈谈位运算符｡
我们在上节课讲赋值运算符的时候已经给你们展示过了, 因为赋值运算符有所有这些复合赋值, 你可以执行一个运算,
比如加法,
然后再赋值.
您可以对这些类型运算符执行相同的操作｡
但让我们深入了解这些细节, 并确切地告诉您它们是什么｡
所以c提供了按位逻辑运算符和移位运算符｡
那些术语可能完全不知道｡
它们看起来像逻辑运算符, 但它们有很大的不同｡ 它们不做任何布尔运算｡
他们不会评估真假｡
它们看起来像是&, &, 或者2&, &, &, &, 或者2&, &, &, &,
&, &, &, &, &, &, 但是它们并不进行任何形式的布尔运算｡
它们所做的是, 在整数值中, 对位进行运算｡
所以你可能会问自己, 你到底为什么要这样做？
大多数程序都不使用它｡ 更像是一种高级技术｡
尽管这是一个初级班｡ 它们是运算符的一部分, 而运算符是初学者的概念｡
所以我将对它们进行阐述, 但我们不一定要关注它们｡
我将给予你们一些例子, 告诉你们如何使用它们｡
但这堂课结束后, 你们不会成为这方面的专家.
但它们之所以有用, 也是因为你可以存储相当多的数据｡
这里有位操作数, 叫做and, 和, 还有位或,
它是一个或, 只是一个平行线｡
请不要再将这些与逻辑运算符混淆｡
逻辑运算符有两个, 一个是“与”, 另一个是“与”｡
位运算符只有一个｡ 所以只要一个&或者一个或｡
所以他们要做的就是测试, 他们要设置整数变量中的各个位｡
什么叫念旧？
我们知道位是衡量数据的一种方式｡
但位本质上只是一个0或1值｡
其中8个组成一个字节｡ 所以位是0或1｡
你能做的是一个整数,
记住, 根据你运行的系统, 它可以是8个字节｡
所以你可以打开和关闭每一位｡
当我说开或关的时候, 我是说你可以让它们等于1或0｡
然后你可以用这些片段来告诉你一些事情｡
所以你可以通过用位来表示某种类型的数据来存储大量数据｡
这就是为什么计算机使用1和0中的位以及二进制数来进行运算的原因之一, 因为你可以存储大量的数据｡
这里有一个例子｡ 您可以使用单一整数变数｡
同样, 整数是一个数字, 一个整数代表4到8个字节,
这取决于您运行的系统｡
也就是说, 如果有4个字节, 就意味着有32位｡
有32个0或1的值｡
所以你可以用所有这些位来表示一些东西｡
比如说, 如果你想存储一个人的单个字符, 你可以用1位,
告诉你这个人是男是女,
1等于男, 0等于女｡
你只要把它打开或关闭｡
然后你可以用3位来指定这个人是否会说法语､ 德语或意大利语｡
因此, 1位可以表示法语｡
如果不是10, 那就说明他们不会说法语｡
如果德语是0, 那就意味着他们不会说德语｡
如果是1, 就表示他们会说德语｡ 因此,
通过关闭和打开这些位, 将它们设置为1到0, 可以表示大量数据｡
你可以用另一个数字来记录这个人的工资是否在50, 000或更高｡
如果是1, 那就是真的, 是的｡ 0错误｡
基本上, 我们在这里指定｡
它实际上是4, 但我们实际上指定了5位数据,
不管我们有32位还是64位, 只有5位, 但我们只用了5位, 我们就能代表一个人是男性还是女性,
他们是否会说法语, 德语或意大利语,
或者说这三种语言｡
以及他们是否赚了超过5万美元｡
我们可以用位来表示所有数据｡
而这正是按位运算符派上用场的地方｡
现在我们知道了如何使用位来存储大量不同的数据｡
让我们来谈谈那些二进制数｡
我们知道二进制数就是一个包含1和0的数｡
这就是为什么它是有利的使用｡ 位运算符中的一个整数, 该数可以是任意长度｡
下面是二进制数的例子, 只有0和1｡
你们已经看过了010101101010｡
请记住, 一个字节是8位｡
在大多数平台上, 整数通常为4个字节｡
这取决于体系结构, 但大多数情况下是32位｡
所以你有32个值, 你可以用1和0来表示开或关｡
二进制数, 同样每个二进制数都有一个对应的十进制值,
所以你需要了解如何将二进制转换为十进制｡
这里的例子是1等于1, 1等于0, 1等于2, 1等于3,
这些都是简单的转换｡
同样, 通常它们有更多的位, 1010111｡
将二进制数转换为十进制数的方法是, 用位对应的位来查找字节中的每个位置,
然后使用2的幂｡
因此, 对于每个数字,
您可以使用2的幂将该数字乘以其位置值｡ 然后你把整个项目加起来得到最终的结果｡
所以位置值和一个二进制数是2的幂｡
所以第一个位置的值是2 0, 换句话说,
就是1.
然后第二个位置是2的一次方, 2的2次方是4, 2的3次方是8,
2的4次方是16｡
而你却一遍又一遍地重复着｡ 所以如果你看到一个好的例子, 这就更容易理解了｡
所以这里我们有一个二进制数0 1 1 0 1 0 0 1｡
它的十进制等效值是105｡
转换的方法是从每个位的右侧开始,
然后乘以2的幂, 具体取决于该位是否为0 1｡
所以如果我们从右边开始, 我们有1｡
所以我们说1乘以1, 我们保留1｡ 然后是下一个1,
第二个位置是0乘以2 0｡ 然后0乘以4,
1乘以8, 0乘以16, 1乘以32,
1乘以64, 0乘以28｡
你把所有这些加起来, 得到105｡
这是一种转换方式｡
实际上, 也可以将其从左向右转换, 方法是乘以2,
然后加1或加0, 具体取决于下一位是什么｡
例如, 你也可以从左到右,
从1开始, 因为0不重要｡
从左到右的第二位是1｡
第三位是1乘2加1, 所以是3｡
再乘以2等于3乘以2加0等于6.
6乘2加1, 就是13｡
13乘以2等于26｡
26乘以2等于52乘以2, 也就是104加1｡
所以再乘以2然后加1｡
再举一个例子, 从右到左通常要容易一些｡
这里是10011100.
这个数字会转换成156, 因为你会说, 0乘以1,
0乘以2, 1乘以4,
1乘以8,
1乘以16, 等等, 然后你把它们加在一起, 就是48121628加上128就是156.
再一次, 如果你从左到右, 你乘2加1｡
所以我们从1开始｡
比如说1249, 4乘以2加1,
9乘以2等于18加1等于19乘以2,
38加1等于39乘以2等于78乘以2等于156｡
这是一个如何将二进制转换为十进制的快速演示｡
现在把分贝转换成二进制, 如果你真的感兴趣的话,
我通常会在网上用一个转换｡ 但是你可以用这些二进制数,
来执行位运算, 让我们来看看位运算｡
因此, 这里总结了按位运算符｡
我在网上找到了另一个很好的表, 但是它们看起来和逻辑运算符很相似｡ 但同样, 不要混淆它们｡
所以&号本身就是一个二进制的and运算符｡
如果两个操作数都有一个位, 那么这个操作就是把它复制到结果中.
所以如果两个都是真的, 那么它会复制一点｡
所以如果a和b等于12, 你会得到一个二进制表示｡
所以a和b就是那个数｡
我们将通过一些例子｡
二进制或会复制存在于任一算子中的比特, 因此a或b会复制存在于任一算子中的比特｡
因此, 如果任何一个操作数等于1, 它将复制一位｡
然后是二进制异或, 这是异或｡
如果在1个操作数中设置了该位, 但不是在两个操作数中都设置了该位, 则此操作将复制该位｡
如果你有一个真值, 但只有一个真值,
你用胡萝卜在键盘上表示它, 然后它会复制一个位, 它会说它是真的, 二进制1的补码｡
这里我们用的是二进制数据, 因为我们讨论的是位｡ 希望1是补码｡
运算符是一元的,
具有翻转位的作用, 基本上只是取反和关闭监视器｡
举个例子, 如果你说波浪号a,
你是在应用1s的补码运算符｡
如果它等于-61, 它就是1100001｡
所以如果你把二进制数转换成十进制数,
十进制数是负数, 第一个数是符号｡
所以1告诉你这是一个征兆｡
然后你说12481633, 然后是61,
这就是它的表示方式.
我会举一些具体的例子｡
但基本上, 如果你有一个二进制数, a最初是一个二进制数,
也就是60, 你提供翻转, 基本上它会变成负的61,
也就是1100000000011｡
这是实际设置的变量的结果｡
所以我再次假设a有特定的二进制表示b也有特定的二进制表示｡
所以如果a等于60,
b等于13, 那么把它们按位加起来的结果就是0000 11
00, 也就是12｡
同样, 我将通过这些例子,
但这是试图提供这些不同的二元运算符的一个小的描述｡
小于小于符号将向左移位｡
因此, 左操作数值向左移动白色操作数指定的位数｡
所以如果你做了小于小于2的运算, 而a实际上等于你知道的某个二进制数,
比如, 0 0 1
1 1 1 0 0,
你要把字节移位2｡
所以你要去掉那些0, 它会变成1111, 那些0会一直到最后｡
右移位运算符也是一样｡ 你只是把它们移到右边而不是左边｡
此处使用大于符号｡
所以我马上要把这些都过一遍｡
要了解位运算符的另一个重要内容是如何计算这些a和b值｡
如果是"和& quot a,
那么1和1的结果是什么呢.
如果是或1, 则1也会评估为1｡
但是如果你用"和"来表示and, 那么1和1以及0的结果是0,
false. 我只想在这里提供一个真值表,
它显示了当你使用and, and, and,
or, exclusive, or时的值｡
这里如果你有p0和q0, 这意味着它们都是假的, 你用and, 它会是假的,
因为它们必须都是真的｡
这就是你在第三行看到的｡
如果它们都为真, 那么p和q的值都是1, 真.
如果它们不都是真的, 那就总是假的｡
P或q中只有一个需要为真｡
这就是为什么第1行和第2行等于1, 第3行等于1｡
只有当它们都是假的时候它才是假的｡
然后这个互斥的或至少是其中1个为真, 而且只有1个｡
所以如果p为假, q为真, 它将返回真｡
如果p为真, q为假, 它将返回1｡
这让你知道它是如何被评估的｡
再一次, 很多数学的东西, 但是当我们谈论二进制数字的时候, 这就是我们所谈论的｡
因此, 让我们看一些具体的示例和代码块｡ 希望这能有点帮助｡
这是我们的函数｡ 我将再创建几个变量｡
我将确保它们是未签名的, 尽管这是默认设置｡
所以如果我说unsigned int, 并赋值给60, 它实际上会用二进制表示为0011,
然后是1100｡
如果我创建另一个无符号变量, int, b, 赋值为13,
它实际上会被表示为二进制的0 0
00 1 1 0
1. 您可以在那里进行转换｡
但是我想在这里演示的是当你设置这些二进制数时,
你可以通过使用不同的按位操作数来关闭这些位｡
所以现在我要创建一个整型结果, 我会说它等于0｡
E将保存按位运算的结果｡
操作中｡ 现在如果我说c等于a,
然后应用按位操作数a和b, 现在应该做的是,
如果a等于1, b等于1, 这些位将被打开｡
那么你会期望这个v的结果是什么呢？
你看a的第一位和b的第一位它们都是0.
所以结果会是0因为如果a和b都为真, 它们必须都为真才能是1｡
所以下一个也是0｡ 下一个是1和0, 第三位｡
所以还是0, 1, 0还是0｡ 现在我们有一个1和一个1｡
所以现在我们终于有了一个真正的｡ 我们还有一对一｡ 我们有一个真正的｡
然后0和0会变成0然后0和1会变成0｡
所以如果我试着打印出c, 它会打印出十进制格式的值｡
如果我做这样的操作, 它会打印出二进制数的十进制等价物, 也就是0 0
0 0｡
这些都是二进制到十进制的转换, 所以你需要知道如何去做,
才能理解这个例子｡ 但是0 0 0
0 1 1 0 0实际上是1 3 7,
这个值实际上是12, 1 3 6 12｡
所以如果我打印出c的话, 这会打印出12个,
或者结果会更好｡
如果我运行这个程序, 你会看到值是12｡
它实际上根据与号的比较关闭和打开了所有的位｡
现在我说run, 我们看到值在d12中, 因为它关闭和打开位, 它实际上将被表示为0 0
0
1 1 0
0, 也就是值12, 因为我们打印出的是十进制｡
如果我改变了这个,
我现在想做一个或, 我仍然在做, 或者记住,
是回车旁边的平行线, 现在我只会在1为真的时候打开位｡
所以00, 这两个都是假的｡ 再一次, 我在这里比较｡
我在比较16和13的这些位｡
16表示为二进制0 0 1 1 1 0 0｡
13是用二进制表示的0 0 0 0 1 1 0是1｡
每个数字代表一个位｡
所以60的第一位是0, 13的第一位是0｡
如果我把它们放在一起, 0和0, 我还是会得到0｡ 这是第一位的第一个结果｡
第二位又是00｡ 第三位是1代表60, 0代表13｡
这就意味着我必须有一个真值所以这就是一个1.
同样适用于位号4和16､ 13｡ 所以现在我又有了1｡
然后是1和1, 它们都是真的｡ 所以再一次,
我只需要一个真值, 另一个1｡
都是假的所以这不可能是真的｡ 0,
记为不真, 1记为真, 0记为11｡ 所以现在我有0 0 1 1 1 1 0 1｡
如果我把它打印出来, 十进制的值是, 你必须知道如何把二进制转换成十进制,
但它基本上是, 1, 3,
7, 15, 30,
61｡ 所以这将打印出61｡
结束这个程序并重建它, 我们将看到值61｡
这就是位运算符｡
这是一种更高级的程序, 但它是一种很好的方法来表示大量的数据,
通过使用&等, 通过打开和关闭位,
本质上｡ 所以你可以玩这个｡
你可以做独家报道, 或者是胡萝卜｡
胡萝卜在键盘上的数字6上面｡
你会看到不同的结果｡ 如果你加一个波浪号, 这基本上就是把所有的东西都关掉了｡
所以对于a和a等于60, 0 0 1 1 1 1 0 0,
它不会等于1 1 0 0 0 1 1｡
另一个很酷的二进制运算符是移位, 左移和右移｡
当你需要左移或右移时, 有几件关键的事情你知道｡
首先, 我们知道无符号整型意味着只能是正数｡
不可能是负数｡
所以如果你在里面存储了一个负值, 编译器会把它转换成更长的值, 它会占用很大的空间｡
记住无符号整型意味着只能取正值｡
有符号整数意味着它们可以是负的或正的｡
但是如果你想移位, 记住要左移, 现在如果我们说result等于, 假设我们想把a,
比如说, 移位2, 另一个重要的事情你想知道的是,
当你有整数的时候, 整数是, 记住,
在大多数平台上是4个字节｡
这取决于你可以通过做大小运算得到的大小｡
所以整数4实际上是32位, 所以这个数实际上是这样的｡
16个像这样的是什么4 8 12 16 20 24｡
所以你可能会这样或那样｡
确实是这个数字｡
我只显示了最后8位, 因为其余的都是0｡ 但是如果你把它看作是一个32位整数, 也就是4个字节, 这就是它在二进制中的样子,
4 0s 4 0s 4 0s
4 0s 4 0s 4 0s然后是0 0
1 1 1 1 0 0｡
所以当你向左或向右移动时,
你必须知道它的大小, 因为如果你移动超过2次, 它就不清楚了｡
它不会掉下来或类似的东西｡
我再确认一下48, 12, 16, 20, 24,
28, 32, 13也一样.
所以如果你把大于2的数向左移, 你最终会得到这些1也会向左移｡
所以结果仍然是前面所有的0, 但是你会得到11110000｡
这将等于240｡
如果我做一个快速的转换, 我会在脑海里说, 1, 3,
7, 15, 30,
60, 122, 40, 但是我们可以通过构建和运行来确认,
你会看到结果是240｡
我们看到结果是240｡
现在如果你想移位到大于2的数,
比如说你想移位4, 这时就需要明白这是一个32位的数｡
所以在这里你实际上必须使用一些0｡
所以如果你想移动4, 你会得到这样的结果｡
如果你想把它们分成4组, 你会得到这样的结果｡
如果我在脑子里这么做的话, 结果是, 1, 3, 7,
15, 30, 60, 120, 240,
480, 然后是960
希望我做对了｡ 当我们运行这个函数的时候,
我们说960, 所以它向左移动｡
如果要向右移动, 请使用大于号｡
所以右移到二进制右移运算符, 你做的是大于｡
二进制左移运算符, 执行小于｡
所以如果你要向右移动, 你要向右移动4｡
如果你在这里结束会发生什么, 如果你有你原来的60,
你试着去4｡ 你的手指会掉下来｡
因此, 我们没有最后4个,
而最初我们有60个｡
所以我们有000111100, 我们必须移动4｡
所以我们最终会丢失2位, 因为它们会下降｡
我们最终得到的结果是这样的0 0｡
所以它等于3, 就像这样, 因为向右移位太多, 实际上会丢失位,
结果是3｡
所以当你左移和右移的时候要小心,
确保你根据你的系统再次使用那些32位4字节｡
这是位运算符的快速摘要｡
当你更高级的时候, 你必须了解如何实际检查一个特定的位是1还是0｡
这很简单｡ 你只要在上面做个和就行了｡
但是你必须写更多的代码｡
本讲座并不打算详尽地介绍位运算符｡
我想给予你一个概述, 给你一个好的开始｡
但是为了更好地理解这些运算符, 你必须学习更多的知识, 使用它们, 练习它们｡
所以我希望这对你有帮助｡ 同样,
它可能会变得有点混乱, 所以你想跟随它, 你想玩它｡ 但是, 最好的学习方法是什么, 写一些代码,
学习一些例子｡ -谢谢—谢谢