关于FP(Free Pascal)的一些非常详细的资料

文章日期:07/14/2007 11:50 pm

关于FP(Free Pascal)的一些非常详细的资料

一、二部分 暂缺

三、TP和 FP的功能区别


  1.Free Pascal理论上可以使用4GB(2^32byte)的内存,因此实际上几乎可以使用系统中的所有剩余内存(除非赛题中有内存限制),这是因为Free Pascal使用的是32位的编译器。
但是对于Turbo Pascal来说,由于是16位的编译器,因此不能定义大小超过64KB(2^16byte)的数据类型和变量,并且在DOS实模式下可以使用的内存总数只有640KB。
但这并不是说,你可以随意定义很大的数组了,因为光读入200MB的数据就会让你的程序超时了(因为现在的7200转硬盘和133的系统总线速度决定了读取数据的速度也就100MB/秒)。


  2.在Free Pascal中,如果用assign给标准输入输出文件变量input和output指定了文件,在程序结束之前一定要用close关闭input和output,否则输出文件可能不能被正确的写入。
这个问题是近几年NOIP竞赛和省队训练、选拔中选手常犯的错误。尤其是程序非正常结束之前(如halt)会忘记。


  3.如果用Rewrite打开文件,那么文件就只能被写入了。如果需要读取这个文件,要对文件执行Reset。所以,在Free Pascal中最好不要对一个文件同时进行读写操作。
4.在Free Pascal中,集合中的元素都是4个字节长的。
5.表达式执行的顺序是不确定的。比如对于表达式a:=g(2)+f(3); 不保证g(2)一定在f(3)之前执行。
6.函数和过程在使用时,参数的类型必须和定义时完全一致。原因是在Free Pascal中添加了函数重载功能。
7.PROTECTED,PUBLIC,PUBLISHED,TRY,FINALLY,EXCEPT,RAISE成为了关键字,因此不能作为函数和过程的名字;而FAR,NEAR不再是关键字了,原因是Free Pascal是32位系统,不再需要这些关键字。


四、FP的新增功能


  1. 函数可以返回复杂的类型,比如记录和数组。

如:
type arrtype=array[1..100] of longint;{必须要先定义数组基类型,否则红色部分不合法}
var i,j,k,n:longint;
a:arrtype;

function sort(a:arrtype;n:longint):arrtype;
 var i,j,k:longint;
 begin
  for i:=1 to n-1 do
  for j:=i+1 to n do
  if a>a[j] then
   begin
    k:=a;
    a:=a[j];
    a[j]:=k;
   end;
  sort:=a;
 end;

begin
 read(n);
 for i:=1 to n do read(a);
 a:=sort(a,n);
 for i:=1 to n do write(a,' ');
 writeln;
end.

2.在函数中,函数的返回值可以作为一个变量来处理。

比如:
function a : longint;
 begin
  a:=12;
  while a>4 do
   begin
    {...}
   end;
 end;
  这个例子在Turbo Pascal中,a>4会被认为是函数的递归调用,但是在Free Pascal中会认为a只是一个变量。如果想在Free Pascal中实现递归调用,就要写成下面的形式:
function a : longint;
 begin
  a:=12;
  if a()>4 then { 递归调用 }
   begin
    {...}
   end;
 end;

3.exit可以接受一个参数作为函数的返回值。

比如:
function a : longint;
 begin
  a:=12;
  if a>4 then
   begin
    exit(a*67); { 函数的返回值就是a*67 }
   end;
 end;

4.Free Pascal支持函数重载。可以用相同的名字定义不同的函数,只要这些函数的参数不同,就是不同的函数。

比如:
procedure DoSomething (a : longint);
 begin
  {...}
 end;
procedure DoSomething (a : real);
 begin
  {...}
 end;
  可以使用不同的参数类型longint或者real来调用不同的DoSomething过程。
由于这个功能,函数的提前声明必须有完整的参数声明:
procedure x (v : longint); forward;
 {...}

procedure x; {这里定义的过程x重载了前面声明的过程x。因此的两个x是不同的}
 begin
  {...}
 end;

5.Free Pascal容许运算符重载。比如,可以自己为矩阵运算定义一个“+”运算。
格式: operator 运算符 (运算数) 结果


