本帖最后由 群发软件 于 2017-6-13 21:40 编辑
第二节的时候,它是定义的一个整型,然后取位。但是他的那个或运算符号好像写错了,写成了异或符号“^”,应该是“|”。我就突然对二进制的输出感兴趣了。想知道怎样输出二进制。我们知道C++输出十六进制是cout〈〈hex〈〈 a;而八进制是cout〈〈 ocx〈〈 a;二进制则没有默认的输出格式,需要自己写函数进行转换,于是上网搜索了一下。网上思路真是广泛啊。下面列出一些方法。
#include 〈iostream〉
#include 〈list〉
#include 〈bitset〉
using namespace std;
//递归输出二进制函数
void BinaryRecursion(int n)
{
int a;
a=n%2;
n=n〉〉1;
if (n==0)
;
else
BinaryRecursion(n);
cout〈〈a;
}
//使用容器转换二进制
void BinaryVector(int n)
{
int temp;
temp=n;
list〈int〉 L;
while(temp!=0)
{
L.push_front(temp%2);
temp=temp〉〉1;
}
for (list〈int〉::iterator iter=L.begin();iter!=L.end();iter++ )
cout〈〈*iter;
cout〈〈endl;
}
//一般方法,32位,逐步与1做与运算。
void Binarycout(int n)
{
for (int i=31;i〉=0;i--)
{
cout〈〈((n〉〉i)&1);
}
cout〈〈endl;
}
//使用bitset转换二进制
void BinaryBitset(int n)
{
cout〈〈bitset〈sizeof(int)*8〉(n)〈〈endl;
}
int main()
{
int a=1045,b=2;
int c;
c=a+b;
cout〈〈"BinaryRecursion(c):";
BinaryRecursion(c);
cout〈 BinaryVector(c);
cout〈〈"Binarycout(c):";
Binarycout(c);
cout〈〈"BinaryBitset(c):";
BinaryBitset(c);
cout〈〈"BinaryChar(c):";
BinaryChar(c);
//cout〈 return 0;
}
运行后的结果如下:
BinaryRecursion(c):10000010111
BinaryVector(c):10000010111
Binarycout(c):00000000000000000000010000010111
BinaryBitset(c):00000000000000000000010000010111
BinaryChar(c):10000010111
Press any key to continue
从中可以看出,有两种运算会得出32位的结果,不太好。我对C++还不是很精通,所以这个效率还不是很清楚哪个个好。
我觉得用容器的可能会好些吧。如果是C,就用字符转换函数,或者直接除后和1做与运算。
整型字面量
可以用非常直接的方式表示整型字面量。下面是一些例子:
–123 +123 123 22333
其中,前两个例子中的“+”和“–”号是前面提及的一元运算符。在第二个例子中,可以省略“+”,因为这是默认的,但为了使该数值的含义更清晰,加上“+”也不会出问题。字面量+123与123是相同的。第4个例子在一般情况下写为22,333,但在整型字面量中不能使用逗号。如果使用了逗号,编译器就会把该数值当做用逗号分隔开的两个数值。
也不能使用老式的整数值。举一个极端的例子,系统不接受有100位的整数。整型字面量是有上限和下限的,这是由存储每种类型的整数值的内存量决定的。本章在后面介绍整型变量时将讨论这个问题。
当然,可以把整型字面量写成小数值,在计算机中这些值将存储为二进制数值。在编程时理解二进制是非常重要的,为了防止读者对二进制数字的工作方式有误解,下面就简要介绍一下。
二进制数
首先考虑一下在表示常见的十进制数,如324或911,时会做什么。显然,324是表示三百二十四,911表示九百一十一。更明确地说,这两个数表示:
324是:3×102+2×101+4×100,也就是3×10×10+2×10+4
911是:9×102+1×101+1×100,也就是9×10×10+1×10+1
这称为十进制表示法,因为这是建立在10的幂的基础之上(来源于拉丁词decimalis,其含义是什一税,即税的10%)。
以这种方式表示数值非常方便,因为人有10根手指或10根脚趾或者10个任何类型的附属物。但是,这对PC就不太方便了,因为PC主要以开关为基础,即开和关,加起来只有2,而不是10。这就是计算机用基数2来表示数值,而不是用基数10的主要原因。这称为二进制计数系统。数字只能是0或1,当只用开/关来表示数字时,这是很理想的。按照基数为10的计数系统的方法,二进制数1101就可以分解为:
1×23+1×22+0×21+1×20,也就是1×2×2×2+1×2×2+0×2+1
计算得13(十进制系统)。在表2-1中,列出了用8个二进制数字表示的对应的十进制值(二进制数字常常称为位)。
表2-1
注意使用前7位可以表示从0到127的数,一共27个数,使用全部8位可以表示256(即28)个数。一般情况下,如果有n位,就可以表示2n个整数,其值从0到2n-1。
在计算机中,二进制数相加是非常容易的,因为对应数字加起来的进位只能是0或1,所以处理过程会非常简单。图2-1中的例子演示了两个8位二进制数相加的过程。
计算机中所有的数据都是用0和1表示的,因为计算机根本表示不出除0和1之外的其它值。但实际上我看们看到计算机中不但能表示各种各样的数值,还能表示文本,表示图像、视频、音乐等。而且除了表示数据还能表示指令,不同的指令组织到一起就是一段程序。
那么计算机内是如何表示这些不同的数据和指令的呢?很简单:编号。拿指令来说,计算机有很多指令,比如加法:ADD;跳转:JUMP等等,怎么区分不同的指令呢? 就是给它们编号呗,编号就是用数嘛,所以如果你去看一个运行的程序的指令,看到的就是数。
再比如文字。每个汉字或每个字母叫做一个字符。比如“人、4、t”。字符的显示其实是计算机把字符的图像画出来的过程。字符的图像提前制作好放在一个表中,要找到字符对应的图像,就得先对字符进行编号,这个编号跟其图像在表中的位置一样,于是跟据字符编号就找了它的图像。其实在内存中,字符就是直接用编号表示的,所以还是一个数。我们都听说过ASC码,就是对256个常用字符进行了编号。代表字符的char型就是一个8位的整数。存放字符图像的表,不就是字体文件吗?
当然其它的东西也是数啊,比如图像是由像素组成的,而每个像素就是一个颜色,颜色是由数表示的,如果是RGB表示的颜色,其每通道占8个字节,一个像素就是由3个字节组成的数表示。
所以计算机技术又叫数字化技术。
那么数据是数,指令也是数,它们之间怎么进行区分呢 ? 你可以发挥一下像想力:把某块内存区指定成代码区,把另一块内存区指定成数据区,那么代码区和数据区的内容虽然看起来都是数,但是计算机却知道代码区的数对应着指令,是指令的编号,是可以执行的,而数据区的数是不可以执行的。
然而,计算机只能表示0和1,但指令有几百个呢,编号的话要编到好几百,字符有几万个呢,要能表示到几万才行,而十亿美元,这个十亿这个数怎么表示呢?
很简单,一个存储单元只能表示0或1吧?那么两个存储单元就能有四种组合00,01,10,11,能表示四个数,分别对应:0,1,2,3 。三个存储单元呢?就能表示2的3次方,8种组合,0到7之间的数。(一个存储单元叫做一个位:bit 。)
所以问题简单了,要表示多大的数都没问题,使用更多的位就行了。但是又有一个问题:位在内存中是连续排列的,如果我们用这三个位来表示一个数,用紧邻的后面6个位表示另一个数,问题是计算机怎么区分这两个数?计算机怎么知道第一个数占三个位,后一个数占8个位呢?
我们在写程序时,需要告诉计算机各个位是怎么组合的,这就是变量类型的作用,比如int a;我们知道a占32个位,char b;我们知道b占8个位。占三个字节的变量是什么类型? 对不起,没有。实际上计算机限于硬件的能力,规定最少也是8个位一起做作为一个访问单位。8个位叫一个字节(byte)。
计算机只认0和1 ,用0和1表示出的数叫做二进制数,但是程序员都是人啊,你给一个变量赋值不可能用二进制方式写数值。还有,赋一个字符给一个变量,我们也不可能每次都查到字符的编号,然后算出这个数的二进制形式。所以为了方便,数值可以用十进制方式表示,字符的话可以直接用字符表示(比如’s’),转成二进制数的复杂过程,就由编译器来承担了。
为啥经常看到十六进制呢?因为十六进制与二进制很容易对应,十六进制的数中,一个数正好对应四个位,比如一看到0xF,就知道是二进制的1111b 。
所谓进制,就是指到了多少需要进位,二进制的话,两数相加到了2就要进位了,所以二进制的10等于十进制的2;10进制的10就等于10进制的10;而16进制的10等于10进制的16 。
计算机中为什么只能表示0和1呢?这个嘛,只是证明了阴阳理论的正确性,呵呵。。。。。其实是一个存储单元只能用高电平和低电平来区分它的状态,所以只有两种状态。