C語言struct結構體全面學習
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:對比上面 學生結構體 和 連結串列結構體 ,試著交換一下訪問符號試試。