例: operator +(x:datatype; y:datatype) z:datatype;
 begin
  {……}
 end;

6. Turbo Pascal中定义了十六进制数的表示方法,即在十六进制数前添加符号$,

如:
X:=$F0A;
Writeln(‘X=’,x);
输出结果是X=3850。


这种进制数的表述给编程者带来很多便捷,而Free Pascal扩容了此优点,除十六进制数外,二进制数也有类似的表述(添加符号%)

如:
X:=%101;
Writeln(‘X=’,x);
输出结果是X=5。

7.Turbo Pascal中注释部分可用(*comment*)或者{comment}表示,

如:
Var I:integer;
Begin
  (*for I:=1 to 100 do
    write(i);*)
  writeln(‘$’);
End.
或者:
Var I:integer;
Begin
  {for I:=1 to 100 do
   write(i)}
  writeln(‘$’);
End.


Free Pascal除前面两种表述方法外,//comment也可以,但其中comment必须在同一行内,

如:
将3、4行都括为注释部分:
Var I:integer;
Begin
  //for I:=1 to 100 do
  // write(i);
  writeln(‘$’);
End.
只将第3行括为注释部分:
Var I:integer;
Begin
  //for I:=1 to 100 do
  write(i);
  writeln(‘$’);
End.

8.在Free Pascal中,编译时使用 Fpc –Op3 *.pas (针对 PⅡ以上的处理器进行了优化)。但实际比赛一般没有什么用(区别不大)。

9.利用指针实现动态开辟数组
var a:^longint;
n,i:longint;
  begin
   readln(n);
   getmem(a,sizeof(longint)*n);
   for I:=1 to n do a[I]:=I;
   freemem(a);
end.
实际很少用,因为一般NOIP的比赛对空间没有限制,在程序开始时总是把数组定义的足够大。

10.强制类型转换
格式:数据类型(数据)


例如:

var

   m:longint;
   n:extended;
begin
  m:=123456;
  n:=extended(m);
  writeln(n:0:6);
end.
注意:并不是任意两个基本数据类型之间都能进行强制转换。一般来说,fp允许两个整型之间的强制转换(实际意义不大,因为在赋值时fp会自动进行整型之间的类型转换),但需注意数据范围,例如,把p定义为integer,语句p:=integer(123456)虽然编译可以通过,但执行过程中p会溢出。fp也允许整型转换为实型,但有可能带来精度误差。至于实型转整型,需要满足整型所占字节数不小于实型,如double占8个字节,因此只能转换为int64。但实型转换为整型后,结果往往是错误的。把字符转换成整型,得到的是字符的Ascii码值,例如,writeln(longint('a'))输出的结果是97。

11.乘方x^y可以表示成x**y。
注意:
  A、在x是实数但y是整数的时候是不能这样表示,其他都可以,但精度可能不符合要求。
  B、x**y的结果如果是整型,不能超过longint的范围;如果是实型,不能超过extended的范围。
一般还是用换底公式(exp(y*ln(x)))来计算x^y。

12.布尔表达式不一定要全部进行计算。只要最终结果已经能够确定,FP就不再计算其它还没有计算的部分。

  比如布尔表达式exp1 AND exp2 AND exp3,如果已知exp1的结果是false,那么整个表达式的结果肯定是false,FP对exp2和exp3就不会再进行计算。


五、FP新增数据类型
1.整型
名称 类型 表示范围 占用字节
Int64 整数类型 -9223372036854775808 ~ 9223372036854775807=2 -1 8
Qword Int64的无符号整数类型 0 ~ 18446744073709551615=2 -1 8
Cardinal Longint(-2147483648~2147483647)的无符号长整型 0 ~ 4294967295=2 -1 4
Smallint 几乎等同于类型Integer(-32768~32767) -32768 ~ 32767=2 -1 2
注意:int64不是有序类型,所以不能作为for循环的循环变量,如:
var i:int64;
 begin
   for I:=1 to 100 do writeln(i);
 end.
编译不能通过,但word类型(integer类型的无符号整数类型,0~65535)可以。
  另外,直接给一个int64类型的变量赋值一个超过longint范围的整数是不合法的,例如:定义a为int64类型,有如下语句:a:=8000000000; 编译就通不过。类似的,以下三条语句也通不过编译:
a:=2*4000000000;
a:=800000*10000;
a:=a*8000000000;
  这是因为fp在表达式的计算过程中用来存储整数的最大默认类型为longint,而不是int64。
当表达式的中间值超过longint时,fp会用实型来储存中间值,而实型是不能直接赋给整型的。


解决方法:
分成两步赋值,先执行 a:=1;然后执行a:=a*800000*10000;
需要强调的是,第二步赋值中一定要把8000000000拆成若干个不超过longint型的整数的和或乘积。
如嫌上述方法麻烦,还可以利用截尾函数trunc,代码如下:
var
  tmp:double;
  a:int64;
begin
  tmp:=8000000000;
  a:=trunc(tmp);
end.

2.实型
FP中的双精度实数类型Double,比TP中的Real精确度更高。

名称 类型 表示范围 占用字节 精度
Real 实数类型 3.4e38 处理器是16位的,则占4个字节,即Single类型;如果是32位的处理器,则占8个字节,此时范围和精度都与double一样 7-8位有效数字
Double 实数类型 1.7e308 8 15-16位有效数字
extended 实数类型 1.1e4932 10 19-20位有效数字

3.允许用户按以下方式定义枚举类型:
Type
  EnumerateType=(Int,Long,Double:=100,Bool,……);
  这是类似于C的定义方式,定义使得Double的值是100,而并非2;Bool的值为101,而并非3……以此类推。但Int和Long的值仍为0和1。

六、FP新增单元和函数
1、过程和函数
①过程fillbyte
声明部分:Procedure FillByte(var X;Count:longint;Value:byte);
作用:用来给头地址为X的一段连续内存空间赋值,共附Count次,每次赋一个单字节无符号整型数Value。通常用fillbyte来给元素类型为byte的数组赋初值。例如:
var
  a:array[1..10] of byte;
  i:longint;
begin
  fillbyte(a,sizeof(a),255);
  for i:=1 to 10 do write(a,' ');
  writeln;
end.
输出:255 255 255 255 255 255 255 255 255 255
其中,函数sizeof(a)可以求出a数组占用的字节数。

②过程fillchar
声明部分:Procedure Fillchar (Var X;Count : Longint;Value : char or byte);
作用:和fillbyte功能相同。

③过程fillword
声明部分:Procedure Fillword (Var X;Count : Longint;Value : Word);
作用:和fillbyte相仿,也是给头地址为X的一段连续空间赋值,附Count次,但每次赋的是一个值为Value的双字节无符号整数(word类型),所以每2个字节赋一次值,而fillbyte是每一个字节就赋一次值。


例:
Var

  a:array[1..10] of word;
  i:longint;
Begin
  fillword(a,sizeof(a) div 2,32767);
  for i:=1 to 10 do write(a,' ');
  writeln;
End.

④过程filldword
声明部分:Procedure FillDWord (Var X;Count : Longint;Value : DWord);
作用:与fillbyte相仿。Dword意思是占用4个字节的整型,具体来讲可以是常用的longint类型。
例:
Var

  a:array[1..10] of longint;
  i:longint;
Begin
  filldword(a,sizeof(a) div 4,2147483647);
  for i:=1 to 10 do write(a,' ');
  writeln;
End.

⑤数组比较函数comparebyte ;
函数声明:function CompareByte(var buf1,buf2;len:longint):longint;
  逐字节地比较两段连续空间的前len个数据,两段空间首地址分别为buf1和buf2。如果都相同,就返回0。如果在第k个数据上首次出现不同,则返回buf1中第k个数据减去buf2中第k个数据的差。通常用来比较两个数组。类似地,comparechar是逐字符地比较,compareword是两个字节两个字节地比较,comparedword是4个字节4个字节地比较。注意慎用comparedword,它取数比较时只取每4字节的后2字节,因此当数组中存在大于65535的整数时,返回结果有可能出错。例如a[1]=65537,b[1]=1,因为65537和1的二进制后16位是一样的,所以comparedword(a,b,1)会返回0。

2、新增单元:sysutils,以下功能要用到此单元。
① 掐时:在NOIP竞赛中,禁止使用meml掐时,可以用其它方法,如以下是学生以前的掐时方法:
var

  t0,t1:real;
