概述
1.结构体的定义和引用
1.1 定义结构体数据类型
语法结构:
struct 结构体名{
成员表
}
- struct为结构体类型标识符,定义和使用时不能省略
- 结构体名可以省略,此时定义的结构体成为无名结构体。
使用例子:
struct info{
char name[20];
char sex;
int age;
};
假设int类型占2个字节,则info结构体占23个字节。
1.2 定义结构体变量
原则:要先定义结构体类型,再定义结构体变量
1.2.1 在定义结构体类型时定义结构体变量
语法结构:
struct 结构体名{
成员表
}结构体变量1,结构体变量2,...,结构体变量n;
例子:
// 例子1(正常写法):
struct info{
char name[20];
char sex;
int age;
} info1,info2;
// 例子2(省略结构体名称):
struct {
char name[20];
char sex;
int age;
} info1,info2;
// 例子3(结构体数组,省略结构体名):
struct {
int year;
int month;
int day;
} date1[10],date2[10],*p=date1;
1.2.2 使用时定义结构体变量
语法:
struct 结构体类型名称 结构体变量名;
例子:
struct info info1,info2;
1.3 结构体变量的引用
语法1:
结构体变量名.成员名称
//调用例子
info1.age
//进行赋值
info1.age=25;
语法2:
结构体数组名[下标].成员名
//调用例子
date[1].year
//进行赋值
date[1].year=2001;
语法3:
指针->成员名
//调用例子
p->year
//进行赋值
p->year=2001;
1.4 结构体变量的初始化
1.4.1 结构体定义时直接进行初始化
struct info{
char name[20];
char sex;
int age;
} info1={'张三','M',25};
1.4.2 使用时进行初始化
struct date{
int year;
int month;
int day;
} ;
//结构体变量
struct date date1={2010,1,1};
// 结构体数组变量
struct date date1[3]={{2012,1,1},{2014,1,1},{2016,1,1}};
2.结构体使用的完整步骤
结构体在实际运用时,要进行定义结构体数据类型、定义结构体变量、结构体变量赋值(或初始化)等步骤,以下是完整调用的例子,供参考。
2.1 普通结构体使用
#include<stdio.h>
#include<string.h>
void main(){
// 定义结构体数据类型
struct date{
int year;
int month;
int day;
char creator[20];
};
// 定义结构体变量,并进行初始化
struct date date1={2020, 9, 27, "张三"};
// 引用结构体变量的值
printf("%s创建的数据: %4d-%02d-%02dn", date1.creator, date1.year, date1.month, date1.day);
// 修改结构体变量的值
date1.day=date1.day - 1;
//字符串类型修改值需要用strcpy函数
strcpy(date1.creator, "李四");
// 引用修改后的结构体变量的值
printf("%s创建的数据,昨天是:%4d-%02d-%02dn", date1.creator, date1.year, date1.month, date1.day);
// 附加部分:在进行定义时,只定义部分值
struct date date2={2020,9};
printf("%4d-%02d-%02dn", date2.year, date2.month, date2.day);
}
2.2 结构体指针变量的使用
#include<stdio.h>
struct student {
int num;
char name[20];
char sex;
int score;
};
void main(){
struct student *p, *q;
struct student stu1 = {1, "张三", 'M', 90};
struct student info[10]={2, "李四", 'F', 85, 3, "王五", 'F', 76};
p = &stu1;
q = info;
printf("stu1的学号为: %d ,姓名是:%s, 性别为%c, 成绩为%dn", stu1.num, stu1.name, p->sex, p->score);
printf("info类表索引为1的学号为: %d ,姓名是:%s, 性别为%c, 成绩为%dn", info[1].num, (q + 1)->name, (info + 1) -> sex, q[1].score);
printf("info类表索引为1的学号为: %d ,姓名是:%s, 性别为%c, 成绩为%dn", (&info[1])->num, (&info[0] + 1)->name, (*(info + 1)).sex,(*(&info[1])).score);
printf("info类表索引为1的学号为: %d ,姓名是:%s, 性别为%c, 成绩为%dn", (*(q + 1)).num, (*(&q[0] + 1)).name, (*(&q[1])).sex, (&q[0] + 1)->score);
printf("info类型索引为1的学号为: %dn",(&q[1])->num);
}
3.结构体案例分享
3.1 管理学生成绩
#include<stdio.h>
#define N 5
struct student {
int num;
char name[20];
char sex;
int score;
} stu[N];
void main(){
int i, ave = 0, max_v = -1, min_v = 101;
for (i = 0; i < N; i++){
printf("请输出第 %-2d名学生的信息,依次输出(学号 姓名 性别 成绩):n", i + 1);
scanf("%d %s %c %d", &stu[i].num, stu[i].name, &stu[i].sex, &stu[i].score);
//printf("第 %-2d名学生的信息,依次输出(学号、姓名、性别和成绩): %d、%s、%c、 %dn", i + 1, stu[i].num, stu[i].name, stu[i].sex, stu[i].score);
ave += stu[i].score;
if (min_v > stu[i].score) min_v = stu[i].score;
if (max_v < stu[i].score) max_v = stu[i].score;
}
ave = ave / N;
printf("学生的平均成绩为:%dn",ave);
printf("学生的最高成绩为:%dn",max_v);
printf("学生的最低成绩为:%dn",min_v);
printf("以下学生的成绩超过平均值:n");
for (i = 0; i < N; i++){
if (stu[i].score > ave)
printf("%-20s%dn", stu[i].name, stu[i].score);
}
}
3.2 循环打印学生信息
#include<stdio.h>
#define N 3
struct student {
int num;
char name[20];
int score;
} stu[N]={1, "张三", 68, 2, "李四", 87, 3, "王五", 85};
void output(struct student *p, int n){
struct student *q ;
q = p + N;
for (; p < q; p++){
printf("学号: %d 姓名: %20s 分数: %3dn", p->num, p->name, p->score);
}
}
void output2(struct student *p, int n){
int i = 0;
for (i = 0; i < N; i++,p++){
printf("学号: %d 姓名: %20s 分数: %3dn", p->num, p->name, p->score);
}
}
void main(){
output(stu, N);
printf("-------分割线---------n");
output2(stu,N);
}
4.结构体的重要引用——链表
链表是非固定长度的数据结构,具备动态存储的技术,即需要时申请内存空间,不需要时释放空间。比较适用于数据个数可变的数据存储。
4.1头插法与尾插法
以下头插法和尾插法均不包含头结点
// 创建链表head,类型struct note *,存储1-100
#include<stdio.h>
#include<stdlib.h>
#define N 100
struct node {
int num;
struct node *next;
};
struct node *createList(struct node *head, int n){
//创建链表,头插法;
struct node *new;
head = (struct node *)malloc(sizeof(struct node));
if (head == NULL) exit(-1);
head->num = 1;
head->next= NULL;
for (int i = 2; i <= n; i++){
new = (struct node *)malloc(sizeof(struct node));
if (new == NULL) exit(-1);
new->num = i;
new->next = head;
head = new;
}
return head;
}
struct node *createlist_tail( struct node *head, int n){
//尾插法
struct node *new, *p; //new为新创建的地址,p用来记录刚创建好的地址
if (n >= 1){
new = (struct node *)malloc(sizeof(struct node));
new->num = 1;
head = new;
p = new;
}
for (int i = 2; i <= n; i++){
new = (struct node *)malloc(sizeof(struct node));
new->num = i;
p->next = new;
p = new;
}
if (n >= 1) return head;
else return NULL;
}
void output(struct node *head){
struct node *p;
if (head != NULL){
p = head;
while (p != NULL){
printf("%3dn", p->num);
p = p->next;
}
}
}
void main(){
struct node *head = NULL;
// 头插法
//head = createList(head, N);
//尾插法
head = createlist_tail(head, N);
output(head);
}
由于struct node 写起来过于麻烦,可以借助typedef方法来进行简化。以下为使用的例子:
STU与struct node相等
pSTU与 stuct node *与 STU *相等
// 创建链表head,类型struct note *,存储1-100
#include<stdio.h>
#include<stdlib.h>
#define N 100
typedef struct node {
int num;
struct node *next;
}STU, *pSTU;
pSTU createList(pSTU head, int n){
//创建链表,头插法;
pSTU new;
head = (pSTU)malloc(sizeof(STU));
if (head == NULL) exit(-1);
head->num = 1;
head->next= NULL;
for (int i = 2; i <= n; i++){
new = (pSTU)malloc(sizeof(STU));
if (new == NULL) exit(-1);
new->num = i;
new->next = head;
head = new;
}
return head;
}
pSTU createlist_tail( pSTU head, int n){
//尾插法
pSTU new, p; //new为新创建的地址,p用来记录刚创建好的地址
if (n >= 1){
new = (pSTU)malloc(sizeof(STU));
new->num = 1;
head = new;
p = new;
}
for (int i = 2; i <= n; i++){
new = (pSTU)malloc(sizeof(STU));
new->num = i;
p->next = new;
p = new;
}
if (n >= 1) return head;
else return NULL;
}
void output(pSTU head){
pSTU p;
if (head != NULL){
p = head;
while (p != NULL){
printf("%3dn", p->num);
p = p->next;
}
}
}
void main(){
pSTU head = NULL;
// 头插法
//head = createList(head, N);
//尾插法
head = createlist_tail(head, N);
output(head);
}
4.2 链表的删除
void delete(pSTU head, pSTU p){
pSTU o;
if (head == NULL) return; //如果head为空指针,直接返回
if (head == p) {
head = p->next; //若要删除的为第一个元素,则直接进行更改
printf("删除后的第一个元素的值为:%dn", head->data);
}
else{
o = head;
while (o->next != p){ //若非删除的位置,则继续查找
o = o->next;
}
o->next = p->next; //找到对应位置后,将前一个内存位置(o)标识为p的下一个内存空间。
}
free(p); //释放内存空间
}
最后
以上就是懵懂花卷为你收集整理的C语言中的结构体详解及应用注意事项的全部内容,希望文章能够帮你解决C语言中的结构体详解及应用注意事项所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复