Pascal 详解"指针类型"

我始终对Pascal里的指针类型不甚明白,在网上看了几篇教程反而更加糊涂(尤其是指向地址,递归定义).还请哪位有识之士讲解一哈,或者推荐几篇好的教程吧.最好能一同讲解哈指... 我始终对Pascal里的指针类型不甚明白,在网上看了几篇教程反而更加糊涂(尤其是指向地址,递归定义).还请哪位有识之士讲解一哈,或者推荐几篇好的教程吧.最好能一同讲解哈指针在数据结构中怎么用.谢 展开
 我来答
wy1234_123
2006-11-12 · TA获得超过114个赞
知道答主
回答量:26
采纳率:0%
帮助的人:0
展开全部
第十一章 指针类型

11.1 指针

11.2 单链表

11.1 指针

指针是通过地址来访问变量的一种特殊的数据类型,属于动态的数据结构,它可以在需要时产生,用完后则又可以取消或回收,以减少占用的内存空间。指针变量与其他类型的变量不同,它占有的不是数据,而是地址。
由于动态数据结构的变量是在程序执行过程中动态生成的,所以不能预先予以说明,无法预先给这些变量起名字,访问时也无法通过名字直接输出或显示,而只能用指针得到其地址,然后间接访问。

1、定义指针类型
在Turbo Pascal中,指针变量用来存放某个存储单元的地址,即指针变量指向某个存储单元。一个指针变量仅能指向某一种类型的存储单元,这种数据类型是在指针类型的定义中确定的,称为指针类型的基类型。指针类型定义如下:
类型名=^基类型名;
例如:type q=^integer;
var a,b,c:q;
说明:q是一指向整型存储单元的指针类型,其中"^"为指针符。a,b,c均定义为指针变量,分别可以指向一个整型存储单元。
上例也可用变量说明为:
var a,b,c:^integer;
指针也可以指向有结构的存储单元。
例如:type person=record
name:string[10];
sex:(male,female);
age:20..70
end;
var pt:^person;
pt为指向记录类型person的指针变量。
2、动态变量
应用一个指针指向的动态存储单元即动态变量的形式如下:
指针变量名^
例如:p^、q^、r^
指针变量p和它所指向的动态变量p^之间有如下关系:

以下语句把整数5存放到p所指向的动态变量p^中去:
p^:=5;
以下语句把p所指向的p^中的值赋给整型变量i:
i:=p^;
如果指针变量p并未指向任何存储单元,则可用下列赋值语句:
p:=nil;
其中nil是保留字,表示“空”,相当于C语言里面的null

3、对动态变量的操作
在Turob Pascal程序中,动态变量不能由var直接定义而是通过调用标准过程new建立的。过程形式为:
new(指针变量名);
如果有下列变量定义语句:
var p:^integer;
仅仅说明了p是一个指向整型变量单元的指针变量,但这个整型单元并不存在,在指针变量p中还没有具体的地址值。在程序中必须通过过程调用语句:new(p);才在内存中分配了一个整型变量单元,并把这个单元的地址放在变量p中,一个指针变量只能存放一个地址。在同一时间内一个指针只能指向一个变量单元。当程序再次执行new(p)时,又在内存中新建立了一个整型变量单元,并把新单元的地址存放在p中,从而丢失了旧的变量单元的地址。
为了节省内存空间,对于一些已经不使用的现有动态变量,应该使用标准过程dispose予以释放。过程形式为:dispose(指针变量名);为new(指针变量名)的逆过程,其作用是释放由指针变量所指向的动态变量的存储单元。例如在用了new(p)后在调用dispose(p),则指针p所指向的动态变量被撤销,内存空间还给系统,这时p的值为 nil。

4.需要注意之处
1、P与P^的区别
P是指向该动态变量的指针变量名,P^则称为动态变量或标志变量。P的值是P^的首地址,P^的值为与基类型相同的一个值。
2、定义后及时分配存储单元
定义了一个指针变量后,并没有为该指针分配动态存储单元,此时的P的值无定义,调用P^则会产生运行错误。若想使该指针可用,可以对指针赋值,也可以通过NEW()过程分配存储单元。
3、使用后及时收回存储单元
指针使用后,不会自动归还占用的存储空间,应及时使用DISPOSE()过程来释放P^所占用的存储单元,以免浪费有限的存储空间.

11.2 单链表

单链表的数据类型可定义如下:

type dlb=^node;

node=record

data:datatype;

next:dlb;

end;

