青少年信息学竞赛Pascal语言:指针(十) 标签:信息学
<p><strong>优学合肥奥数网讯:</strong>合肥市青少年信息学竞赛Pascal语言:指针</p><p>指针</p><p>指针是通过地址来访问变量的一种特殊的数据类型,属于动态的数据结构,它可以在需要时产生,用完后则又可以取消或回收,以减少占用的内存空间。指针变量与其他类型的变量不同,它占有的不是数据,而是地址。</p><p>由于动态数据结构的变量是在程序执行过程中动态生成的,所以不能预先予以说明,无法预先给这些变量起名字,访问时也无法通过名字直接输出或显示,而只能用指针得到其地址,然后间接访问。</p><p>1、定义指针类型</p><p>在Turbo Pascal中,指针变量用来存放某个存储单元的地址,即指针变量指向某个存储单元。一个指针变量仅能指向某一种类型的存储单元,这种数据类型是在指针类型的定义中确定的,称为指针类型的基类型。指针类型定义如下:</p><p>类型名=^基类型名;</p><p>例如:type q=^integer;</p><p>var a,b,c:q;</p><p>说明:q是一指向整型存储单元的指针类型,其中"^"为指针符。a,b,c均定义为指针变量,分别可以指向一个整型存储单元。</p><p>上例也可用变量说明为:</p><p>var a,b,c:^integer;</p><p>指针也可以指向有结构的存储单元。</p><p>例如:type person=record</p><p>name:string;</p><p>sex:(male,female);</p><p>age:20..70</p><p>end;</p><p>var pt:^person;</p><p>pt为指向记录类型person的指针变量。</p><p>2、动态变量</p><p>应用一个指针指向的动态存储单元即动态变量的形式如下:</p><p>指针变量名^</p><p>例如:p^、q^、r^</p><p>指针变量p和它所指向的动态变量p^之间有如下关系:</p><p>以下语句把整数5存放到p所指向的动态变量p^中去:</p><p>p^:=5;</p><p>以下语句把p所指向的p^中的值赋给整型变量i:</p><p>i:=p^;</p><p>如果指针变量p并未指向任何存储单元,则可用下列赋值语句:</p><p>p:=nil;</p><p>其中nil是保留字,表示“空”,相当于C语言里面的null</p><p>3、对动态变量的操作</p><p>在Turob Pascal程序中,动态变量不能由var直接定义而是通过调用标准过程new建立的。过程形式为:</p><p>new(指针变量名);</p><p>如果有下列变量定义语句:</p><p>var p:^integer;</p><p>仅仅说明了p是一个指向整型变量单元的指针变量,但这个整型单元并不存在,在指针变量p中还没有具体的地址值。在程序中必须通过过程调用语句:new(p);才在内存中分配了一个整型变量单元,并把这个单元的地址放在变量p中,一个指针变量只能存放一个地址。在同一时间内一个指针只能指向一个变量单元。当程序再次执行new(p)时,又在内存中新建立了一个整型变量单元,并把新单元的地址存放在p中,从而丢失了旧的变量单元的地址。</p><p>为了节省内存空间,对于一些已经不使用的现有动态变量,应该使用标准过程dispose予以释放。过程形式为:dispose(指针变量名);为new(指针变量名)的逆过程,其作用是释放由指针变量所指向的动态变量的存储单元。例如在用了new(p)后在调用dispose(p),则指针p所指向的动态变量被撤销,内存空间还给系统,这时p的值为 nil。</p><p>4.需要注意之处</p><p>1、P与P^的区别</p><p>P是指向该动态变量的指针变量名,P^则称为动态变量或标志变量。P的值是P^的首地址,P^的值为与基类型相同的一个值。</p><p>2、定义后及时分配存储单元</p><p>定义了一个指针变量后,并没有为该指针分配动态存储单元,此时的P的值无定义,调用P^则会产生运行错误。若想使该指针可用,可以对指针赋值,也可以通过NEW()过程分配存储单元。</p><p>3、使用后及时收回存储单元</p><p>指针使用后,不会自动归还占用的存储空间,应及时使用DISPOSE()过程来释放P^所占用的存储单元,以免浪费有限的存储空间.</p><p>单链表</p><p>单链表的数据类型可定义如下:</p><p>type dlb=^node;</p><p>node=record</p><p>data:datatype;</p><p>next:dlb;</p><p>end;</p><p>例1 连续输入一序列整数,组成链表(并以动态的形式把它们记录下来),当输入的数为-1时,停止输入,然后把输入的整数按相反的顺序输出.</p><p>program lianbiao;</p><p>type link=^data;</p><p>data=record</p><p>num:integer;</p><p>next:link;</p><p>end;</p><p>var p,q:link;</p><p>i:integer;</p><p>begin</p><p>q:=nil;</p><p>readln(i);</p><p>while i<>-1 do</p><p>begin</p><p>new(p);</p><p>with p^ do</p><p>begin</p><p>num:=i;</p><p>next:=q;</p><p>end;</p><p>q:=p;</p><p>readln(i);</p><p>end;</p><p>while p<>nil do</p><p>begin</p><p>write(p^.num:6);</p><p>p:=p^.next;</p><p>end;</p><p>readln;</p><p>end.</p><p>练习:将例1中如果数据不按现反的顺序(按输入时的顺序)输出时,怎样建表.</p><p>程序:</p><p>建链表与顺序遍历:</p><p>program lianbiao;</p><p>type link=^data;</p><p>data=record</p><p>num:integer;</p><p>next:link;</p><p>end;</p><p>var head,p,tail:link;</p><p>i:integer;</p><p>begin</p><p>head:=nil;</p><p>readln(i);</p><p>while i<>-1 do</p><p>begin</p><p>new(p);</p><p>p^.num:=i;</p><p>p^.next:=nil;</p><p>if head=nil then begin head:=p; tail:=p end</p><p>else begin tail^.next:=p; tail:=p end;</p><p>readln(i);</p><p>end;</p><p>p:=head;</p><p>while p<>nil do</p><p>begin</p><p>write(p^.num:6);</p><p>p:=p^.next;</p><p>end;</p><p>readln;</p><p>end.</p><p>上述建表方式其实就是分别从表头和表尾插入元素,下面是从表中插入元素;</p><p>例2:输入若干整数(输入20237停止输入)排序(小到大)输出之。</p><p>program lianbiao;</p><p>type link=^data;</p><p>data=record</p><p>num:integer;</p><p>next:link;</p><p>end;</p><p>var head,p,q,r:link;</p><p>i:integer;</p><p>begin</p><p>head:=nil;</p><p>readln(i);</p><p>while i<>20237 do</p><p>begin</p><p>new(p);</p><p>p^.num:=i;</p><p>p^.next:=nil;</p><p>if head=nil then begin head:=p;end</p><p>else</p><p>begin</p><p>q:=head;</p><p>if p^.num<q^.num then begin head:=p;p^.next:=q endelse</p><p>begin</p><p>while (p^.num >=q^.num) and (q<>nil) do begin r:=q ;q:=q^.next;end;</p><p>if q=nil then r^.next:=p else begin r^.next:=p;p^.next:=q end</p><p>end;</p><p>end;</p><p>readln(i);</p><p>end;</p><p>p:=head;</p><p>while p<>nil do</p><p>begin</p><p>write(p^.num:6);</p><p>p:=p^.next;</p><p>end;</p><p>readln;</p><p>end.</p><p>练习:建立一个若干整数的链表后(-1结束)再从链表中删除从键盘上输入一个整数的所有结点.</p><p>程序:</p><p>链表的删除程序如下:</p><p>program lianbiao;</p><p>type link=^data;</p><p>data=record</p><p>num:integer;</p><p>next:link;</p><p>end;</p><p>var head,p,tail,r:link;</p><p>i,x:integer;</p><p>begin</p><p>writeln('input lbdata:');</p><p>head:=nil;</p><p>readln(i);</p><p>while i<>-1 do</p><p>begin</p><p>new(p);</p><p>p^.num:=i;</p><p>p^.next:=nil;</p><p>if head=nil then begin head:=p; tail:=p end</p><p>else begin tail^.next:=p; tail:=p end;</p><p>readln(i);</p><p>end;</p><p>write('input delete integer:');</p><p>readln(x);</p><p>p:=head;</p><p>while p<>nil do</p><p>begin</p><p>if p^.num=x then</p><p>if p=head then begin head:=p^.next;p:=head end</p><p>else if p^.next<>nilthen</p><p>begin r^.next:=p^.next ;p:=p^.next end</p><p>else</p><p>begin r^.next:=nil;p:=nil end</p><p>else begin r:=p;p:=p^.next end;</p><p>end;</p><p>p:=head;</p><p>while p<>nil do</p><p>begin</p><p>write(p^.num:6);</p><p>p:=p^.next;</p><p>end;</p><p>readln;</p><p>end.</p><p><strong>往期最新阅读</strong>:信息学竞赛Pascal语言:集合类型(八)</p><p>信息学竞赛Pascal语言:记录与文件类型(九)</p><p>更多内容,请参加优学合肥奥数网“<strong>杯赛竞赛</strong>”频道。</p>
页:
[1]