惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy & Cybersecurity Law Blog
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
Netflix TechBlog - Medium
罗磊的独立博客
F
Fortinet All Blogs
T
Threatpost
Y
Y Combinator Blog
博客园_首页
美团技术团队
Security Latest
Security Latest
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog
V
V2EX - 技术
The Cloudflare Blog
L
LINUX DO - 热门话题
博客园 - 司徒正美
Jina AI
Jina AI
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
The Hacker News
The Hacker News
P
Privacy International News Feed
T
The Exploit Database - CXSecurity.com
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
M
MIT News - Artificial intelligence
Latest news
Latest news
NISL@THU
NISL@THU
Google DeepMind News
Google DeepMind News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
雷峰网
雷峰网
Application and Cybersecurity Blog
Application and Cybersecurity Blog
B
Blog RSS Feed
W
WeLiveSecurity
D
DataBreaches.Net
G
Google Developers Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
GRAHAM CLULEY
Spread Privacy
Spread Privacy
Know Your Adversary
Know Your Adversary
TaoSecurity Blog
TaoSecurity Blog
S
Securelist
Help Net Security
Help Net Security

博客园 - abatei

AT指令之 TCP/IP 命令 使用 AT 指令进行 Socket 通信 使用 Visual Studio Code 进行远程开发 QR 码详解(下) QR 码详解(上) Contiki学习笔记  第一个程序:Hello World contiki学习笔记---process结构体 用Silverlight打造位运算器(3)--完成 用Silverlight打造位运算器(2)--制作数字文本框控件 用Silverlight打造位运算器(1)--制作简易工具条控件 C#与数据结构--哈希表(Hashtable) 《数据结构(C#语言描述)》目录 C#与数据结构--树论--红黑树(Red Black Tree) Silverlight版拼图游戏 C#与数据结构--树论--平衡二叉树(AVL Tree) 二叉树遍历非递归算法视频 新书预告---《数据结构--C#语言描述》 C#与数据结构--图的遍历 C#与数据结构--二叉树的遍历
位标志
abatei · 2008-05-03 · via 博客园 - abatei
 

由于有读者对《C#程序设计基础教程与实训》214页的那个例子无法理解,所以专门写一篇文章对位标志进行讲解,希望可以对初学者有一些帮助。要理解这篇文章,首先要知道什么是位运算,什么是二进制,这些是计算机一级的内容,我不打算在这里讲解。如果有不懂的请上网用Google了解或查找相关书籍了解,写这篇文章的目的在于让你知道为什么要使用位运算,使用它会带来什么好处。

我们首先从一个问题着手:如果你正在编写一个课程管理系统,你会以什么样的形式来表示你今天哪些节有课哪些节没课呢?比如一天有12节课,如下图所示

可能大家会问,为什么只是记录哪些节有课,哪些节没课呢?这样的信息有什么作用呢?当然有用,比如你要查找某同学今天上午12节是否有课,又比如在排课系统中,把某门课排到星期二下午67节,首先就要确定这两节课是否已经分配给了其他课程。。。。。。

我想大部分人最初能想到的就是使用一个bool数组来表示它(这大部分人当中当然也包括我自己),使用代码来表示就是下面这个样子:

bool[] arrCourse = new bool[13];

arrCourse[5]=true;

arrCourse[6]=true;

好!恭喜你,有了一个很不错的开始,很好地完成了任务,以上代码执行完的结果如下图所示:

在数组中,当元素值为T时,表明这一节有课,为F时,表明这一节没课。现在感觉相当良好,现在可以开始排课了。比如我们现在需要在某天排入某门课,这一天现在的课程状态如下图所示:

如果我们要把这门课排到第12节,就需要做出如下判断

if(arrCourse[0]==false && arrCourse[1]==false)

如果我们需要把排到123节,就需要做出如下判断

if(arrCourse[0]==false && arrCourse[1]==false && arrCourse[2]==false)

如果需要把课排到1~5节或1~13节。。。!现在有点晕了,怎么这么麻烦啊!当然,你要是真的这么写程序那就是真的有点麻烦了,这样的判断应该借助循环。但无论怎么样,判断的次数是不能减少的,这样的数据结构也不能让人满意。是否有更好的解决方案呢?

好!我们尝试把F变为0T变为1,看看效果怎么样:

这幅图表示的不是一个二进制数吗?用计算器来转换一下,它就是十进制的902。哈哈!真是天才的想法,用一个整数就可以表示这一天的上课状态了。现在我要把新课排在12节只需要把902跟二进制的(110000000000)也就是十进制的3072进行“与”运算(902 & 3072)就OK了,结果为0,表明可以排进去,结果不为0表明12节至少有一节已排入其他课了。

如果要排入的是下午67节,只需跟二进制(000001100000)也就是十进制的96进行“与”运算。现在不再需要进行多次判断,只需一次运算,判断结果是否为0就解决了所有问题。

现在大家应该明白位运算有多好了吧!Windows中存在着大量的位标志,如果曾经使用Windows API进行编程应该对此有很深的体会。举个例子:假设Windows字体存在以下几种样式:加粗,斜体,下划线。一个字体即可以同时拥有以上三种样式,也可以只拥有一种样式,或拥有其中任意两种样式,或者干脆一种都没有。如何表示字体的样式呢?当然最佳的方案就是使用位标志。如用第一个位表示字体是否加精,第二、三个位分别表示是否是斜体和下划线,如下图所示:

当位标志为:010------(十进制的2)时,表示这个字体只有斜体这种样式

当位标志为:011------(十进制的3)时,表示这个字体为粗体,同时又是斜体

。。。。。。。

所以当你要把某行字变为粗体时,只需让它跟二进制的(001)进行“或”运算就行了

把某行字变为斜体时,只需让它跟二进制的(010)进行“或”运算

把某行字变为带下划线时,只需让它跟二进制的(100)进行“或”运算

如果要把粗体去掉呢?只需把001求补变为110,然后跟位标志进行“与”运算就行了

把某行字的斜体去掉,只需把010求补变为101,然后跟位标志进行“与”运算就行了

把某行字的下划线去掉,只需把100求补变为011,然后跟位标志进行“与”运算就行了

好,现在你应该理解了课本216页的那些古怪代码了吧!当然,字体样式不止这些,加粗是否放在第一个位我也不知道,但道理就是这样的。如果还不明白,请先把位运算学好了再来看这篇文章。课本的第四章也对几个位运算符&,|,~做了详细的讲解。