例1 连续输入一序列整数,组成链表(并以动态的形式把它们记录下来),当输入的数为-1时,停止输入,然后把输入的整数按相反的顺序输出.

program lianbiao;
type link=^data;
data=record
num:integer;
next:link;
end;
var p,q:link;
i:integer;
begin
q:=nil;
readln(i);
while i<>-1 do

begin

new(p);
with p^ do
begin
num:=i;
next:=q;
end;
q:=p;
readln(i);

end;
while p<>nil do
begin
write(p^.num:6);
p:=p^.next;
end;
readln;
end.

练习:将例1中如果数据不按现反的顺序(按输入时的顺序)输出时,怎样建表.(程序)

上述建表方式其实就是分别从表头和表尾插入元素,下面是从表中插入元素;

例2:输入若干整数(输入32767停止输入)排序(小到大)输出之。

program lianbiao;
type link=^data;
data=record
num:integer;
next:link;
end;
var head,p,q,r:link;
i:integer;
begin
head:=nil;
readln(i);
while i<>32767 do
begin
new(p);
p^.num:=i;
p^.next:=nil;
if head=nil then begin head:=p;end
else
begin
q:=head;
if p^.num<q^.num then begin head:=p;p^.next:=q end else
begin
while (p^.num >=q^.num) and (q<>nil) do begin r:=q ;q:=q^.next;end;
if q=nil then r^.next:=p else begin r^.next:=p;p^.next:=q end
end;
end;
readln(i);
end;
p:=head;
while p<>nil do
begin
write(p^.num:6);
p:=p^.next;
end;
readln;
end.
zhouhylai
2006-11-10 · TA获得超过135个赞
知道答主
回答量:99
采纳率:0%
帮助的人:48.7万
展开全部
10.1 指针的动态变量

1.定义指针类型
在Turbo Pascal中,指针变量中存放的某个存储单元的地址,即指针变量指向某个存储单元。一个指针变量仅能指向某一种类型的存储单元,这种数据类型是在指针类型的定义中确定的,称为指针类型的基类型。指针类型定义如下:
类型名=^基类型名;
例如:type q=^integer;
var a,b,c:q;
说明q是一指向整型存储单元的指针类型,其中"^"为指针符。a,b,c均定义为指针变量,分别可以指向一个整型存储单元。
上例也可定义为:
var a,b,c:^integer;
指针也可以指向有结构的存储单元。
例如:type person=record
name:string[10];
sex:(male,female);
age:20..70
end;
var pt:^person;
pt为指向记录类型person的指针变量。
2.动态变量
应用一个指针指向的动态存储单元即动态变量的形式如下:
指针变量名^
例如:p^、q^、r^
指针变量p和它所指向的动态变量^p之间有如下关系:

以下语句把整数5存放到p所指向的动态变量p^ 中去:
p^:=5;
以下语句把p所指向的p^中的值赋给整型变量i:
i:=p^;
如果指针变量p并未指向任何存储单元,则可用下列赋值语句:
p:=nil;
其中nil是Turbo Pascal保留字,表示“空”,相当于C里面的null

10.2 对动态变量的操作

在Turob Pascal程序中,动态变量不能由var直接定义而是通过调用标准过程new建立的。过程形式为:
new(指针变量名);
如果有下列变量定义语句:
var p:^integer;
仅仅说明了p是一个指向整型变量单元的指针变量,但这个整型单元并不存在,在指针变量p中还没有具体的地址值。在程序中必须通过过程调用语句:new(p);才在内存中分配了一个整型变量单元,并把这个单元的地址放在变量p中,一个指针变量只能存放一个地址。在同一时间内一个指针只能指向一个变量单元。当程序再次执行new(p)时,又在内存中新建立了一个整型变量单元,并把新单元的地址存放在p中,从而丢失了旧的变量单元的地址。
为了节省内存空间,对于一些已经不使用的现有动态变量,应该使用标准过程dispose予以释放。过程形式为:dispose(指针变量名);为new(指针变量名)的逆过程,其作用是释放由指针变量所指向的动态变量的存储单元。例如在用了new(p)后在调用dispose(p),则指针p所指向的动态变量被撤销,内存空间还给系统,这时 p的值为 nil。

