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:对比上面 学生结构体 和 链表结构体 ,试着交换一下访问符号试试。