指向結構體變量的指針與鏈表結構的關系應用
1、 一個結構體變量的指針就是該變量所占據的內存段的起始地址。可以設一個指針變量,用來指向一個結構體變量,此時該指針變量的值是結構體變量的其實地址。指針變量也可以用來指向結構體數組的元素。
例如:聲明一個結構體Student類型,定義一個Student結構體類型變量stu,聲明一個Student指針*p指向stu的地址,我們可以通過stu調用Student結構體類型的成員變量,相應的,因為*p指向stu的內存的起始位置,所以我們可以通過調用*p來調用stu的成員變量,例如:(*p).name,(*p).age來賦值操作等等,注意*p的括號不可省略,因為成員運算符”.”優先級大於”*”。
2、 指向運算符:
為了使用方便直觀,C++提供了指向結構體變量的運算符->,例如:p->num表示指向p當前指向的結構體變量中的成員num。p->num和(*p).num等價。
總結:如下三種形式等價:
結構體變量.成員名。如stu.num
(*p).成員名。如:(*p).num
p->成員名。如p->num。”->”稱為指向運算符。
分析如下幾種運算:
p->n:得到p指向的結構體變量中的成員n的值
p->n++:得到p指向的結構體變量中的成員
n的值,用完該值後使它加1.
++p->n:得到p指向的結構體變量中的成員n的值,並使之加1然後再使用。
3、 用結構體變量和指向結構體變量的指針構成鏈表
a) 鏈表是一種常見的重要的數據結構。
b) 鏈表有一個“頭指針“變量,用來存放一個地址。該地址指向一個元素。鏈表中的每一個元素稱為”結點“,每個結點都應包括兩個部分:一是用戶需要用的實際數據,二是下一個結點的地址。最後一個元素不再指向其他元素,稱為”表尾“,它的地址部分放一個”NULL“(空地址),鏈表到此結束。
c) 鏈表中各元素在內存中的存儲單元可以是不連續的。查找元素可以通過前後鏈表之間的關系查找,前一個鏈表的第二個元素的地址是下一個鏈表的第一個元素。
d) 這種鏈表的數據結構,必須利用結構體變量和指針才能實現。可以聲明一個結構體類型,包含兩種成員,一種是用戶需要用的實際數據,另一種是用來存放下一個結點地址的指針變量。例如:
struct Student
{
int num;
float score;
Student*next;
};
其中成員num和score是用戶需用用到的數據,next是指針類型的成員,指向Student類型數據,用來存放下一個結點的地址。設計者不必知道各個結點的具體地址,只要保證能將下一個節點的地址放到前一個結點的成員next中即可。
建立並輸出一個簡單鏈表:
/*
*table.cpp
*
* Created on: 2012-4-8
* Author: David
*/
#define NULL 0
#include<iostream>
struct Student
{
long num;
float score;
struct Student *next;
};
int main()
{
Studenta,b,c,*head,*p;
a.num=31001;a.score=89.5;//對結點a的num和score成員賦值
b.num=31003;b.score=90;//對結點b的num和score成員賦值
c.num=31007;c.score=85;//對結點c的num和score成員賦值
head=&a; //將結點a的起始地址賦給頭指針head
a.next=&b; //將結點b的起始地址賦給a結點的next成員
b.next=&c; //將結點b的起始地址賦給b結點的next成員
c.next=NULL;//結點的next成員不存放其他結點地址
p=head; //將p指針指向a結點
do
{
cout<<p->num<<""<<p->score<<endl; //輸出p指向的結點的數據
p=p->next; //使p指向下一個結點
}
while(p!=NULL); //輸出完c結點後p的值為NULL
return 0;
}
開始時使head指向a結點,a.next指向b結點,b.next指向c結點,這就構成鏈表關系。第一行用#define命令定義了符號常量NULL代表0,在16行將0地址賦給c.next的作用是使c.next不指向任何有用的存儲單元。
4、 靜態鏈表:所有結點(結構體變量)都是在程序中定義的,不是臨時開辟的,也不用用完後釋放,這種鏈表稱為靜態鏈表。
5、 動態鏈表:各結點是可以隨時插入和刪除的,這些結點並沒有變量名,只能先找到上一個結點,才能根據它提供的下一結點的地址找到下一個結點。
6、 只提供第一個結點的地址叫做頭指針head,只有有了頭指針,鏈表才能訪問整個鏈表。