例:输入两个数,要求先打印大数后打印小数的方式输出,用动态变量做。
program dongtai;
type intepter=^integer;
var p1,p2:intepter;
procedure swap(var,q1,q2:intepter);
var p:integer;
begin
p:=q1;q1:=q2;q2:=p;
end;
begin
new(p1);new(p2);
writeln('input 2 data: ');readln(p1^,p2^);
if p1^<p2^ then swap(p1,p2);
writeln('output 2 data: ',p1^:4,p2^:$);
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
zjh777007
2006-11-09 · TA获得超过331个赞
知道小有建树答主
回答量:235
采纳率:0%
帮助的人:141万
展开全部
为什么要用指针类型

以前,程序中所用的各种类型的全程变量一经说明,就在内存中占有固定不变的存贮单元,一直保持到程序结束;而各种类型的局部变量在其作用域内一经说明也占有固定不变的存贮单元,直至退出作用域为止,这类变量不能在执行时随时分配存贮单元,也不能在不使用时将已占用的存贮单元释放掉,因而称为静态变量。静态变量在其存贮分配时具有一定局限性,例如程序中使用的数组必须一开始在说明时确定元素个数,如果数组定义太大,会浪费存贮空间,定义太小,则又会出现下标越界的错误。

Pascal提供了一种称为指针的类型,在程序执行时,通过指针实现动态存贮的目的。

第一节 动态变量

一 定义指针类型

在Pascal中,指针变量中存放的某个存贮单元的地址,即指针变量指向某个存贮单元。一个指针变量仅能指向某一种类型的存贮单元,这种数据类型是在指针类型的定义中确定的,称为指针类型的基类型。指针类型定义形式如下:

类型名=基类型名;

例如: type intepter=^integer;
var p,q,r:intepter;

说明:intepter是一指向整型存贮单元的指针类型,其中“^”为指针符。p,q,r 均定义为指针变量,分别可以指向一个整型存贮单元。

上例也可定义为: var p,q,r:^integer;

指针也可指向有结构的存贮单元,例如:
type person=record
name:string[10];
sex:(male,female);
age:20..60
end;
var pts:^person;
pts为指向记录类型person的指针变量。

二 动态变量
引用一个指针指向的动态存贮单元即动态变量的形式如下:
指针变量名^
例如: p^、q^、r^等等。

指针变量p与它所指示的动态变量p^之间的关系可用下图表示:

以下语句可把整数5存放到p所指向的动态变量p^中去:
p^:=5;

下列语句则可把p所指向的p^中的值赋给整型变量i中去:
i:=p^;

如果指针变量p并未指向任何存贮单元,则可用下列赋值语句:
p:=Nil;
其中Nil是Pascal保留字,表示“空”的意思,为唯一的一个指针类型常量。

第二节 对动态变量的操作

一 动态变量的建立和撤消

在Pascal程序中,动态变量不能由var定义而是通过调用标准过程new建立的。过程形式为:
new(指针变量名);

如果有下列变量定义语句: var p:^integer;
仅说明了p是一个指向整型变量单元的指针变量,但这个整型单元并不存在,在指针变量p中尚没有具体的地址值。在程序中必须通过过程调用语句:
new(p);
才在内存中分配了一个整型变量单元,并把这个单元的地址放在变量p中,一个指针变量只能存放一个地址。在同一时间内一个指针只能指向一个变量单元。当程序再次执行new(p)时,又在内存中新建立了一个整型变量单元,并把新单元的地址存放在p中,从而丢失了老的变量单元的地址。

为了节省内存空间,对于一些已不使用的现有动态变量,应该使用标准过程dispose予以释放。过程形式为:
dispose(指针变量名);
为new(指针变量名)的逆过程,其作用是释放由指针变量所指向的动态变量的存贮单元。
例如在用了new(p)后再调用dispose(p),则指针p所指向的动态变量被撤消,内存空间归还Pascal系统可作它用,这时p的值为Nil。

二 程序举例

1. 输入两个整数,要求先打印大数后打印小数的方式输出。

program ex11_1;
type intepter=^integer;
var p1,p2: intepter;
procedure swap(var q1,q2: intepter);
var p: intepter;
begin
p:=q1; q1:=q2; q2:=p;
end; {swap}
begin
new(p1); new(p2);
write('Input two data: '); readln(p1^ ,p2^ );
if p1^ <p2^ then swap(p1, p2);
writeln('Output two data: ',p1^ :4, p2^ :4);
end.

程序中用指针p1和p2指向整型动态变量p1^和p2^,当p1^的值小于p2^的值时,就执行过程swap(p1,p2),使p1总指向大数单元,在过程中所交换的是两个存贮单元的地址,而两个存贮单元中的值并未改变。

2. 输入n个字符串,请按从小到大的顺序打印输出字符串。

