Freepascall资料详解
一、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;
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 8 Qword Int64的无符号整数类型0 ~ 18446744073709551615 8 Cardinal Longint的无符号长整型0 ~ 4294967295 4 Smallint 几乎等同于类型Integer -32768 ~ 32767 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; x既不是由1循环至32769,
Begin 也不是由1循环到32767,
For x:=1 to 32769 do Write(x); 而是由1循环至2。
End. 所以输出结果为:12
数组下标循环越界Var i:integer; 会不定性的出现两种情况:
a,b:array[1..5]of integer; 情况1:程序运行到a[6]:=6是出错中止,
Begin 出现“000070E7 SYSTEM$$_HANDLE
For i:=1 to 5 do b:=i; ERRORADDRFRAME$LONG INT
For i:=1 to 6 do a:=i; $LONG INT$LONGINT( )”等信息;
End. 情况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); 255
Writeln(length(S));1234567890 (6789012345)
Writeln(S);
End.
集合范围越界Var i:integer; 虽然单独写入s:=[1..10]的语句,FP无任何不良S:set of 1..128; 反应,但程序运行到“if 0 in s then writeln(0)“时
Begin 会出错终止,哪怕程序第3行写入的是语句
S:=[1..10]; s:=[0..10]也同样不能做if 0 in s的判断。
For i:=0 to 128 do If i in s then writeln(i); 还必须把集合的定义
End. 改成S:set of 0..128;
空间溢出Var a:array[1..100000000]of longint; FP不会提前报错,
Begin 但一运行程序,就会因空间溢出而出错中止。
……
End.
对于不会报告的错误,倘若是空间溢出等,虽然在调试过程中会出现挂机、莫名退出程序、跟踪光条消失种种问题,让人甚为恼火,但相比之下,数据循环越界、数组下标越界等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进行掐时。
六、Math库实用汇总
在FP中,Math库为我们提供了丰富的数学函数。以下介绍在OI中可能会用到的Math 库中一些函数、过程。使用方法:在程序头用Uses语句加载Math库例子:Program Ex_Math;
Uses Math;
Begin
Writeln(hypot(3,4));
End.
函数介绍:
hypot
原型:function hypot(x:float;y:float):float
功能:返回直角三角形中较长边的长度,也就是sqrt(sqr(x)+sqr(y))
ceil
原型:function ceil(x:float):Integer
功能:返回比参数大的最小整数。引发错误:在x超出Integer的范围时会引发溢出错误
floor
功能:返回参数小的最大整数。引发错误:在x超出Integer的范围时会引发溢出错误
power
原型:function power(base:float;exponent:float):float
功能:返回base的exponent次方。引发错误:在base为负数且exponent为小数时intpower
原型:function intpower(base:float;const exponent:Integer):float
功能:返回base的exponent次方
Ldexp
原型:function ldexp(x:float;const p:Integer):float
功能:返回2的p次方乘以x
log10
原型:function log10(x:float):float
功能:返回x的常用对数
log2
原型:function log2(x:float):float 功能:
返回x以2为底的对数
logn
原型:function logn(n:float;x:float):float
功能:返回x以n为底的对数
Max
原型:function Max(a:Integer;b:Integer):Integer
function Max(a:Int64;b:Int64):Int64
function Max(a:Extended;b:Extended):Extended
功能:返回a与b中较大的一个
Min
原型:function Min(a:Integer;b:Integer):Integer
function Min(a:Int64;b:Int64):Int64
function Min(a:Extended;b:Extended):Extended
功能:返回a与b中较小的一个
arcsin
原型:function arcsin(x:float):float
功能:返回x的反正弦值,返回的是弧度
arcos
原型:function arccos(x:float):float
功能:返回x的反余弦值,返回的是弧度
tan
原型:function tan(x:float):float
功能:返回x的正切值,x以弧度为单位
cotan
原型:function cotan(x:float):float
功能:返回x的余切值,x以弧度为单位
arcsinh
功能:返回双曲线的反正弦
arccosh
原型:function arccosh(x:float):float
功能:返回双曲线的反余弦
arctanh
原型:function arctanh(x:float):float
功能:返回双曲线的反正切
sinh
原型:function sinh(x:float):float
功能:返回双曲线的正弦
cosh
原型:function cosh(x:float):float
功能:返回双曲线的余弦
七、精度问题
FP中的round函数不精确,而且只能在一定范围内使用,如
var x:real;则round(x)要小心,比如x:=1999.5;实际上计算机里存的是1999.49999......,这种情况用x:=x+1e-9之类,或者直接用场宽输出。有时干脆先加0.5,再trunc。
所有打开的文件在程序运行结束前一定要关闭,尤其是在非正常结束前(halt,exit)不要忘记;
一、单项选择题(共10 题,每题1.5 分,共计15 分。每题有且仅有一个正确答案.)。13届普及组一、单项选择题:(每题1.5分) 1. D 2. D 3. C 4. B 5. B 6.B 7. B 8. C 9. C 10. A 11. C 12. A 13. A 14. A 15. B 16. D 17. C 18. D 19. A 20. A 1.在以下各项中,()不是CPU的组成部分。 A.控制器 B.运算器 C.寄存器 D.主板 2.在关系数据库中,存放在数据库中的数据的逻辑结构以()为主。 A.二叉树 B.多叉树 C.哈希表 D.二维表 3.在下列各项中,只有()不是计算机存储容量的常用单位。 A.Byte B.KB C.UB D.TB 4.ASCII码的含义是()。 A.二→十进制转换码 B.美国信息交换标准代码 C.数字的二进制编码 D.计算机可处理字符的唯一编码 5.一个完整的计算机系统应包括()。 A.系统硬件和系统软件 B.硬件系统和软件系统 C.主机和外部设备 D.主机、键盘、显示器和辅助存储器 6.IT的含义是()。 A.通信技术 B.信息技术 C.网络技术 D.信息学 7.LAN的含义是()。 A.因特网 B.局域网 C.广域网 D.城域网 8.冗余数据是指可以由其它数据导出的数据。例如,数据库中已存放了学生的数学、语文和英语的三科成绩,如果还存放三科成绩的总分,则总分就可以看作冗余数据。冗余数据往往会造成数据的不一致。例如,上面4个数据如果都是输入的,由于操作错误使总分不等于三科成绩之和,就会产生矛盾。下面关于冗余数据的说法中,正确的是()。 A.应该在数据库中消除一切冗余数据 B.用高级语言编写的数据处理系统,通常比用关系数据库编写的系统更容易消除冗余数据 C.为了提高查询效率,在数据库中可以保留一些冗余数据,但更新时要做相容性检验 D.做相容性检验会降低效率,可以不理睬数据库中的冗余数据 9.在下列各软件,不属于NOIP竞赛(复赛)推荐使用的语言环境有()。A.gcc B.g++ C.Turbo C D.Free Pascal
Freepascall资料详解 一、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;
动态规划 一、背包问题 1、0/1背包[问题背景及描述] Bessie 正在减肥,所以她规定每天不能吃超过C (10 <= C <= 35,000)卡路里的食物。农民John 在戏弄她,在她面前放了B (1 <= B <= 21) 捅食物。每桶内都有某个单位卡路里(范围:1..35,000)的食物(不一定相同)。Bessie 没有自控能力,一旦她开始吃一个桶中的食物,她就一定把这桶食物全部吃完。Bessie 对于组合数学不大在行。请确定一个最优组合,使得可以得到最多的卡路里,并且总量不超过C。例如,总量上限是40卡路里,6 桶食物分别含有7, 13, 17, 19, 29, 和31卡路里的食物。Bessie可以吃7 + 31 = 38卡路里,但是可以获取得更多:7 + 13 + 19 = 39卡路里。没有更好的组合了。 [输入] 共两行。 第一行,两个用空格分开的整数:C 和 B 第二行,B个用空格分开的整数,分别表示每桶中食物所含的卡路里。 [输出] 共一行,一个整数,表示Bessie能获得的最大卡路里,使她不违反减肥的规则。 [输入样例] 40 6 7 13 17 19 29 31 [样例输出] 39 2、固定次数的0/1背包 有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件体积是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。V〈30000,n〈100,n[i]〈50。 输入输出格式: 第1行,两个用空格分开的整数:v 和n 第2—n+1行,每件体积是c[i],价值是w[i],最多有n[i]件可用 [输入样例] 40 2 10 20 5 20 30 6 [样例输出] 80 3、重复背包货币系统money 母牛们不但创建了他们自己的政府而且选择了建立了自己的货币系统。[In their own
钻孔制作方法: 一.读入Gerber file: Windows→input→Identify Open wheel template→All→????→???Illegal???→sym修改完毕→File→Close→修改ncdrill格式,将光标移到此处,按右键→Parameters…→修改格式后→OK→Translate→ Path:genesis/input/691040a21 Job:691040a21 step:ori Exclude:*.zip;*.gap…. 注:1.识别:绿色表示识别成功;蓝色表示无法识别;粉红色表示部分有问题。 2.转换:红色表示失败。 二.建立PCB文件: 点击job matrix…→ori→edit→copy→出现ori+1,在ori+1处按左键,修改step:ori+1为pcb→file→save→close→file→close 一.更改层名:job matrix….→在Layer处修改层名 二.排序:将光标移到需移动的层→左键→Ctrl+x→光标移至目的层。反复上述动作,直到与实物板迭构相同为止。 三.定义属性: 1.除map层外,其余均定义为Board。 2.将skc、sks定义为silk-screen;smc、s ms定义为solder-mask;vc2、gn3定义为power-ground,若内层为负片,则需 定义为negative,否则定义为positive。 3.File→save→close。 四.归零点: 1.打开map层→选中PCB外围框→Edit→Copy→other layer→Layer name:outline→ok,将框线改为10mil。 2.用单项选择钮点取outline层左下角二条线→Rout→connections…→选择直角钮→Corner→best→close。 3.将所有层设为影响层→将网格设为交点→点击outline层左下角交点处→Ctrl+x→在X,Y处键入0 0后回车→关闭影 响层。 五.定义Profile:选中outline层→Edit→create→profile。 六.钻孔处理: 1.打开map层,将drill chart部分放大,按CTRL+P打印。 2.打开dr1层,光标移至此处按右键→Drill tool manager…→与drill chart图纸仔细核对顺序及孔径大小是否一致→定义 np孔→Apply→ok→close。 3.在dr1层处按右键→Hole sizes→键入孔径→OK→OK。 以上3步可通过下列方式实现: 将ncdrill.tap另存新檔至ncdrill-1.tap中,但只保留孔径大小部分,其余全部删除,则可自动input孔径大小。 4.槽孔处理:打开map与dr1层,并将dr1层设为工作层→Edit→Reshap→change symbol→symbol→选中槽孔符号→输 入width及值→OK→Apply→Close。 5.Include symbol:oval*→select→Edit→reshape→break。 6.→Redundancy cleanup→NFP Removal…→Duplicate。 7.检查钻孔与其它层状态:Analysis→Drill checks→运行。 8.检查钻孔孔距:Analysis→Board-Drill-Check→运行。 9.孔位校正:DFM→Repair→pad snapping→Ref layer:top→运行。 10.将CPU及BGA处刀与其它部位刀分开处理: a. 选中欲分刀之孔→Edit→Resize→Glolav…→Size:-0.1my。 b. Size:+0.1my。 11.设定np User filer...→no plated hole→将线钮按下→Select→Edit→copy→layer name:np→ok。 12.设定11 a.将dr1层和outline层分别Copy到11层。 b.将np层Copy至11层,Invert项选Y es,Resize处键入-20mil→OK。 七〃削到VIA PAD 选出方法: 1. 将外层按工作片方式加大(线加大1mil,PA D加大0.5mil) 2. 打开原稿dr1层,将成品径<=18mil的孔选出并定义为via层 3. top(只选PAD)、via(ref)→touch→move → 001层 4. top(只选PAD)、s mc(ref)→touch→ Copy并加大9.1mil→002 层 5. 001 、002(ref)→touch→move →003 6. top、001(ref)→touch→Ctrl+B 7. 001(+7.1mil)、top(ref)→touch →(-7.1mil)Move → 003 8. bot(只选PAD)、via(ref)→touch→move → 004层 9. bot(只选PAD)、s ms(ref)→touch→ Copy并加大9.1mil→005 层 10. 004 、005(ref)→touch →move → 003 11. bot、004(ref)→touch→Ctrl+B 12. 004(+7.1mil)、bot(ref)→touch →(-7.1mil)Move → 003 13. dr1、003(ref)→Touch →减小0.1my 八.钻孔输出: 1. 增加End: 打开PANEL→Step→panelization→Drill/Rout verification→Edit…→New→Step: End ;width(最大钻孔径):; Height(End长度):→OK→Table→new step…→End→OK→点击End→将Angle设为90→放置合理位置→ 击End,此时step处出现End→Type选择drill→Mode选择End→Layer name输入dr1→Method选择 Automatic→Distance: 40 ml Spacing ; Min size: 0 ml ; Max size(最大钻孔径): ml ;Min hits:0→OK→OK。 2. 自动钻孔程序管理:
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:对象未初 始化 211:调用抽象 方法 212:流登计错 213:集合下标 越界 214:集合溢出 215:算术上溢 错误 216:存取非法 217:控制-C 218:授权指令 219:无效的TY PECAST 220:无效的变 体TYPECAST 221:无效的变 体操作 222:没有变体 方法调用DISPA TCHER 223:不能建立 变体数组 224:变体不包 含数组 225:变体数组 边界错误 226:TLS初始化 错误 2、编译错误对照表
GENESIS2000制作資料步驟清單一.鑽孔的制作: 1.去重復孔 2.校正鑽孔 3.定義VIA孔屬性 4.孔徑補償 5.短槽孔制作 6.BGA分刀 7.CPU跳鑽制作(當此板無插件式CPU時可省略此步驟) 8.對雙面開窗的VIA孔進行處理 9.鑽孔總測 10.COPY AOI-NPTH層(特別注意孔數是否同DD中相符) 11.機器比對原稿(公差設5mil) 二.內層負片的制作 1.去除成型線以外的物件 2.優化正負片資料(若客戶設計隔離線非正負片疊加而成,可省略此步驟) 3.去除比鑽孔小的蜘蛛PAD 4.將指示分層的字母加大1MIL制作 5.放大隔離PAD 6.檢測隔離PAD放大的結果 7.補細絲 8.看導通寬度 9.成型削銅 10.總測 11.比對原稿 12.測網絡 13.機器比對原稿 三. 內層正片無線路的制作 1.去除成型線以外的物件 2.去重復PAD 3.去獨立PAD 4.換銅面 5.套隔離 6.檢測銅皮的寬度 7.放大PAD的Ring邊,補償線寬,將指示分層字母加大1mil制作 8.將銅面分別移回相應內層中(移回時不改極性) 9.成型削銅 10.總測 11.比對原稿 12.測網絡 13.機器比對原稿 四. 內層正片有線路的制作 1.去除成型線以外的物件 2.去重復PAD 3.去獨立PAD 4.換銅面 5.套隔離 6.放大PAD的Ring邊,補償線寬,加淚滴 7.套銅面 8.檢測銅皮的寬度 9.將銅面分別移回相應內層中(移回時不改極性) 10.削PAD 11.成型削銅 12.總測 13.比對原稿 14.測網絡 15.機器比對原稿
五. 外層制作 1.去除成型線以外的物件 2.分析資料 3.去NPTH孔上的PAD 4.換PAD 5.換銅面 6.定義SMD屬性 7.PAD的補償 8. 放大PAD的Ring邊 9. 檢測PAD的Ring邊放大的結果 10. 線寬的補償(當資料間距較小需用蝕刻補償制作時,此時可補最小線寬) 11. 套銅面(注意處理銅皮寬度是否有做到5mil以上) 12. 將銅面COPY至相應的線路層 13. 削間距,看IC縮線 14.加淚滴,補針孔 15.蝕刻補線(若前面補線已符合要求達到最佳值時可省略此步驟) 16.獨立線的加補 17.成型削銅的處理 18.檢測PTH孔上的PAD間距是否有6MIL以上 19.加UL MARK(若UL MARK需以文字方式添加可省略此步驟) 20.總測 21.比對原稿 22.測網絡 23.機器比對原稿 六. 防焊制作 1. 刪除工作稿M1及M4層中的資料 2.手動制作M1及M4 3.挑pad的狀態 4.挑ON PAD的狀態 5.削防焊PAD間的間距 6.削BGA pad的間距 7.防焊爆油的檢測 8.防焊VIA孔單面開窗的處理 9.比對原稿 10.總測 11.機器比對原稿 七. 擋點的制作 1.按要求挑擋點的狀態 2.削擋點的間距 3.擋點的檢測 4.檢查 八.文字制作 1.去除成型線以外的物件 2.查看文字的線寬是否在5mil以上,不足的要加寬至5MIL. 3.加大文字框 4.移文字,看是否有鏡象字體 5.用防焊反套文字 6.加廠內料號及UL MARK 7.比對原稿 8.總測 9.加模序號
FP调试及其他注意事项 事先说明:调试并不是万能药,FP的调试系统有时并不稳定,如果感觉异常,或者变量一值处于无意义的随机值,或者F7单步模式下它拒绝进入自定义的函数或过程,一般需要你新启动FP再次开始重新调试,如果尝试多次仍然不行,那需要你重新安装Free pascal了,操作方法:先卸载FP,然后手工删除你FP的安装目录(一般是如C盘或D盘下的整个FPC文件夹),然后重新安装FP。1.确定fp处于Debug (调试)模式下,否则将可能无法显示一些诸如越界等错误。 1查看修改方法:Options菜单下-->Mode...后面是否为Debug如果不是,请单击修改为Debug。 2.调试说明A:设置要观察变量:一般用Ctrl+F7可以添加需要查看的变量,也可以单击Debug菜单下-->Watches打开watches窗口右击进行添加修改删除。可以直接添加变量名,也可添加数组名观察整个数组,甚至可以直接加a[i]的这种形式,观察数组中的某个元素。 B:调试方法(均在run菜单下):
F7单步模式,每次执行一条语句(确切的说是屏幕上的一行),运行时会在watches 窗口更新变量的值以供观察。 F8步进模式,每次执行一条语句,但不会深入到自定义的过程或函数中(F7会进入函数过程执行),只在主程序中按行调试执行。 F4Goto Cursor执行到光标处:调试前先将光标停在某行,然后按F4,程序自动在F4处停止,然后可以继续使用F7或F8进行调试,可以省下很多的时间。 复赛解题步骤
1、读题 2、构思策略方法 3、模拟样例数据 4、推举是否存在反例能推翻构思,如果是重新读题构思 5、建立数据结构,估算数据范围。 6、编制程序,使程序通过编译。 7、测试样例。 8、调试程序 根据源代码设计数据,尽可能让程序执行到每条语句(所有分支)。 调试数据选择: a样例b手工构造随机数据c边界数据d特殊构造数据 调试方法: (1)静态查错,直接即观察源代码,需要时打草稿。(不要一出错就跟踪) (2)动态跟踪,F7+Watches(仅在无法在静态差错中找到错误) 9、检查程序,调节优化,估算时间、空间使用情况,根据需要修改程序。 10、检查细节:输入文件名、文件夹。
FreePascal中的编译器选项 FreePascal中的编译器选项 2010-10-09 18:32:29| 分类: Win32Program |举报 |字号订阅编译器选项: 普通选项: -h 该选项将把所有的命令行选项列出来,然后退出程序 -? 同-H一样的,在分屏显示 -i 这个选项显示编译器版权信息,你能给一个选项,类似下面-ixxx D 返回编译器的日期 V 返回编译器版本 SO 返回编译器的系统版本 SP 返回编译器所选的处理器 TO 返回编译目标系统 TP 返回编译后目标处理器 -l 在标准出上显示Free Pascal的LOGO,同时告诉你Free Pascal的版本号 -n 告诉编译器并不要读入默认的配置文件,你仍
然可以通过@选项来使用配置文件编译器返回的信息: -vxxx xxx可以是下面的: e: 默认的选项,只显示错误 i: 只显示普通的信息 w: 显示警告 n: 显示注意 h: 显示提醒 l: 使用百分比显示错误行的位置 u: 显示加载的单元名称 t: 显示程序试图打开的文件 p: 显示过程和函数的名称 c: 告诉编译器警告你当它处理有条件时 m: 显示被定义的宏 d: 显示其它的调试信息 a: 显示所有的可能的信息 0: 不要任何信息. 当你想不使用配置文件中的默认设置时有用 b: 显示所有所有声明的过程如果一个重载函数出现错误 x: 输出一些执行信息(只对Win32系统游) r: Rhide/GCC兼容模式: 将错误整理以便RHIDE能够使用
V: 创建一个包含有很多调试信息的fpcdebug.txt,主要是给编译器开发者的关于路径及文件的选项 -exxx xxx指明可执行文件as (the assembler)和ld (the linker)的路径. -FaXYZ 在系统单元后但是在其他单元之前加载单元XYZ . XYZ 是一个用逗号分隔的单元名称列表. 只能用于程序,并且和把XYZ放在USES语句的一条效果一致. -FcXXX 设置输入代码页to XXX.还在试验中. -FD 和-e 一样. -Fexxx 将错误写入文件名为xxx的文件. -FExxx 将单元和可执行文件输出到目录xxx ,而不是当前目录. -Fixxx 将xxx作为包含文件的搜索目录 . -Flxxx 将xxx作为library查找路径, 被传给连接器. -FLxxx
Designer By:Anjie Date:2015-09-09 资料整理 1.检查整理资料(解压缩.zip,打印客户PDF等资料). 2.INPUT资料(注意钻孔D-CODE属性设置) 3.更改层命名,定义层属性及排序. 4.层对齐及归原点(最左下角). 5.存ORG. 整理原始网络 6.钻孔核对分孔图(MAP) 7.挑选成型线至outline层 8.工作层outline层移到0层. 9.整理钻孔(例如:将大于6.4mm钻孔移动到outline层, 其它层NPTH,SLOT移 动到DRL层) 10.整理成型线(断线、缺口、R8) 11.整理outline(将outline层需要钻孔的移动到drl层) 12.创建Profile. 13.板外物移动到0层. 14.核对0层成型线及板外物是否移除正确. 15.内层网络检查(如负性假性隔离) 16.防焊转PAD 17.线路转PAD
18.分析钻孔(检查线路PAD是否有漏孔、重孔修正,内层short) 19.定义SMD属性 20.存NET 21.打印原稿图纸. 编辑钻孔 22.补偿钻孔 (1)检查原始孔径是否正确(不能有“?”号) (2)合刀排序 (3)输入板厚与补偿值(PTH+4 /PTH+6) (4)定义钻孔属性(VIA,PTH,NPTH)主要定义VIA属性NPTH在整理原始网络前定义. (5)输入公差(注意单位). (6)检查最大与最小孔是否符合规范 (7)短SLOT孔分刀,8字孔分刀。(尾数+1 或-1) 23.校对钻孔中心(参照TOP防焊及TOP线路) 24.分析钻孔 25.短SLOT孔加预钻孔 26.挑选NPTH属性的孔移动到新建NPTH层. 内层负片编辑 1.检查有无负性物件(负性物件需要合并) 2.层属性是否为NEG 3.对齐钻孔(内层负片为影响层,参考钻孔层对齐)