begin
  t0:=meml[$40:$6c];
   ……
  t1:=meml[$40:$6c];
  if (t1-t0)/18.2>3 then {时限3秒}
    begin
      ……
      break;
    end;
  end.
改成:
uses sysutils;
var

  t1:tdatetime;
  i,j,k:longint;
begin
  t1:=now;
  while true do
    begin
      if (now-t1)*86400>3 then
        begin
          ……
          break;
        end;
    end;
end.

② 知道年月日,求星期。
uses sysutils;
function getday(year,month,day:word):word;
  var t:tdatetime;
    begin
      T:=encodedate(year,month,day);
      Getday:=dayofweek(t);
    End;


begin
  writeln(getday(2005,4,20));
end.
其中year表示年号,month表示月份,day表示日期。输出1表示Sunday,2表示Monday,以此类推。

② 获取今天的日期
uses sysutils;
var year,month,day:word;
procedure getdate(var year,month,day:word);
  var t:tdatetime;
  begin
      t:=now;
      decodedate(t,year,month,day);
  end;
begin
  getdate(year,month,day);
  writeln(year,' ',month,' ',day);
end.
其中year表示年号,month表示月份,day表示日期。

③ 判断是否是润年
uses sysutils;
var year:word;
begin
  year:=2005;
    if isleapyear(year) then writeln('Yes')
    else writeln('No');
end.
其中year表示年号。

④ 将一个十进制整数转换成十六进制
uses sysutils;
var

  x:int64;
  s:string;
begin
  x:=100;
  s:=IntToHex(x,5);
  writeln(s);
end.
其中x是十进制数,s是存十六进制数的字符串。IntToHex的第二个参数是返回的16进制数的位数,如果此参数大于实际总位数,则在高位补'0'。

⑤ 将一个整数转换成字符串
uses sysutils;
var

  x:int64;
  s:string;
begin
  x:=987654321;
  s:=IntToStr(x);
  writeln(s);
end.
其中x是十进制数,s是字符串。

⑥ 将一个浮点小数转换成字符串
uses sysutils;
var

  s:string;
  x:extended;
begin
  x:=12034.05678;
  s:=FloatToStr(x);
  writeln(s);
end.
其中x是浮点小数,s是字符串。

3、新增单元:math,以下功能要用到此单元。
① 求K
uses math;
var

  k,x:extended;
  n:longint;
begin
  k:=5;n:=10;
  x:=Ldexp(k,n);
  writeln(x:0:3);
end.

② 求一个整数数组中的最大值
var a:array[1..Maxint]of longint;
begin
  Max:=MaxIntValue(a);
end.

③ 求一个整数数组中的最小值
var a:array[1..Maxint]of longint;
begin
  Min:=MinIntValue(a);
end.

④ 求一个实数数组中的最大值
var a:array[1..Maxint]of extended;
begin
  Max:=MaxValue(a);
end.

⑤ 求一个实数数组中的最小值
var a:array[1..Maxint]of extended;
begin
  Min:=MinValue(a);
end.

⑥ 反余弦 angle:=arcos(x);
反正弦 angle:=arcsin(x);
反正切 angle:=arctan(x);
其中x是余弦(正弦、正切),angle是弧度制的角度。

⑦ 返回不超过实数x且最接近x的整数
n:=floor(x);

⑧ 计算直角三角形的斜边
c:=hypot(a,b);
⑨ 计算
k:=logn(n,x);


七、在FP环境下调试程序的注意事项
1. 调试前的几点注意事项

(1) 增加程序本身的稳定性
a) 静态查错
为了减少无谓的调试,这一步很重要。往往一个TP中很容易查出的错误,FP却要花费惨重的代价。
b) 很小的数据可以手工运算
就好比分区联赛初赛中的阅读程序写运行结果一样,一些低级错误尽量不要依靠调试来检查。

(2) 检查数组和数据的范围
FP中有些错误同TP一样,会提前报告,如:

错误类型 举例 报告信息
数组赋值越界 var a:array[1..10]of integer;begin a[0]:=0;end; Range check error while evaluating constants
数据赋值越界 Var x:integer;Begin x:=2147483647;End. Range check error while evaluating constants
但有些错误不会提前报错,如:Var a:array[x..y] of 基类型;下标p出现小于x或大于y的情况,如下:
var a:array[1..100] of integer;
i:integer;
begin
  fillchar(a,sizeof(a),0);
  i:=100;
  while a=0 do i:=i-1;
   write(a);
  readln
end.
这个程序在TP下运行没有问题,但在FP下就会出现201错误。原因是while循环结束后的i值是0,输出a[0]的值。
再比如,下面的这个求1~N的全排列的回溯法程序:
program p17a;
var

  stack:array[1..20] of integer;
  s:set of 0..20;
  j,top,k,n:integer;
begin
  readln(n);
  s:=[ ];
  top:=0;k:=0;
  while top>=0 do
    begin
      k:=k+1;
      if k>n then begin k:=stack[top];s:=s-[k];top:=top-1;end{回溯}
      else if not(k in s) then begin
         top:=top+1;
         stack[top]:=k;
         s:=s+[k];
         k:=0;
         if top=n then
           begin
             for j:=1 to top do write(stack[j]);
             writeln;
           end
      end
    end
end.
运行后输出结果正确,但会报201错误,只要把stack[1..20]改成[0..20]就OK了。

下面列出一些常见的蕴涵错误,大家必须当心:

错误类型 举例 造成影响
数据循环越界 Var x:integer;Begin For x:=1 to 32769 do Write(x);End. x既不是由1循环至32769,也不是由1循环到32767,而是由1循环至2。所以输出结果为:12
数组下标循环越界 Var i:integer; a,b:array[1..5]of integer;Begin For i:=1 to 5 do b:=i; For i:=1 to 6 do a:=i;End. 会不定性的出现两种情况:情况1:程序运行到a[6]:=6是出错中止,出现“000070E7 SYSTEM$$_HANDLEERRORADDRFRAME$LONG INT$LONG INT$LONGINT( )”等信息;情况2:a[6]:=6语句的出现会修改其它变量比如b[1]的值。这一点比较像Delphi5。
字符串长度越界 Var i:integer; S:string;Begin S:=’’; For i:=1 to 256 doS:=S+chr(i mod 10+48); Writeln(length(S)); Writeln(S);End. 对于超出长度范围上界的字符串部分,所有操作一律无效。输出结果为:2551234567890………………6789012345
集合范围越界 Var i:integer; S:set of 1..128;Begin S:=[1..10]; For i:=0 to 128 do If i in s then writeln(i);End. 虽然单独写入s:=[1..10]的语句,FP无任何不良反应,但程序运行到“if 0 in s then writeln(0)“时会出错终止,哪怕程序第3行写入的是语句s:=[0..10]也同样不能做if 0 in s的判断。还必须把集合的定义改成S:set of 0..128;
空间溢出 Var a:array[1..100000000]of longint;Begin ……End. FP不会提前报错,但一运行程序,就会因空间溢出而出错中止。

对于不会报告的错误,倘若是空间溢出等,虽然在调试过程中会出现挂机、莫名退出程序、跟踪光条消失种种问题,让人甚为恼火,但相比之下,数据循环越界、数组下标越界等FP自以为“兼容”的问题,却更加可怕。它们很隐蔽的潜藏起来,如果不加注意,只关心算法本身的正确性,会耗费很多调试程序的时间,这是不值得的。

(3) 把数组开小一点
若不然,FP会出现莫名其妙退出的现象,哪怕程序毫无错误。

(4) 编程过后要存盘。
存盘是当然,不然FP会报告"Can't compile unsaved file!"信息,以防止程序意外丢失。

2. 调试时的几点注意事项

(1) 模块调试
这种分治策略,针对FP IDE速度慢,而且Bug多的特点,降低了调试难度。

(2) 避免使用F7
F7经常失效,它往往拒绝进入子程序展开进一步的跟踪。这时,F4可以代替F7完成工作。切记这一点,不然在跳过子程序后再重头调试是很麻烦的。

(3) 减少F8的使用频率
虽然F8不象F7那样不听指挥,但也时常失效,尤其是在程序运行出错以后。

(4) 尽量使用F4
很多时候,F8会在程序出错再调试时出现一些随机给出的错误,比如说蓝条会消失,FPcx莫名退出,甚至死机。F4相对稳定一些,只不过当遇到类似If 、Case 语句时,最好看清楚了,程序会执行哪一步。

(5) ALT+F7会失效
对于这一点,似乎没有很好的补救措施,只能打开Run菜单,点击Parameter。

(6) 集合类型不能察看怎么办
这里有两条应对措施:
a) 简单的试题保证集合类型使用正确;
b) 繁琐的试题避免使用集合类型;

(7) 诡异的多维数组跟踪
在程序体中用a[i,j]和a[j]来访问数组都是正确的,但在watches中跟踪二维数组的一个单元时,就只能用a[j]来查看了。例如二维数组a[3,4]=10,在watches中跟踪a[3,4]看到的不是10,只有跟踪a[3][4],显示出来的才是10。

3. 出错后的几点应对措施
(1) 发现错误,想结束调试。
千万不要在修改测序后接着使用F8,因为FP不会理睬你对程序的修改,不会像TP 和Dlephi一样出现类似“Source hs been modified. Rebuild? Yes? No? Cancle”的对话框,还可能导致蓝条的消失。所以,使用快捷键CTRL+F2终止调试,然后使用快捷键ALT+F9进行编译,当然存盘不要忘记。

(2) 程序运行出错
使用ALT+F5察看黑屏上有无出错信息。
当你再次调试时,有时一切运行良好,但有时会出现一些问题:
a) 如果F8不工作了,那么再次存盘并使用Build编译;
b) 如果F8仍然不工作,那么尝试使用F4;
c) 如果蓝条消失,也可以尝试使用F4;
d) 如果F4也不工作,那么关闭其它窗口的程序,再尝试一次;
e) 如果F4仍然不工作,那么ALT+X关掉所有可以关闭的程序,并退出失控的FP, 然后重新进入。

4、其他
① Free Pascal在windows 95及其以上的windows版本上支持长文件名。对于文件名,由于windows系统对大小写不敏感,因此在程序中,文件名的大小写是无关的。但是对于其它大小写敏感的系统,比如linux,程序中用到的文件名必须和系统中的文件名完全一致。
由于信息学竞赛的评测系统一般是linux,因此要求程序中的文件名和系统中的文件名一样。即:比赛中涉及的所有文件名(包括源程序名、输入文件名、输出文件名、答案文件名),都必须严格按照题目要求命名,严格区分大小写。例如:题目要求输入文件名为game.in,则程序中必须按照该名字打开文件,不能使用Game.in、GAME.IN等名字;

② 在NOIP比赛中,程序中不得使用题目规定外的其他任何库(unit),一般在试机时确认;

③ 在NOIP比赛中,源代码中不得使用编译选项(开关);

④在NOIP比赛中,禁止使用meml进行掐时。

八、Free Pascal错误一览表
1、 Run Time Errors 运行错误
(A) DOS 错误代码:
1:无效DoS功能号
2:文件末找到
3:路径未找到
4:打开文件过多
5:禁止文件存取
6:无效文件句柄
12:无效文件存取代码
15:无效驱动器号
16:不能删除当前日录
17:不能跨驱动器改文件名
(B) I/O错误
100:磁盘读错误
101:磁盘写错误
102:文件变量末赋值
103:文件未打开
104:文件未用输入方式打开
105:文件末用输出方式打开
106:无效数字格式
(C) 严重错误
150:磁盘写保护
15l:未知单元
152:驱动器未准备好
153:未知命令
154:数据CRC校验错
155:驱动器请求的结构长度错
156:磁盘定位错
157:未知媒介类型
158:扇区末找到
159:打印机缺纸
160:设备写失败
161:设备读失败
162:硬件故障
(D) 致命错误
200:被零除
20l:范围检查错
202:堆栈溢出错
203:堆溢出错
204:无效指针操作
205:浮点上溢出
206:浮点下溢出
207:无效浮点运算
208:未安装覆盖管理程序
209:覆盖文件读错
210:对象未初始化
2ll:调用抽象方法
212:流登计错
213:集合下标越界
214:集合溢出
215:算术上溢错误
216:存取非法
217:控制-C
218:授权指令
219:无效的TYPECAST
220:无效的变体TYPECAST
221:无效的变体操作
222:没有变体方法调用DISPATCHER
223:不能建立变体数组
224:变体不包含数组
225:变体数组边界错误
226:TLS初始化错误

