C語言結構體的運用與總結歸納(struct學習必備)
一、什么是結構體
結構體(struct):是在C語言編程中,一種用戶自定義可使用的數據類型,且是由多個相同或不同數據類型的數據項構成的一個集合。所有的數據項組合起來表示一條記錄。(如:學生的結構體,數據項有學號、姓名、班級等等)
常用於定義的數據項類型:char、int、short、long、float、double、數組、指針、結構體等等。(結構體的成員變量數據類型)
二、結構體定義的方式
1.結構定義步驟:①使用結構體struct語句(形式如下) ②確定定義結構體的內容 ③完成定義
struct 結構體名稱{
char a;
int b; //a,b,c……皆為結構體成員變量(結構體內容)
double c;
…………
}結構體變量;
PS:結構體名稱、結構體內容、結構體變量,三者必有其二才能構成結構體。
2.結構定義方式
例:學生結構體 (snumber為學號,sname為姓名,sclass為班級)
(1) 一般定義方式:
#include<stdio.h>
/*最標准的定義方式*/
struct Student{ //結構體定義與變量聲明分開
char snumber[16];
char sname[12];
char sclass[8];
};
int main(){
struct Student s1 = {"100001","張三","一班"};//聲明結構體變量
printf("%s %s %s\n",s1.snumber,s1.sname,s1.sclass);//打印
return 0;
}
PS:結構體定義的時候不定義變量。(最常用的定義方式)
(2) 一般不用的定義方式:
#include<stdio.h>
/*一般不用的定義方式*/
struct Student{ //結構體定義與變量聲明一起
char snumber[16];
char sname[12];
char sclass[8];
}s1 = {"100001","張三","一班"}; //聲明結構體變量s1
int main(){
printf("%s %s %s\n",s1.snumber,s1.sname,s1.sclass);//打印 s1
struct Student s2 = {"100002","李四","二班"};//聲明結構體變量s2
printf("%s %s %s",s2.snumber,s2.sname,s2.sclass);//打印 s2
return 0;
}
PS:結構體定義的時候聲明變量。
(3) 最不提倡用的定義方式:
#include<stdio.h>
/*最不提倡用的定義方式*/
struct{ //結構體定義與變量聲明一起,但沒有結構體名稱
char snumber[16];
char sname[12];
char sclass[8];
}s1 = {"100001","張三","一班"};//此結構體就只能用一次
int main(){
printf("%s %s %s\n",s1.snumber,s1.sname,s1.sclass);//打印
return 0;
}
PS:結構體定義的時候無結構體名稱。(即此結構體只能用一次,浪費資源)
(4) 帶 typedef 的結構體:
①typedef 關鍵字作用:相當於給已有的數據類型取個其它的名字。如下:(使用方法)
#include<stdio.h>
typedef int ZhengShu;//給 int 取個新名字 ZhengShu
int main(){
ZhengShu a = 2;//聲明整數變量
printf("%d",a); //打印
return 0;
}
//結果輸出為:2
②使用 typedef 定義的結構體:(三種方法等價,書上常見第一種*)*
//第一種
/*用 typedef 定義結構體,無結構體名稱*/
typedef struct{
char snumber[16];
char sname[12];
char sclass[8];
}SStudent; //給結構體取別名
//第二種
/*用 typedef 定義結構體,有結構體名稱*/
typedef struct Student{
char snumber[16];
char sname[12];
char sclass[8];
}SStudent; //給結構體取別名
//第三種
/*一般定義結構體的方法,之后再用 typedef*/
struct Student{
char snumber[16];
char sname[12];
char sclass[8];
};
typedef struct Student SStudent;//用 typedef 給結構體取別名
/*以上三種結構體聲明變量的方法相同*/
int main(){
SStudent s1 = {"100001","張三","一班"}; //聲明一個結構體變量
printf("%s %s %s\n",s1.snumber,s1.sname,s1.sclass);//打印
return 0;
}
結果:
PS:以上三種定義方法都可以用在實際編寫代碼中,且三種方法等價;具體用哪一種,因個人習慣和偏愛而因人而異。(吾比較喜歡第三種!)
三、結構體中使用結構體
1.結構體定義中使用其他結構體:
#include<stdio.h>
struct Score{ //成績結構體
int Math;
int Chinese;
int English;
};
/*Score結構體必須比Student先定義或聲明*/
struct Student{ //學生結構體
char snumber[16];
char sname[12];
char sclass[8];
struct Score sscore;
};
//用 typedef 給結構體取別名
typedef struct Student SStudent;
typedef struct Score SScore;
int main(){
SScore score = {92,88,82}; //聲明一個成績結構體變量
SStudent s1 = {"100001","張三","一班",score}; //聲明學生一個結構體變量,並存入成績
printf("信息:%s %s %s\n 成績:%d %d %d\n",s1.snumber,s1.sname,s1.sclass, //打印學生信息
s1.sscore.Math,s1.sscore.Chinese,s1.sscore.English); //打印成績
return 0;
}
結果:
2.兩個結構體定義相互調用:
#include<stdio.h>
/*一般很少用,了解定義結構就行了*/
struct B;//結構體 B 必須有不完整聲明
struct A{
struct B *p; //結構體 A 中有結構體 B 的指針
};
struct B{
struct A *p; //結構體 B 中有結構體 A 的指針
};
3.結構體定義中使用自身結構體 (鏈表的結構體定義,后面有完整的鏈表創建使用方法)
#include<stdio.h>
/*簡單地創建使用鏈表*/
struct Node{ //結構體中使用自身結構體
int velue;
struct Node *next;//結構體指針 (struct可以省略)
};
四、結構體指針
1.普通指針:是一種用來存放內存地址的變量。(如下)
#include<stdio.h>
/*指針的簡單使用*/
int main(){
int x = 6;
int *p; //一個整型指針
p = &x;
printf(" 整數的地址:%p\n p指針存儲的地址:%p\n p指針自己的地址:%p",&x,p,&p);
return 0;
}
結果:
2.結構體指針 (配合 結構體中使用的結構體的方法一起創建 鏈表)
#include<stdio.h>
#include <stdlib.h>
/*簡單地創建使用鏈表*/
struct Node{ //結構體中使用自身結構體
int velue;
struct Node *next;//結構體指針 (struct可以省略)
};
//用 typedef 給結構體取別名
typedef struct Node* list; //鏈表
typedef struct Node Node_p; //節點
//創建鏈表
list MakeList(){
Node_p* head = (Node_p*)malloc(sizeof(struct Node));//結構體指針
if(head == NULL)printf("內存不足!");
//頭節點
head->velue = 0;
head->next = NULL;
return head;
}
//判空
bool IsEmpty(list L){
return L->next == NULL;
}
//插入
void Insert(int x,list L){
Node_p *temp,*p;//結構體指針
temp = L;
//到達位節點處
while(temp->next != NULL)temp = temp->next;
//動態分配空間
p = (Node_p*)malloc(sizeof(struct Node));
if(p == NULL)printf("內存不足!");
//插入節點
p->velue = x;
p->next = NULL;
temp->next = p;
}
//遍歷
void PrintAll(list L){
Node_p* temp = L->next;
int i = 1;
while(temp != NULL){
printf("第%d次=%d\n",i,temp->velue);
temp = temp->next;
i++;
}
}
//主函數
int main(){
list L;
L = MakeList();
//判斷表是否為空
if(IsEmpty(L))printf("此鏈表為空!\n");
//添加元素
for(int i = 1;i <= 5; i++){
Insert(i,L);
}
//遍歷(彈棧)
PrintAll(L);
return 0;
}
結果:
五、如何訪問結構體變量
1.結構體訪問成員變量時的符號:
①" . "(點)
②" → "(箭頭)
2.使用方法 (要訪問結構體成員時)
①如果是結構體指針,則用箭頭運算符訪問。
②如果是結構體一般變量,則用點運算符。
PS:對比上面 學生結構體 和 鏈表結構體 ,試着交換一下訪問符號試試。