type str=string[20];
var s:array[1..11] of ^str;
i,j,n:integer;
begin
write(‘n(<=10)=’);readln(n);
for i:=1 to n+1 do new(s[i]);
for i:=1 to n do readln(s[i] ^);
for i:=1 to n-1 do
for j:=i+1 to n do
if s[i] ^>s[j] ^ then
begin
s[11]:=s[i];
s[i]:=s[j];
s[j]:=s[11]
end;
for i:=1 to n do writeln(s[i] ^);
end.

同例1一样,过程swap只是交换了p1,p2中的地址值,但并未改变指向的字符串变量的值。这种方式的交换避免了大量字符串移动的操作,从而能提高程序运行的效率。

写出下列程序的结果:
1.
type pt= ^integer;
var p1,p2: pt;
begin
new (p1);
p1^:=5;
p2 :=p1;
new(p2);
p2^:=5;
if p1=p2 then writeln(‘p1=p2’)
else writeln(‘p1<> p2’);
if p1^ =p2^ then writeln(‘p1^=p2^’)
else writeln(‘p1^<>p2^’);
end.

2.
type
pt= ^integer;
var
p1,p2: pt;
begin
new (p1);
p1^:=5;
p2 :=p1;
new(p2);
p2^:=5;
if p1=p2 then writeln(‘p1=p2’)
else writeln(‘p1<> p2’);
if p1^ =p2^ then writeln(‘p1^=p2^’)
else writeln(‘p1^<>p2^’);
end.

写出下列程序的结果:
(1)
var
p1,p2,p3:^integer;
begin
new(p1);
p1^:=5;
new(p2);
p2^:=8;
p1^:=p1^+p2^;
writeln(p1^:8,p2^);
end.

(2)
var
p1,p2,p3:^integer;
begin
new(p1);
new(p2);
p1^:=9;
p2^:=5*(p1^ mod 5);
p3:=p1;p1:=p2;p2:=p3;
writeln(p1^:6,p2^:6,p3^);
end.

(3)
type
rec=record
a:integer;
b:char;
end;
var
p1,p2:^rec;
begin
new(p1); new(p2);
p1^.a:=90; p1^.b:=’B’;
p2^.a:=100;p2^.b:=’C’;
p1:=p2;
writeln(p1^.a:6,p2^.a);
end.

指针练习
例1:设有类型定义和变量说明:
type link=^integer;
var p1,p2:link;
n:integer;
以下过程首部:
procedure p1(var p:link;I,j:integer);
则合法的调用过程是 。
A. p1(p1^,p2,n);
B. p1(p1,p2^,3);
C. p1(p1,p2,2.0);
D. p1(p1^,p2^,n);

例2:指针变量的基类型不能是 。
A.顺序类型 B.构造类型 C.实数类型 D.指针类型

例3:下面的类型定义正确的是 。
A. type
Link=^p;
P=record
Name:packed array [1..100] of char;
Next:^p;
End;
B. type
Link=^p;
P=record
Name:packed array [1..100] of Boolean;
Next:^link;
End;
C. type
Link=^p;
P=record
Name:packed array[1..100] of real;
Next:link;
End;
D. type
P=record
Name:packed array [1..100] of integer;
Next:link
Link=^p;
End;
例4:设有说明VAR p1,p2:^integer;若在内存中开辟两个存储单元,并使其内容均为1,则应采用的语句组为 。
A. p1^:=1;p2^:=1;
B. new(p2);p1^:=1;p2:=p1;
C. new(p1);p1^:=1;new(p2);p2^:=1;
D. new(p1);p1^:=1;p2^:=p1^;

例5:设有变量说明如下:
var p,q:^integer;
s:array [2..19] of integer;
则下面的 语句是合法的。
A. p^:=5;q^:=7;s[p]:=q;
B. p^:=5;q^:=7;s[p]:=q^;
C. p^:=5;q^:=7;s[p^]:=q;
D. p^:=5;q^:=7;s[p^]:=q^;

例6:设有说明:
var p1,p2:^integer;
则下面程序段的运行结果是 。
new(p1);
p1^:=5;
p2:=p1;
new(p1);
p1^:=p2^+3;
writeln(p1^,p2^);

作业:(h6041401)
1.
设有类型定义和变量说明:
type t=^integer;
var p,q:t;
以下过程首部:
procedure pr(a:integer;q:t);
则合法的调用过程是 。
A. pr(p,q);
B. pr(p^,q^);
C. pr(p^,q);
D. pr(p,q^);

