⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 关于fp的一些非常详细的资料.txt

📁 关于FreePascal的一些非常详细的资料 包含 1.易错Tips 以及注意事项 2.出错信息 希望对你的编程带来帮助
💻 TXT
📖 第 1 页 / 共 2 页
字号:
衡阳市第八中学信息学奥赛论坛&zju译题站
  http://61.187.179.132:82/index.asp

关于FP的一些非常详细的资料  
 三、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); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -