FP 与 TP 详细比较整理.docx
- 文档编号:4701021
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:30
- 大小:37.19KB
FP 与 TP 详细比较整理.docx
《FP 与 TP 详细比较整理.docx》由会员分享,可在线阅读,更多相关《FP 与 TP 详细比较整理.docx(30页珍藏版)》请在冰豆网上搜索。
FP与TP详细比较整理
FP与TP详细比较
一、编程环境的发展趋势
1、操作系统
竞赛的基础运行平台,分为选手用和评测用两方面。
*选手:
windows(NOIP)、linux(NOI)
*评测:
windows(NOIP省测)、linux(NOIP全国复评、NOI)
因为选手环境与评测环境不一致
,可能会蕴涵一些技术问题,另外出于版权问题,所以今后向linux方向发展,同时linux也是一种先进的操作系统,它的功能完善、系统可靠、引入了现代操作系统概念,更重要的是它是一种开放源代码的软件,使用成本低,无版权问题。
同时也为了与国际比赛(IOI、ACM等)接轨和有利于自动评测的进行。
2、集成开发环境和编译系统
①BASIC系列:
2004年已停用(中学)。
②PASCAL系列:
*ANSIPASCAL:
标准PASCAL;
*TurboPascal/BorlandPascal:
常用的两种Pascal,一是版权问题,二是技术落后,不能充分利用现代计算机的性能,表现在:
16位系统,内存限制(64KB/640KB),不统一的内存模式(far/near),单一平台(windows);
*FreePascal:
开放源代码的自由软件,没有版权问题,还可以进行二次开发。
更重要的是它是32位的编译系统、统一的内存模式、无内存使用限制、标准的语言版本、可跨平台使用(Linux、Windows),新增了一些功能,具体来说:
1)语法:
与ANSIPASCAL兼容,但与TP、BP有一定区别,如个别关键字、执行过程、文件名的大小写、个别专用函数等;
2)调试器:
debugger,调试程序的方便性,主流的图形化界面(基于GDB),与IDE集成在一起;
3)编译器:
检查语法及逻辑错误的能力、形成可执行文件(exe)的质量,有GO32W2和WIN32之分,后者调试时不稳定,但编译成的EXE代码质量高一点。
根据版本不同还可分为:
1.0.4、1.0.6、1.0.10等;
4)单元及应用编程接口:
提供的函数、过程数量与功能;应用编程接口(API-ApplicationProgrammingInterface);
5)集成开发环境(IDE):
integrationdevelopenvironment,为了方便用户的程序开发过程,将源代码编辑、编译、调试等多个程序的功能集成到一个界面下的开发工具,如DOS下的Turbo环境、Windows下的VisualStudio、Linux下的RHIDE都是集成开发环境。
FP的IDE与TP没有什么区别;
*NOIP专用FreePascal(官方FP):
在普通FreePascal基础上二次开发,具体如下:
调试器版本:
DebuggerGDB5.2.1;
编译器版本:
只提供GO32W2,CompileVersion1.0.10;
集成开发环境:
IDEforDosVersion0.9.2(withGraphicSupport);
关于语法与库单元后面会详细解释。
③C系列:
*TurboC/BorlandC:
相当于TP、BP;
*dev-c++:
一种很好的编程环境,用的很多;
*DJGCC:
相当于FP,GCC/RHIDE(图形界面GDB/Linux标准编辑开发环境);
*VC++(Windows):
优点是32位编译系统、标准的语言版本、良好的集成环境、完善的联机手册;缺点是版权问题、少量细节与GCC不一致;
3、中国计算机协会NOI科学委员会计划分3步推进编程环境的变革:
①从2005年起,取消TC/TP,筛选新的IDE和GDB图形前端;
②从2006年开始,试用新的IDE,与旧的RHIDE/FPIDE并存;
③从2008年年开始,鼓励使用新的IDE和GDB图形前端;
二、FP与TP的本质区别
虽然FreePascal尽量设计得和TurboPascal接近,但是由于以下的两个原因,两者之间还是有一些区别的:
1.FreePascal是一个32位的编译器,而TurboPascal只是16位的编译器;
2.FreePascal是一个跨平台的编译器,而TurboPascal只在windows上使用。
如果你的程序代码是完全遵守ANSIPascal的,那么你的程序代码从TurboPascal移植到FreePascal上是没有问题的。
三、TP和FP的功能区别
1.FreePascal理论上可以使用4GB(2^32byte)的内存,因此实际上几乎可以使用系统中的所有剩余内存(除非赛题中有内存限制),这是因为FreePascal使用的是32位的编译器。
但是对于TurboPascal来说,由于是16位的编译器,因此不能定义大小超过64KB(2^16byte)的数据类型和变量,并且在DOS实模式下可以使用的内存总数只有640KB。
但这并不是说,你可以随意定义很大的数组了,因为光读入200MB的数据就会让你的程序超时了(因为现在的7200转硬盘和133的系统总线速度决定了读取数据的速度也就100MB/秒)。
2.在FreePascal中,如果用assign给标准输入输出文件变量input和output指定了文件,在程序结束之前一定要用close关闭input和output,否则输出文件可能不能被正确的写入。
这个问题是近几年NOIP竞赛和省队训练、选拔中选手常犯的错误。
尤其是程序非正常结束之前(如halt)会忘记。
3.如果用Rewrite打开文件,那么文件就只能被写入了。
如果需要读取这个文件,要对文件执行Reset。
所以,在FreePascal中最好不要对一个文件同时进行读写操作。
4.在FreePascal中,集合中的元素都是4个字节长的。
5.表达式执行的顺序是不确定的。
比如对于表达式a:
=g
(2)+f(3);不保证g
(2)一定在f(3)之前执行。
6.函数和过程在使用时,参数的类型必须和定义时完全一致。
原因是在FreePascal中添加了函数重载功能。
7.PROTECTED,PUBLIC,PUBLISHED,TRY,FINALLY,EXCEPT,RAISE成为了关键字,因此不能作为函数和过程的名字;而FAR,NEAR不再是关键字了,原因是FreePascal是32位系统,不再需要这些关键字。
四、FP的新增功能
1.函数可以返回复杂的类型,比如记录和数组。
如:
typearrtype=array[1..100]oflongint;{必须要先定义数组基类型,否则红色部分不合法}
vari,j,k,n:
longint;
a:
arrtype;
functionsort(a:
arrtype;n:
longint):
arrtype;
vari,j,k:
longint;
begin
fori:
=1ton-1do
forj:
=i+1tondo
ifa[i]>a[j]then
begin
k:
=a[i];
a[i]:
=a[j];
a[j]:
=k;
end;
sort:
=a;
end;
begin
read(n);
fori:
=1tondoread(a[i]);
a:
=sort(a,n);
fori:
=1tondowrite(a[i],'');
writeln;
end.
2.在函数中,函数的返回值可以作为一个变量来处理。
比如:
functiona:
longint;
begin
a:
=12;
whilea>4do
begin
{...}
end;
end;
这个例子在TurboPascal中,a>4会被认为是函数的递归调用,但是在FreePascal中会认为a只是一个变量。
如果想在FreePascal中实现递归调用,就要写成下面的形式:
functiona:
longint;
begin
a:
=12;
ifa()>4then{递归调用}
begin
{...}
end;
end;
3.exit可以接受一个参数作为函数的返回值。
比如:
functiona:
longint;
begin
a:
=12;
ifa>4then
begin
exit(a*67);{函数的返回值就是a*67}
end;
end;
4.FreePascal支持函数重载。
可以用相同的名字定义不同的函数,只要这些函数的参数不同,就是不同的函数。
比如:
procedureDoSomething(a:
longint);
begin
{...}
end;
procedureDoSomething(a:
real);
begin
{...}
end;
可以使用不同的参数类型longint或者real来调用不同的DoSomething过程。
由于这个功能,函数的提前声明必须有完整的参数声明:
procedurex(v:
longint);forward;
{...}
procedurex;{这里定义的过程x重载了前面声明的过程x。
因此的两个x是不同的}
begin
{...}
end;
5.FreePascal容许运算符重载。
比如,可以自己为矩阵运算定义一个“+”运算。
格式:
operator运算符(运算数)结果
例:
operator+(x:
datatype;y:
datatype)z:
datatype;
begin
……
end;
6.TurboPascal中定义了十六进制数的表示方法,即在十六进制数前添加符号$,如:
X:
=$F0A;
Writeln(‘X=’,x);
输出结果是X=3850。
这种进制数的表述给编程者带来很多便捷,而FreePascal扩容了此优点,除十六进制数外,二进制数也有类似的表述(添加符号%),如:
X:
=%101;
Writeln(‘X=’,x);
输出结果是X=5。
7.TurboPascal中注释部分可用(*comment*)或者{comment}表示,如:
VarI:
integer;
Begin
(*forI:
=1to100do
write(i);*)
writeln(‘$’);
End.
或者:
VarI:
integer;
Begin
{forI:
=1to100do
write(i)}
writeln(‘$’);
End.
FreePascal除前面两种表述方法外,//comment也可以,但其中comment必须在同一行内,如:
将3、4行都括为注释部分:
VarI:
integer;
Begin
//forI:
=1to100do
//write(i);
writeln(‘$’);
End.
只将第3行括为注释部分:
VarI:
integer;
Begin
//forI:
=1to100do
write(i);
writeln(‘$’);
End.
8.在FreePascal中,编译时使用Fpc–Op3*.pas(针对PⅡ以上的处理器进行了优化)。
但实际比赛一般没有什么用(区别不大)。
9.利用指针实现动态开辟数组
vara:
^longint;
n,i:
longint;
begin
readln(n);
getmem(a,sizeof(longint)*n);
forI:
=1tondoa[I]:
=I;
freemem(a);
end.
实际很少用,因为一般NOIP的比赛对空间没有限制,在程序开始时总是把数组定义的足够大。
10.强制类型转换
格式:
数据类型(数据)
例如:
varm:
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就不再计算其它还没有计算的部分。
比如布尔表达式exp1ANDexp2ANDexp3,如果已知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循环的循环变量,如:
vari:
int64;
begin
forI:
=1to100dowriteln(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
声明部分:
ProcedureFillByte(varX;Count:
longint;Value:
byte);
作用:
用来给头地址为X的一段连续内存空间赋值,共附Count次,每次赋一个单字节无符号整型数Value。
通常用fillbyte来给元素类型为byte的数组赋初值。
例如:
var
a:
array[1..10]ofbyte;
i:
longint;
begin
fillbyte(a,sizeof(a),255);
fori:
=1to10dowrite(a[i],'');
writeln;
end.
输出:
255255255255255255255255255255
其中,函数sizeof(a)可以求出a数组占用的字节数。
②过程fillchar
声明部分:
ProcedureFillchar(VarX;Count:
Longint;Value:
charorbyte);
作用:
和fillbyte功能相同。
③过程fillword
声明部分:
ProcedureFillword(VarX;Count:
Longint;Value:
Word);
作用:
和fillbyte相仿,也是给头地址为X的一段连续空间赋值,附Count次,但每次赋的是一个值为Value的双字节无符号整数(word类型),所以每2个字节赋一次值,而fillbyte是每一个字节就赋一次值。
例:
Vara:
array[1..10]ofword;
i:
longint;
Begin
fillword(a,sizeof(a)div2,32767);
fori:
=1to10dowrite(a[i],'');
writeln;
End.
④过程filldword
声明部分:
ProcedureFillDWord(VarX;Count:
Longint;Value:
DWord);
作用:
与fillbyte相仿。
Dword意思是占用4个字节的整型,具体来讲可以是常用的longint类型。
例:
Vara:
array[1..10]oflongint;
i:
longint;
Begin
filldword(a,sizeof(a)div4,2147483647);
fori:
=1to10dowrite(a[i],'');
writeln;
End.
⑤数组比较函数comparebyte;
函数声明:
functionCompareByte(varbuf1,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,以下功能要用到此单元。
1掐时:
在NOIP竞赛中,禁止使用meml掐时,可以用其它方法,如以下是学生以前的掐时方法:
vart0,t1:
real;
begin
t0:
=meml[$40:
$6c];
……
t1:
=meml[$40:
$6c];
if(t1-t0)/18.2>3then{时限3秒}
begin
……
break;
end;
end.
改成:
usessysutils;
vart1:
tdatetime;
i,j,k:
longint;
begin
t1:
=now;
whiletruedo
begin
if(now-t1)*86400>3then
begin
……
break;
end;
end;
end.
2知道年月日,求星期。
usessysutils;
functiongetday(year,month,day:
word):
word;
vart:
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,以此类推。
②获取今天的日期
usessysutils;
varyear,month,day:
word;
proceduregetdate(varyear,month,day:
word);
vart:
tdatetime;
begin
t:
=now;
decodedate(t,year,month,day);
end;
begin
getdate(year,month,day);
writeln(year,'',month,'',day);
end.
其中year表示年号,month表示月份,day表示日期。
③判断是否是润年
usessysutils;
varyear:
word;
begin
year:
=2005;
ifisleapyear(year)
thenwriteln('Yes')
elsewriteln('No');
end.
其中year表示年号。
④将一个十进制整数转换成十六进制
usessysutils;
varx:
int64;
s:
string;
begin
x:
=100;
s:
=IntToHex(x,5);
writeln(s);
end.
其中x是十进制数,s是存十六进制数的字符串。
IntToHex的第二个参数是返回的16进制数的位数,如果此参数大于实际总位数,则在高位补'0'。
⑤将一个整数转换成字符串
usessysutils;
varx:
int64;
s:
string;
begin
x:
=987654321;
s:
=IntToStr(x);
writeln(s);
end.
其中x是十进制数,s是字符串。
⑥将一个浮点
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- FP TP 详细比较整理 详细 比较 整理