飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 4534|回复: 5

[C/C++] [转]理解C++ — 类型的意义

[复制链接]
  • TA的每日心情
    开心
    2024-6-4 09:58
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2007-9-27 10:30:26 | 显示全部楼层 |阅读模式
    [转]理解C++ — 类型的意义
    内存是分为一个一个的基本单元,通常每个基本单元有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之类的参数,就是用来指示你想将数据当成什么类型,以便进行不同的输出。
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    前天 09:19
  • 签到天数: 1087 天

    [LV.10]以坛为家III

    发表于 2007-9-27 11:08:12 | 显示全部楼层
    能多转一些类似的东东过来就更好了!
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-3-26 00:17
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    发表于 2007-9-29 21:31:28 | 显示全部楼层
    是啊,要转就转完啊!
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2024-6-9 16:20
  • 签到天数: 24 天

    [LV.4]偶尔看看III

    发表于 2007-10-24 17:10:33 | 显示全部楼层
    呵,有兴趣的可以看看,加强理解吧。基础知识。
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-10-5 10:59:15 | 显示全部楼层
    能多转一些类似的东东过来就更好了!
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2017-9-24 22:49
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2008-10-9 09:20:11 | 显示全部楼层
    很不错,最好是自己理解的
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表