吳昊 朱林麗
[摘 要]本文主要對C程序中引用結構體類型數據中成員的一些方法做了比較詳細的探討,分析了使用結構體變量和指針變量引用成員的區別,并結合具體案例,讓初學者對結構體成員的引用有進一步認識。
[關鍵詞]C程序;結構體變量;指針變量;成員
doi:10.3969/j.issn.1673 - 0194.2021.04.105
[中圖分類號]G642[文獻標識碼]A[文章編號]1673-0194(2021)04-0-02
0 ? ? 引 言
結構體類型是C語言程序設計課程中比較重要的一種構造性數據類型,這種數據類型是由多個成員構成,一般用來定義結點型的數據類型。雖然結構體類型的數據中所有的成員是一個整體,但對成員不可以整體訪問,只能單獨訪問。一般對成員的訪問有兩種方式,一種是使用“.”,一種是使用“->”。然而在實際的教學中,有許多學生容易混淆這兩種引用方式,不能很好地理解結構體變量和結構體指針變量在訪問成員時的具體指向,從而導致學生在編寫涉及結構體數據類型的程序時遇到許多麻煩。為了幫助初學者在學習C語言程序設計這門課程時,能夠對通過結構體變量引用成員和通過結構體指針變量引用成員這兩種方式有更深的了解,本文將做比較詳細的探討。
1 ? ? 結構體類型
1.1 ? 結構體數據類型的聲明
結構體數據類型與基本的數據類型(如整形、字符型、浮點型)是有區別的,基本的數據類型是由系統定義的,用戶可以直接使用,而結構體數據類型是由用戶根據解決問題的實際需要自己聲明[2]。聲明結構體數據類型的一般形式如下。
struct 結構體名
{ 成員表列 };
例如,一名學生包含學號、姓名、性別、年齡和專業等一些基本信息,則聲明學生結構體數據類型如下。
struct ?student
{
int ?num; ? ? ? ? //學號
char ?name[10]; ? //姓名
char ?sex; ? ? ? ?//性別
int ?age; ? ? ? ? //年齡
char ?pro[20]; ? ?//專業
};
1.2 ? 結構體變量和結構體指針變量的定義
聲明好結構體數據類型以后,就可以使用它來定義結構體變量或結構體指針變量。例如,利用上面已經聲明好的學生結構體數據類型來定義結構體變量p和指針變量q的形式為:
struct ?student ?p, *q;
此外,還可以在聲明類型的同時定義變量或指針變量,因此,利用學生結構體數據類型定義結構體變量p和指針變量q,還可以表示為:
struct ?student
{
int ?num;
char ?name[10];
char ?sex;
int ?age;
char ?pro[20];
} p, *q;
2 ? ? 引用結構體數據成員的方法
定義好結構體變量或指針變量以后,就可以通過它們來引用結構體數據中的成員,引用結構體數據成員主要有以下3種方法。
2.1 ? 通過結構體變量來引用成員
使用結構體變量來引用成員是通過“.”來實現的,且它引用的是自己的成員,如文中第二部分定義的p是一個結構體變量,引用結構體變量p中的成員可表示:p.num,p.name,p.sex,p.age,p.pro。
2.2 ? 通過結構體指針變量和“->”來引用成員
結構體指針變量只能存儲和它同類型的變量或存儲單元的地址,它沒有自己的成員,在使用結構體指針變量之前,必須把同類型的變量的地址或動態創建的同類型的存儲單元(用malloc函數創建)的地址賦值給它,讓它有所指向,否則使用結構體指針變量是無意義的。當結構體指針變量有指向以后,可以通過“->”來引用指針變量所指向的變量或存儲單元中的成員。如文中第二部分定義的q是一個結構體指針變量,而p是一個結構體變量,如果把p的地址賦值給q(即q=& p),則可通過q來引用p中的成員,使用q來引用結構體變量p中的成員可表示為:q->num,q->name,q->sex,q->age,q->pro。
2.3 ? 通過結構體指針變量和“.”來引用成員
當把變量的地址賦值給同類型的指針變量以后(指針變量指向該變量),“*指針變量”和“變量”的作用是一樣的,如文中第二部分定義的變量p和指針變量q,如果把p的地址賦值給q(即q=& p),則*q的作用相當于p,使用q來引用結構體變量p中的成員可表示為:(*q).num,(*q).name,(*q).sex,(*q).age,(*q).pro。(注:在C語言程序中,由于“.”的優先級比“*”的優先級高,故*q外面的括號不可以省略)
3 ? ? 具體的案例實現
以創建一個具有三個結點的單鏈表為例,分別介紹以結構體變量創建、結構體變量加指針變量創建以及結構體變量加動態開辟存儲單元創建的3種情況,單鏈表的結點是一個結構體類型,主要包括整形的數據成員和指針成員,結點的結構體類型聲明如下。
struct ?node
{
int ?data;
struct ?node ?*next;
};
3.1 ? 結構體變量創建單鏈表
void main()
{
struct ?node ?a1,a2,a3;
scanf(“%d%d%d”,&a1.data, &a2.data, &a3.data);
a1.next=&a2; ?//把a2鏈在a1的后面
a2.next=&a3; ?//把a3鏈在a2的后面
a3.next=NULL; //最后一個結點的指針成員賦值為空
}
注:a1,a2,a3定義的是結構體變量,所以在程序中都是用“.”來引用成員
3.2 ? 結構體變量加指針變量創建單鏈表
void main()
{
struct ?node ?a1,a2,a3,*t1,*t2,*t3;
t1=&a1; ?t2=&a2; ? t3=&a3; ?//分別把a1、a2、a3的地址賦值給t1、t2、t3
scanf(“%d%d%d”,&t1->data, &t2->data, &t3->data);
t1->next=t2; ?//把t2所指結點鏈在t1所指向結點之后
t2->next=t3; ?//把t3所指結點鏈在t2所指向結點之后
t3->next=NULL; //最后一個結點的指針成員賦值為空
}
注:t1,t2,t3定義的是結構體指針變量,所以在程序中都是用“->”來引用成員
3.3 ? 結構體變量加動態開辟存儲單元創建單鏈表
void main()
{
/* h和r分別指向鏈表的頭結點和最后一個結點,t指向新建的結點*/
struct ?node ?*t,*r,*h;
int ?i=1;
while(i<=3) ?//判斷循環的次數
{
t=(* struct ?node)malloc(sizeof(struct ?node)); ?//新建一個結點
scanf(“%d”,&t->data);
if(i==1) ?//如果創建的是第一個結點
{
h=r=t; ?// h和r都指向該結點
continue;
}
r->next=t; ?//把t所指向的結點插到r所指向結點的后面
r=t; ? ?//讓r重新指向鏈表中最后一個結點
}
r->next=NULL; ?//最后一個結點的指針成員賦值為空
}
注:t,r,h定義的是結構體指針變量,所以在程序中都是用“->”來引用成員
以上3種方法雖然都可以創建一個具有三個結點的單鏈表,但不難發現,第一、第二兩種方法在創建單鏈表時需要定義結構體變量,鏈表中有多少個結點就需要定義多少個結構體變量,而第三種方法不需要定義結構體變量,只需使用malloc函數創建結點即可,需要多少建多少,程序設計比前兩種方法要靈活許多。
4 ? ? 結 語
本文主要對C程序中使用結構體變量和指針變量來引用成員的兩種情況做了較詳細的分析和總結,在引用結構體成員時,一定要注意變量引用和指針變量引用兩者之間的區別,即變量引用成員使用的是“.”,用的是自己的成員,而指針變量可以使用 “->”或 “(*指針變量).成員”的方式來引用它所指向的結構體變量或存儲單元的成員,用的不是自己的成員。
主要參考文獻
[1]譚浩強.C程序設計[M].第5版.北京:清華大學出版社,2017:309-314.
[2]王敬.用C語言結構體類型指針實現數據結構鏈表操作[J].數字技術與應用,2013(4):165-166.