Fillchar过程全解

Fillchar是Turbo/Borland Pascal的System单元的一个标准过程,它的使用格式是:FillChar(var X; Count: Word; Value),它的功能是,把指定变量X在内存段中所占的低Count个字节赋为相同的值Value, 其中Value是填充的值,只能是Byte、Char或Boolean等单字节类型的值。在Free Pascal中稍加扩展为FillChar(var X; Count: Longint; Value), 功能没变。

[例1]:Fillchar通常用来给数据赋初值。
CODE: [Copy to clipboard]
——————————————————————————–

var a:array [1..10] of arrtype;
执行fillchar(a,sizeof(a),0);
当arrtype为
1.real(其他实数类型差不多) 使得a中的元素全部成为0.0
2.integer(byte,word,longint,shortint都相同) 全部为0
3.boolean 全部为false
4.char 全部为#0

这里使用了函数sizeof(a),其功能是返回变量a所占的总字节数,如上例返回:

当arrtype为

real sizeof(a)的值为60(每个元素占6个字节,10个元素共占60个字节)
single sizeof(a)的值为40(每个元素占4个字节,10个元素共占40个字节)
double sizeof(a)的值为80(每个元素占8个字节,10个元素共占80个字节)
extended sizeof(a)的值为100(每个元素占10个字节,10个元素共占100个字节)
comp sizeof(a)的值为80(每个元素占8个字节,10个元素共占80个字节)

integer(word) sizeof(a)的值为20 (每个元素占2个字节,10个元素共占20个字节)

byte (shortint) sizeof(a)的值为10 (每个元素占1个字节,10个元素共占10个字节)

longint sizeof(a)的值为40 (每个元素占4个字节,10个元素共占40个字节)

boolean sizeof(a)的值为10(每个元素占1个字节,10个元素共占10个字节)

char sizeof(a)的值为10 (每个元素占1个字节,10个元素共占10个字节)

所以例1的结果就是将数组a的所有元素(全部字节)用0来填充,要注意对不同类型的数据而言,对“0”的“解释”是截然不同的!对整型或实型量来讲,所有字节均为0,则该量也为0;对boolean型量(一个字节)来讲,0表示false(非0数表示true),则该量为false;对char型量(一个字节)来讲,0表示ASCII码值为0的字符,则该量为#0。

[例2]:将上例中的fillchar(a,sizeof(a),0)改为 fillchar(a,sizeof(a),1),结果如何呢?
CODE: [Copy to clipboard]
——————————————————————————–

执行fillchar(a,size(a),1);
当arrtype为

boolean 全部为true(1是非0值,表示true)

char 全部为#1

byte,shortint 每个元素是1字节量,全部为1

integer,word 每个元素是2字节量,全部为(257)10。这是因为

在一个integer或word 型变量中,它的高、低两个字节均用1来填充(将10进制数1转化为二进制数00000001),结果为:

高字节 低字节
CODE: [Copy to clipboard]
——————————————————————————–

15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
CODE: [Copy to clipboard]
——————————————————————————–

0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
1
显然,得到的量就是(257)10=(0000000100000001)2。

如果,执行的是fillchar(a,size(a),171),结果又是怎样的?

因为(171)10=(10101011)2,所以,填充后为:

高字节 低字节
CODE: [Copy to clipboard]
——————————————————————————–

15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
CODE: [Copy to clipboard]
——————————————————————————–

1
0
1
0
1
0
1
1
1
0
1
0
1
0
1
1
对于integer类型的量,其值为(-21589)10,这是因为integer类型的数据是用补码表示的有符号数,最高位是符号位,0表示正,1表示负,由于本数是负数,补码为1010101110101011,则反码为1010101110101010,原码为1101010001010101,其值为-(214+212+210+26+24+22+1)10=-(21589)10;对于word类型的量,其值为(43947)10,这是因为word类型的数据是用原码表示的无符号数(非负数),原码为1010101110101011,其值为(215+213+211+29+28+27+25+23+21+1)10=(43947)10;

5.longint 每个元素是4字节量,执行fillchar(a,size(a),1)后,全部为(16843009)10。这是因为,对于每个元素来讲,用1填充后变为:

最高字节 次高字节
CODE: [Copy to clipboard]
——————————————————————————–

31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
CODE: [Copy to clipboard]
——————————————————————————–

0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
1
次低字节 最低字节
CODE: [Copy to clipboard]
——————————————————————————–

15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
CODE: [Copy to clipboard]
——————————————————————————–

0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
1
longint类型的数据是用补码表示的有符号数,最高位是符号位,0表示正,1表示负,由于本数是正数,故补码、反码及原码均为00000001000000010000000100000001,其值为(224+216+28+1)10=( 16843009)10;

如果,执行的是fillchar(a,size(a),255),结果又是怎样的?

由于(255)10=(11111111)2,故填充后,补码为11111111111111111111111111111111,它是负数,则其反码为11111111111111111111111111111110,原码为10000000000000000000000000000001,其值为-1

6.single 每个元素是4字节量,全部为2.36942782761724E-0038,这是因为,对于每个元素来讲,用1填充后的结果与longint类型的二进制码完全相同,但是, single类型对此数据的“解释”却完全不同:

最高位(第31位)是整个数的符号位,0为正, 1为负;

接着的8位(第30位至第23位)是用移码表示的阶码;

后面的23位(第22至第0位)表示尾数;

单精度量的值为:±2实际指数*实际尾数

①、若阶码=00000000,则实际指数=-126,实际尾数=(0.???????????????????????)2,其中的?代表相应位置上的二进制码(0或1);显然,在?全为0时, 这个单精度量的值为0;

②、若阶码大于00000000且小于11111111,则实际指数=阶码-(127)10=阶码-01111111,实际尾数=(1.???????????????????????)2

③、INF(无穷大)若阶码=11111111,尾数全0,则已达上界,被作为无穷大

④、浮点运算错误:若阶码=11111111,尾数在(00000000000000000000000, 10000000000000000000000)之间。

⑤、NAN(非数:Not A Number)若阶码=11111111,尾数在[10000000000000000000000, 11111111111111111111111]之间

下面,我们来分析二进制码为00000001000000010000000100000001的单精度数(single类型)的值是多少

Leave a Reply

Your email address will not be published. Required fields are marked *