现在的位置: 首页 > 综合 > 正文

理解C++ — 类型的意义

2013年01月06日 ⁄ 综合 ⁄ 共 2629字 ⁄ 字号 评论关闭
类型的意义

内存是分为一个一个的基本单元,通常每个基本单元有8位,一个基本单元叫做1 Byte(字节)。两个基本单元之间没有本质上的区别,就好象一个个同样大小,同样形状,同样颜色的小箱子。要将基本单元区分开,最直接的方法是将其编号。就好象将箱子排成一列,这是0号箱,这是1号箱,这是2号箱.....内存的基本单元也被编号。这个编号就叫做地址。计算机要读内存的时候,首先要先给出个地址,再发出个读信号,这个地址里面的数据就被读出来了; 同样要写内存的时候,先写进一个地址,再写进一个数据,跟着发出个写信号,数据就被写到内存。从前面的描述可以知道,内存有两个最最基本的要素,一个是它的地址(编号),另一个就是它存放的数据。比如一个个的箱子,编号用来区分哪一个箱子,而箱子里面可放着东西。这时候,大家可以回想起指针的概念,指针本质上就是一个内存单元的编号,只不过这个编号也放在内存而已。

好啦。已经知道基本单元可以放1 Byte的数据,1 Byte其实是很少的,我们所需要的数据很多时候1个基本单元放不下。那怎么办? 还用问,分开几个来放嘛。比如我的数据需要4个字节来放,这个时候就会产生个问题,怎么找回我的数据。可能你会说,还用问,用地址嘛,不是有个编号的吗?没有错,是有地址,不过4个字节有4个地址,你用哪一个? 最简单的是, 需要的基本单元地址是连续,用第一个地址(你也可以用最后一个地址)来表示, 这第一个地址叫做起始地址。好,现在再来想一想,光知道数据的起始就可以找回我宝贵的数据了吗?答案是:不行。比如我有两个数据,一个是4字节,一个是8字节,存放之后都得到一个起始地址,可惜你怎么知道这个起始地址标明的数据有多少个字节呢?所以为找回我的数据,除了要知道起始地址,还需要知道数据有多大,也就是size。假如我知道了起始地址为600, 有8个字节,我就可以理直气壮地说,从地址为600起,后面我8个字节都是我的,你们不要乱取哦。所以,类型的第一个意义就是表明这数据的大小,知道了类型就知道数据的大小,这大小在C++中可以用sizeof得到。

类型有很多,C++中最简单的类型就有char int double float等,还可以自己来定义。变量,常量都有自己的类型,定义之后就存放在内存,变成1001010100之类的二进制数据,什么int, 什么double,什么string最后都变成二进制,那怎么区分呢? 还有数据放在内存,代码也放在内存,怎么区分呢? 答案很奇妙,对于二进制数字(其实不单是二进制),本身是不可区分的,关键是看你怎么去看待,怎么去处理。同样一个二进制数值,你当成整数来处理,它就是整数,当成浮点数来处理它就是浮点数。同样的二进制数值,你执行它时,它就是代码,你将它进行运算时,它就是数据。也可以说,同样的二进制数值,你想将它当成整数,就用整数的方式去处理它,想将它当成浮点数,就用浮点数的方式去处理它。同样的数值,想将它当成代码,就去执行它,想将它当成数据,就进行运算。概括来说就是,数值本身不可区分,以操作来区分。也可以说数值本身是没有意义,看你想给他什么意义。这是一个很重要的概念,不理解它就很难理解计算机的运行方式。(就我而言,这恐怕是我接触到的最基本的计算机方面的概念了)

其实这有点涉及到编码,编码本身没有意义,可以区别你要编码的事物就可以了。比如我有16盏台灯,也有16台收音机,对台灯和收音机进行编号。对于9这个数字,本身没有意义。不过当我说打开第9盏台灯,还说打开第9台收音机,这个9就有意义了。不过我用openLamp和openRadio来表示打开台灯和打开收音机两个操作,发出两条指令openLamp 9, openRadio 9, 你也知道如何做。要是我将openLamp改为操作1,openRadio该为操作2,我说 操作1 9, 操作2 9,你有知道怎么做。连操作两字都去掉,就变成1 9, 2 9, 同样也知道我想做什么。现在我有个约定,将它化成2进制,头两个位表示操作,后4个位表示编号。那么说打开第9盏台灯,说打开第9台收音机,就分别是011001, 101001。将上面的二进制数值看成所谓的代码,你就能正确的打开台灯和收音机。

原则上,什么整数,什么浮点数只不过是个编号,用编号来区分不同的整数,不同的浮点数。当我们说9的时候,是没有意义的,不过用add来表示整数想加,用fadd来表示浮点数相加。9 add 10 表示一种操作,将编号为9的那个整数和编号为10的那个整数进行相加。另外9 fadd 10也表示一种操作,将编号为9的那个浮点数和编号为10的浮点数相进行相加。至于编号为9,为10的整数,编号为9,为10的浮点数到底是什么,就要看你怎么编码了。有些编码方式确实比其他方式要合理,有效,那就多人使用,当成默认,就成了标准了。现在无符号整数,有符号整数,浮点数如何编码都有自己的标准。

废话说了这样多,我们可以得到类型的第二个意义。以类型来指示如何操作放在内存的数值。

概括起来,类型的意义有两个
1)指明数据的大小,以便正确分配,访问,回收内存。
2)对本质上不可区分的内存数据进行不同的操作。

至于检查语法错误之类,不是类型最基本的意义。应该说,正因为有这两个意义,才有必要进行类型检查。

#include <iostream>
using namespace std;

int main()
{
    char chs[] = { 'A', 'B', 'C', 'D'};

    char *pChar = (char*)(&chs);
    short *pShort = (short*)(&chs);
    int *pInt = (int*)(&chs);
    float *pFloat = (float*)(&chs);

    cout<<*pChar<<endl;
    cout<<*pShort<<endl;
    cout<<*pInt<<endl;
    cout<<*pFloat<<endl;

    return 0;
}

比如同样的数据'A', 'B', 'C', 'D'存放之后变成二进制码,跟着将那些数值当成不同的类型,可以得出不同的输出。你也可以用printf, printf里面的%d, %s, %f之类的参数,就是用来指示你想将数据当成什么类型,以便进行不同的输出。
 

抱歉!评论已关闭.