2、 编译错误对照表
下面列出在编译程序时可能出现的错误,在集成环境下,Pascal将自动加载源程序并定位于出错处。
1:内存溢出
2:缺标识符
3:标识符未定义
4:标识符重定义
5:语法错误
6:实型常量错
7:整型常量错
8:字符串常量跨行
9:文件嵌套过多
10:非正常文件结束
11:行过长
12:缺类型标识符
13:打开文件过多
14:无效文件名
15:文件未找到
16:磁盘满
17:无效编译指示
18:文件过多
19:指针定义中未定义类型
20:缺变量标识符
21:类型错误
22:结构过长
24:文件分量不能为文件
25:无效字符串长度
26:类型不匹配
27:无效子界基类型
28:下界大于上界
29:缺有序类型
30:缺整型常数
31:缺常数
32:缺整型或实型常数
33:缺指针类型标识符
34:无效的函数结果类型
35:缺标号标识符
36:缺BEGIN
37:缺END
38:缺整型表达式
39:缺有序表达式
40:缺布尔表达式
41:操作数类型与操作符不匹配
42:表达式错
43:非法赋值
44:缺字段标识符
45:目标文件过长
46:未定义外部标识符
47:无效*.OBJ文件记录
48:代码段过长
49:数据段过长
50:缺DO
51:无效PUBLIC定义
52:无效EXTRN定义
53:EXTRN定义过多
54:缺0F
55:缺INTERFACE
56:无效重定位引用
57:缺THEN
58:缺T0或DOWNTO
59:未定义的向前引用
60:过程过多
61:无效类型转换
62:被零除D
63:无效文件类型
64:不能读写该类型的变量
65:缺指针变量
66:缺字符串变量
67:缺字符串表达式
68:单元循环引用
69:单元名不匹配
70:单元版本不匹配
71:单元重名
72:单元文件格式错误
73:缺IMPLEMENTATl0N
74:常数与CASE类型不相匹配
75:缺记录变量
76:常数越界
77:缺文件变量
78:缺指针变量
79:缺整型或实型表达式
80:标号不在当前块中
81:标号已定义
82:标号未定义
83:无效参数
84:缺UNIT
85:缺“;”
86:缺“:”
87:缺“,”
88:缺“(”
89:缺“)”
90:缺“=”
91:缺“:=”
92:缺“[”或“(.”
93:缺“]”或“.)”
94:缺“.”
96:变量过多
97:无效FOR控制变量
98:缺整型变量
99:此处不允许用文件和
100:字符串长度不匹配
101:无效字顺序
102:缺字符串常数
103:缺整型或实型变量
104:缺有序变量
105:INLINE错
106:缺字符表达式
107:重定位项过多
112:CASE常量越界
113:语句错
114:不能调用中断过程
116:必须在8087方式下编译
117:末找到目标地址
118:此处不允许包含文件
120:缺NIL
121:无效限定符
122:无效变量引用
123:符号过多
124:语句部分过长
126:文件必须为变量参数
127:条件符号过多
128:条件指令错位
130:初始条件定义错
13l:过程和函数头与前面定义的不匹酉
132:严重磁盘错误
133:不能计算该表达式
134:表达式错误结束
l35:无效格式说明符
136:无效间接引用
137:此处不允许结构变量
138:无SYSTEM单元不能计算
l39:不能存取该符号
140:无效浮点运算
141:不能将覆盖编译至内存
142:缺过程和函数变量
143:无效过程或函数引用
144:不能覆盖该单元
147:缺对象类型
148:不允许局部对象类型
149:缺VIRTUAL
150:缺方法标识符
151:不允许虚拟构造方法
152:缺构造方法标识符
153:缺释放方法标识符
154:FAIL只允许在构造方法内使用
155:无效的操作符和操作数组合
156:缺内存引用
l57:不能加减可重定位符号
158:无效寄存器组合
159:未激活286/287指令
160:无效符号引用
161:代码生成错
162:缺ASM