3.
program allie(output);
type p=^integer;
var p1,p2:p;
begin
new(p1);
p1^:=4;
p2:=p1;
new(p2);
p2^:=4;
if p1=p2 then writeln('p1=p2')
else writeln('p1<>p2')
if p1^=p2^ then writeln('p1^=p2^)
else writeln('p1^<>p2^')
end.
程序运行结果为 。
A. p1<>p2 p1^=p2^
B. p1=p2 p1^=p2^
C. p1=p2 p1^<>p2^
E. p1<>p2 p1^<>p2^

4.
program pro(input,output);
var p1,p2,p3:^integer;
begin
new(p1);
new(p2);
p1^:=783 mod 10+round(2.91);
p2^:=p1^ div 3+2;
p3:=p1;p1=p2;p2:=p3
writeln(p1^:5,p2^:5,p3^:5);
end.

5.
设有以下说明
var n:integer;
p,q:^integer;
且各变量已赋值,则以下语句不合法的是 。
a.q:=p b.p:=n c.p^:=q^ d.n:=p^

11.
设有说明var p1,p2:^integer;若p1,p2已建立,且有赋值语句p1^:=10;p2^:=20;用矩形表示内存单元,矩形框内数字表示内存单元内容,则实现如图所示的操作可用赋值语句 。
A.p1^:=p2^ B.p1:=p2 C.p1:=p2^ D.p1^:=p2

14.
program s(input,output);
var p1,p2,p3:^integer;
begin
new(p1);new(p2);
p1^:=5
p2^:=p1^ mod 2;
if p1^<>p2^ then p3:=p1
else p3:=p2;
writeln(p1^,p2^,p3^)
end.
运行结果 。
A.515 B.511 C.121 D.522

第十届全国青少年信息学奥林匹克联赛复赛试题
( 提高组 )津津的储蓄计划 (save.pas/dpr/c/cpp)
【问题描述】
津津的零花钱一直都是自己管理。每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。
为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上20%还给津津。因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于100元或恰好100元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。
例如11月初津津手中还有83元,妈妈给了津津300元。津津预计11月的花销是180元,那么她就会在妈妈那里存200元,自己留下183元。到了11月月末,津津手中会剩下3元钱。
津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。
现在请你根据2004年1月到12月每个月津津的预算,判断会不会出现这种情况。如果不会,计算到2004年年末,妈妈将津津平常存的钱加上20%还给津津之后,津津手中会有多少钱。
【输入文件】
输入文件save.in包括12行数据,每行包含一个小于350的非负整数,分别表示1月到12月津津的预算。
【输出文件】
输出文件save.out包括一行,这一行只包含一个整数。如果储蓄计划实施过程中出现某个月钱不够用的情况,输出-X,X表示出现这种情况的第一个月;否则输出到2004年年末津津手中会有多少钱。
【样例输入1】
290
230
280
200
300
170
340
50
90
80
200
60
【样例输出1】
-7
【样例输入2】
290
230
280
200
300
170
330
50
90
80
200
60
【样例输出2】
1580
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
揭绮波Ic
2006-11-11 · 超过19用户采纳过TA的回答
知道答主
回答量:154
采纳率:0%
帮助的人:58.8万
展开全部
为什么要用指针类型

以前,程序中所用的各种类型的全程变量一经说明,就在内存中占有固定不变的存贮单元,一直保持到程序结束;而各种类型的局部变量在其作用域内一经说明也占有固定不变的存贮单元,直至退出作用域为止,这类变量不能在执行时随时分配存贮单元,也不能在不使用时将已占用的存贮单元释放掉,因而称为静态变量。静态变量在其存贮分配时具有一定局限性,例如程序中使用的数组必须一开始在说明时确定元素个数,如果数组定义太大,会浪费存贮空间,定义太小,则又会出现下标越界的错误。

Pascal提供了一种称为指针的类型,在程序执行时,通过指针实现动态存贮的目的。

第一节 动态变量

一 定义指针类型

在Pascal中,指针变量中存放的某个存贮单元的地址,即指针变量指向某个存贮单元。一个指针变量仅能指向某一种类型的存贮单元,这种数据类型是在指针类型的定义中确定的,称为指针类型的基类型。指针类型定义形式如下:

类型名=基类型名;

例如: type intepter=^integer;
var p,q,r:intepter;

说明:intepter是一指向整型存贮单元的指针类型,其中“^”为指针符。p,q,r 均定义为指针变量,分别可以指向一个整型存贮单元。

上例也可定义为: var p,q,r:^integer;

指针也可指向有结构的存贮单元,例如:
type person=record
name:string[10];
sex:(male,female);
age:20..60
end;
var pts:^person;
pts为指向记录类型person的指针变量。

二 动态变量
引用一个指针指向的动态存贮单元即动态变量的形式如下:
指针变量名^
例如: p^、q^、r^等等。

指针变量p与它所指示的动态变量p^之间的关系可用下图表示:

以下语句可把整数5存放到p所指向的动态变量p^中去:
p^:=5;

下列语句则可把p所指向的p^中的值赋给整型变量i中去:
i:=p^;

如果指针变量p并未指向任何存贮单元,则可用下列赋值语句:
p:=Nil;
其中Nil是Pascal保留字,表示“空”的意思,为唯一的一个指针类型常量。

第二节 对动态变量的操作

一 动态变量的建立和撤消

在Pascal程序中,动态变量不能由var定义而是通过调用标准过程new建立的。过程形式为:
new(指针变量名);

如果有下列变量定义语句: var p:^integer;
仅说明了p是一个指向整型变量单元的指针变量,但这个整型单元并不存在,在指针变量p中尚没有具体的地址值。在程序中必须通过过程调用语句:
new(p);
才在内存中分配了一个整型变量单元,并把这个单元的地址放在变量p中,一个指针变量只能存放一个地址。在同一时间内一个指针只能指向一个变量单元。当程序再次执行new(p)时,又在内存中新建立了一个整型变量单元,并把新单元的地址存放在p中,从而丢失了老的变量单元的地址。

为了节省内存空间,对于一些已不使用的现有动态变量,应该使用标准过程dispose予以释放。过程形式为:
dispose(指针变量名);
为new(指针变量名)的逆过程,其作用是释放由指针变量所指向的动态变量的存贮单元。
例如在用了new(p)后再调用dispose(p),则指针p所指向的动态变量被撤消,内存空间归还Pascal系统可作它用,这时p的值为Nil。

二 程序举例

1. 输入两个整数,要求先打印大数后打印小数的方式输出。

program ex11_1;
type intepter=^integer;
var p1,p2: intepter;
procedure swap(var q1,q2: intepter);
var p: intepter;
begin
p:=q1; q1:=q2; q2:=p;
end; {swap}
begin
new(p1); new(p2);
write('Input two data: '); readln(p1^ ,p2^ );
if p1^ <p2^ then swap(p1, p2);
writeln('Output two data: ',p1^ :4, p2^ :4);
end.

程序中用指针p1和p2指向整型动态变量p1^和p2^,当p1^的值小于p2^的值时,就执行过程swap(p1,p2),使p1总指向大数单元,在过程中所交换的是两个存贮单元的地址,而两个存贮单元中的值并未改变。

2. 输入n个字符串,请按从小到大的顺序打印输出字符串。

type str=string[20];
var s:array[1..11] of ^str;
i,j,n:integer;
begin
write(‘n(<=10)=’);readln(n);
for i:=1 to n+1 do new(s[i]);
for i:=1 to n do readln(s[i] ^);
for i:=1 to n-1 do
for j:=i+1 to n do
if s[i] ^>s[j] ^ then
begin
s[11]:=s[i];
s[i]:=s[j];
s[j]:=s[11]
end;
for i:=1 to n do writeln(s[i] ^);
end.

同例1一样,过程swap只是交换了p1,p2中的地址值,但并未改变指向的字符串变量的值。这种方式的交换避免了大量字符串移动的操作,从而能提高程序运行的效率。

写出下列程序的结果:
1.
type pt= ^integer;
var p1,p2: pt;
begin
new (p1);
p1^:=5;
p2 :=p1;
new(p2);
p2^:=5;
if p1=p2 then writeln(‘p1=p2’)
else writeln(‘p1<> p2’);
if p1^ =p2^ then writeln(‘p1^=p2^’)
else writeln(‘p1^<>p2^’);
end.

2.
type
pt= ^integer;
var
p1,p2: pt;
begin
new (p1);
p1^:=5;
p2 :=p1;
new(p2);
p2^:=5;
if p1=p2 then writeln(‘p1=p2’)
else writeln(‘p1<> p2’);
if p1^ =p2^ then writeln(‘p1^=p2^’)
else writeln(‘p1^<>p2^’);
end.

写出下列程序的结果:
(1)
var
p1,p2,p3:^integer;
begin
new(p1);
p1^:=5;
new(p2);
p2^:=8;
p1^:=p1^+p2^;
writeln(p1^:8,p2^);
end.

(2)
var
p1,p2,p3:^integer;
begin
new(p1);
new(p2);
p1^:=9;
p2^:=5*(p1^ mod 5);
p3:=p1;p1:=p2;p2:=p3;
writeln(p1^:6,p2^:6,p3^);
end.

(3)
type
rec=record
a:integer;
b:char;
end;
var
p1,p2:^rec;
begin
new(p1); new(p2);
p1^.a:=90; p1^.b:=’B’;
p2^.a:=100;p2^.b:=’C’;
p1:=p2;
writeln(p1^.a:6,p2^.a);
end.

指针练习
例1:设有类型定义和变量说明:
type link=^integer;
var p1,p2:link;
n:integer;
以下过程首部:
procedure p1(var p:link;I,j:integer);
则合法的调用过程是 。
A. p1(p1^,p2,n);
B. p1(p1,p2^,3);
C. p1(p1,p2,2.0);
D. p1(p1^,p2^,n);

例2:指针变量的基类型不能是 。
A.顺序类型 B.构造类型 C.实数类型 D.指针类型

例3:下面的类型定义正确的是 。
A. type
Link=^p;
P=record
Name:packed array [1..100] of char;
Next:^p;
End;
B. type
Link=^p;
P=record
Name:packed array [1..100] of Boolean;
Next:^link;
End;
C. type
Link=^p;
P=record
Name:packed array[1..100] of real;
Next:link;
End;
D. type
P=record
Name:packed array [1..100] of integer;
Next:link
Link=^p;
End;
例4:设有说明VAR p1,p2:^integer;若在内存中开辟两个存储单元,并使其内容均为1,则应采用的语句组为 。
A. p1^:=1;p2^:=1;
B. new(p2);p1^:=1;p2:=p1;
C. new(p1);p1^:=1;new(p2);p2^:=1;
D. new(p1);p1^:=1;p2^:=p1^;

例5:设有变量说明如下:
var p,q:^integer;
s:array [2..19] of integer;
则下面的 语句是合法的。
A. p^:=5;q^:=7;s[p]:=q;
B. p^:=5;q^:=7;s[p]:=q^;
C. p^:=5;q^:=7;s[p^]:=q;
D. p^:=5;q^:=7;s[p^]:=q^;

例6:设有说明:
var p1,p2:^integer;
则下面程序段的运行结果是 。
new(p1);
p1^:=5;
p2:=p1;
new(p1);
p1^:=p2^+3;
writeln(p1^,p2^);

作业:(h6041401)
1.
设有类型定义和变量说明:
type t=^integer;
var p,q:t;
以下过程首部:
procedure pr(a:integer;q:t);
则合法的调用过程是 。
A. pr(p,q);
B. pr(p^,q^);
C. pr(p^,q);
D. pr(p,q^);

3.
program allie(output);
type p=^integer;
var p1,p2:p;
begin
new(p1);
p1^:=4;
p2:=p1;
new(p2);
p2^:=4;
if p1=p2 then writeln('p1=p2')
else writeln('p1<>p2')
if p1^=p2^ then writeln('p1^=p2^)
else writeln('p1^<>p2^')
end.
程序运行结果为 。
A. p1<>p2 p1^=p2^
B. p1=p2 p1^=p2^
C. p1=p2 p1^<>p2^
E. p1<>p2 p1^<>p2^

4.
program pro(input,output);
var p1,p2,p3:^integer;
begin
new(p1);
new(p2);
p1^:=783 mod 10+round(2.91);
p2^:=p1^ div 3+2;
p3:=p1;p1=p2;p2:=p3
writeln(p1^:5,p2^:5,p3^:5);
end.

5.
设有以下说明
var n:integer;
p,q:^integer;
且各变量已赋值,则以下语句不合法的是 。
a.q:=p b.p:=n c.p^:=q^ d.n:=p^

11.
设有说明var p1,p2:^integer;若p1,p2已建立,且有赋值语句p1^:=10;p2^:=20;用矩形表示内存单元,矩形框内数字表示内存单元内容,则实现如图所示的操作可用赋值语句 。
A.p1^:=p2^ B.p1:=p2 C.p1:=p2^ D.p1^:=p2

14.
program s(input,output);
var p1,p2,p3:^integer;
begin
new(p1);new(p2);
p1^:=5
p2^:=p1^ mod 2;
if p1^<>p2^ then p3:=p1
else p3:=p2;
writeln(p1^,p2^,p3^)
end.
运行结果 。
A.515 B.511 C.121 D.522

第十届全国青少年信息学奥林匹克联赛复赛试题
( 提高组 )津津的储蓄计划 (save.pas/dpr/c/cpp)
【问题描述】
津津的零花钱一直都是自己管理。每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。
为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上20%还给津津。因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于100元或恰好100元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。
例如11月初津津手中还有83元,妈妈给了津津300元。津津预计11月的花销是180元,那么她就会在妈妈那里存200元,自己留下183元。到了11月月末,津津手中会剩下3元钱。
津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。
现在请你根据2004年1月到12月每个月津津的预算,判断会不会出现这种情况。如果不会,计算到2004年年末,妈妈将津津平常存的钱加上20%还给津津之后,津津手中会有多少钱。
【输入文件】
输入文件save.in包括12行数据,每行包含一个小于350的非负整数,分别表示1月到12月津津的预算。
【输出文件】
输出文件save.out包括一行,这一行只包含一个整数。如果储蓄计划实施过程中出现某个月钱不够用的情况,输出-X,X表示出现这种情况的第一个月;否则输出到2004年年末津津手中会有多少钱。
【样例输入1】
290
230
280
200
300
170
340
50
90
80
200
60
【样例输出1】
-7
【样例输入2】
290
230
280
200
300
170
330
50
90
80
200
60
【样例输出2】
1580
回答者:zjh777007 - 助理 二级 11-9 13:13

10.1 指针的动态变量

1.定义指针类型
在Turbo Pascal中,指针变量中存放的某个存储单元的地址,即指针变量指向某个存储单元。一个指针变量仅能指向某一种类型的存储单元,这种数据类型是在指针类型的定义中确定的,称为指针类型的基类型。指针类型定义如下:
类型名=^基类型名;
例如:type q=^integer;
var a,b,c:q;
说明q是一指向整型存储单元的指针类型,其中"^"为指针符。a,b,c均定义为指针变量,分别可以指向一个整型存储单元。
上例也可定义为:
var a,b,c:^integer;
指针也可以指向有结构的存储单元。
例如:type person=record
name:string[10];
sex:(male,female);
age:20..70
end;
var pt:^person;
pt为指向记录类型person的指针变量。
2.动态变量
应用一个指针指向的动态存储单元即动态变量的形式如下:
指针变量名^
例如:p^、q^、r^
指针变量p和它所指向的动态变量^p之间有如下关系:

以下语句把整数5存放到p所指向的动态变量p^ 中去:
p^:=5;
以下语句把p所指向的p^中的值赋给整型变量i:
i:=p^;
如果指针变量p并未指向任何存储单元,则可用下列赋值语句:
p:=nil;
其中nil是Turbo Pascal保留字,表示“空”,相当于C里面的null

10.2 对动态变量的操作

在Turob Pascal程序中,动态变量不能由var直接定义而是通过调用标准过程new建立的。过程形式为:
new(指针变量名);
如果有下列变量定义语句:
var p:^integer;
仅仅说明了p是一个指向整型变量单元的指针变量,但这个整型单元并不存在,在指针变量p中还没有具体的地址值。在程序中必须通过过程调用语句:new(p);才在内存中分配了一个整型变量单元,并把这个单元的地址放在变量p中,一个指针变量只能存放一个地址。在同一时间内一个指针只能指向一个变量单元。当程序再次执行new(p)时,又在内存中新建立了一个整型变量单元,并把新单元的地址存放在p中,从而丢失了旧的变量单元的地址。
为了节省内存空间,对于一些已经不使用的现有动态变量,应该使用标准过程dispose予以释放。过程形式为:dispose(指针变量名);为new(指针变量名)的逆过程,其作用是释放由指针变量所指向的动态变量的存储单元。例如在用了new(p)后在调用dispose(p),则指针p所指向的动态变量被撤销,内存空间还给系统,这时 p的值为 nil。

例:输入两个数,要求先打印大数后打印小数的方式输出,用动态变量做。
program dongtai;
type intepter=^integer;
var p1,p2:intepter;
procedure swap(var,q1,q2:intepter);
var p:integer;
begin
p:=q1;q1:=q2;q2:=p;
end;
begin
new(p1);new(p2);
writeln('input 2 data: ');readln(p1^,p2^);
if p1^<p2^ then swap(p1,p2);
writeln('output 2 data: ',p1^:4,p2^:$);
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式