新手c语言讲解及题目分享(十五)--结构体专项练习

目录

前言

一.结构体

1.结构体一般形式:

2.定义结构体变量:

Ⅰ.先声明结构体类型,再定义变量:

Ⅱ.在声明结构体类型的同时定义变量:

Ⅲ.不包含结构体类型名,直接定义结构体类型变量:

3.引用结构体变量:

4.定义结构体数组:

Ⅰ.先定义结构体类型,后定义结构体数组:

Ⅱ.在定义结构体类型的同时定义结构体数组:

Ⅲ.直接定义结构体数组:

5.指向结构体变量的指针:

6.结构体变量作为函数参数:

7.结构体指针作为函数参数:

二.共用体

1.定义共用体变量:

Ⅰ.先定义共用体类型再定义共用体变量:

Ⅱ.在定义共用体类型的同时声明共用体变量:

Ⅲ.直接定义共用体类型的变量:

2.引用共用体变量:

三.经验总结和题目分享

1.经验总结:

2.题目分享:

题目1:定义一个学生结构体,包含学生的姓名、年龄和成绩。编写一个函数,该函数接受一个学生结构体数组和学生数量作为参数,并打印出所有成绩高于平均分的学生信息。

题目2:定义一个表示日期的结构体,并编写一个函数来比较两个日期的大小。

题目3:定义一个表示点的结构体,包含二维坐标(x, y)。编写一个函数,该函数接受两个点的结构体,并计算两点之间的距离。

题目4:定义一个表示矩形的结构体,包含长度和宽度。编写一个函数,该函数接受一个矩形结构体,并计算矩形的面积。

题目5:定义一个表示复数的结构体,包含实部和虚部。编写一个函数,该函数接受两个复数结构体,并计算它们的和。

题目6:定义一个表示时间的结构体,包含小时、分钟和秒。编写一个函数,该函数接受一个时间结构体,并将时间转换为总秒数。


前言

C 语言定义的数据类型有固定的类型说明符、数据长度、数据组织和存储形式,程序设 计者可在程序中直接用它们来定义数据对象。在实际的应用中这些数据类型是不够的,人们 常需要定义新的数据类型来满足问题求解的需要。为满足这类问题的需要,C 语言允许用户 自定义数据类型,并用它们来定义与之相关的对象,把关系密切的多种不同类型的数据组成 一个整体,用一种复杂构造的数据类型来描述它。

本人每天不定时分享一些自己以往总结的笔记,本文的笔记均是由王学艳主编的《c语言程序设计》整理而来。

一.结构体

结构体是一种“构造”而成的数据类型(即自定义数据类型),在说明和使用之前必须 先定义(构造)它,其用途是把不同类型的数据组合成一个整体。

1.结构体一般形式:

定义一个结构体类型的一般形式为:

struct 结构体名

{

成员说明表列;

};

其中,struct 是关键字,作为定义结构体数据类型的标志;结构体名,由用户自行定义; 花括号“{}”内是结构体的成员表列,说明结构体所包含的成员及其数据类型。

注:(1)struct 是定义结构体类型的关键字,结构体名是由程序设计者按 C 语言标识符 命名规则指定的;

(2)成员说明表列由若干个成员组成,每个成员是该结构体的一个组成部分,必须 作类型说明。

(3)最后一个花括号外的分号“;”不能省略,否则将引起编译错误。

2.定义结构体变量:

结构体定义之后,即可进行变量定义。

Ⅰ.先声明结构体类型,再定义变量:
struct student 
{ 
 int num; 
 char name[20]; 
 char sex; 
 int age; 
 float score; 
 char addr[30]; 
}; 
struct student stu1,stu2;

struct student 是结构体类型名,而 stu1 和 stu2 是结构体变量名,由于使用相同的 struct student 类型定义的变量,这两个变量就具有相同的结构。 为了使规模较大的程序更便于修改和使用,常常将结构体类型的声明放在一个头文件 中,这样在其他源文件中需要使用该结构体类型时,可以用#include 命令将该头文件包含到 源文件中。

Ⅱ.在声明结构体类型的同时定义变量:

struct 结构体名

{

成员列表;

}变量名列表;

在一般形式中将定义的变量名称放在声明结构体的末尾处。定义的变量不是只能有一 个,可以定义多个变量。

Ⅲ.不包含结构体类型名,直接定义结构体类型变量:
struct 
{ 
 int num; 
 char name[20]; 
 char sex; 
 int age; 
 float score; 
 char address[20]; 
}student1,student2; 

这种方法一般适合一次性使用指定变量,不适合重复说明。结构体中的成员可以单独使 用,作用相当于普通变量。成员名可以和程序中的变量名相同,但互不影响。

注:(1)结构体类型与结构体变量是不同的概念。定义一个结构体类型,系统并不分配 内存单元存放成员说明表列中说明的各数据项成员,只有在声明该结构体变量后,才分 配存储单元。

(2)结构体变量中的成员可以单独使用,作用与地位与普通变量相同。

(3)结构体成员名与程序中变量名可重名,两者不代表同一对象。例如,在程序中 声明一个变量 num,它与 struct student 类型变量中的 num 是不同的。

3.引用结构体变量:

在 ANSI C 中除了允许具有相同类型的结构体变量相互赋值外,一般对结构体变量的使 用,包括赋值、输入、输出、运算等都是通过结构体变量的成员来实现的。

利用结构体变量名引用其成员的一般形式为: 结构体变量名.成员名

例如,student1.num 表示引用结构体变量 student1 中的 num 成员,该成员的类型为 int, 可以对它进行 int 型变量的运算。

如果一个结构体类型中嵌套了结构体类型,则访问一个成员时,应采取逐级访问的方 法,直到得到所需访问的成员为止。 对结构体变量的成员进行各种有关的运算时,允许运算的种类与相同类型的简单变量的 种类相同。 结构体变量和其他变量一样,可以在声明变量的同时进行初始化。在初始化时,按照所 定义的结构体类型的数据结构,依次写出各初始值,在编译时将其赋给给此变量中的成员。

4.定义结构体数组:

元素为结构体类型的数组称为结构体数组,结构体数组的每一个元素都是具有相同类型 的结构体变量。在实际应用中,经常用结构体数组来表示具有相同数据结构的群体,如一个 学生的序号、年龄、性别等。假设有 20 个学生的信息需要存储,可以采用结构体数组。结 构体数组的定义方法与结构体变量相同。

Ⅰ.先定义结构体类型,后定义结构体数组:
struct student 
{ 
 int num; 
 char name[20]; 
 char sex; 
 int age; 
}; 
struct student stu[20]; 
Ⅱ.在定义结构体类型的同时定义结构体数组:
struct student 
{ 
 int num; 
 char name[20]; 
 char sex; 
 int age; 
}stu[20]; 
Ⅲ.直接定义结构体数组:
struct 
{ 
 int num; 
 char name[20]; 
 char sex; 
 int age; 
}stu[20]; 

5.指向结构体变量的指针:

结构指针变量说明的一般形式为:

struct 结构体名 *结构体指针变量名;

例如,在前面的例题中定义了结构体 stu,如要说明一个指向 stu 的指针变量 pstu,可写为: struct stu *pstu; 当然也可在定义 stu 结构的同时说明 pstu。结构体指针变量也必须要赋值后才能使用。 结构体名和结构体变量是两个不同的概念,不能混淆。结构体名只能表示一个结构体形 式,编译系统并不对它分配内存空间。只有当某变量被说明为这种类型的结构体时,才对该 变量分配存储空间,有了结构体指针变量,就能更方便地访问结构变量的各个成员。

其访问的一般形式为:

(*结构指针变量).成员名

或为:

结构指针变量->成员名

注:(1)“结构体指针变量.成员名”中的圆括号是必须的,因为运算符“*”的优先级 低于运算符“.”。如去掉括号写作*pstu.num 则等效于*(pstu.num),这样,意义就完全 不同了。

(2)习惯采用运算符“—>”来访问结构体变量的各个成员。

6.结构体变量作为函数参数:

结构体变量作为函数参数的用法与普通变量类似,都需要保证主调函数的实参类型和被 调用函数的形参类型相同。

7.结构体指针作为函数参数:

在 ANSI C 标准中允许用结构体变量作为函数参数进行整体传送,但是这种传送要将全 部成员逐个传送,传送的时间和空间开销很大,降低了程序的执行效率。使用指针指针变量 作函数参数进行传送时,由实参传向形参的只是地址,可以减少时间和空间的开销。

二.共用体

在 C 语言中,还有另外一种和结构体非常类似的语法,叫做共用体,

它的定义格式为:

union 共用体名 {

类型标识符 成员名;

类型标识符 成员名;

……………

};

共用体也被称为联合或者联合体,这也是 union 的本意。

1.定义共用体变量:

Ⅰ.先定义共用体类型再定义共用体变量:
union data 
{ 
 int i; 
 char ch; 
 float f; 
}; 
union data a,b,c; 
Ⅱ.在定义共用体类型的同时声明共用体变量:
union data 
{ 
 int i; 
 char ch; 
 float f; 
}a,b,c; 
Ⅲ.直接定义共用体类型的变量:
union 
{ 
 int i; 
 char ch; 
 float f; 
}a,b,c; 


2.引用共用体变量:

在共用体变量定义的同时,只能为第 1 个成员类型的值进行初始化。

共用体变量初始化 的方式如下:

union 共用体类型名 共用体变量={第 1 个成员的类型值};

三.经验总结和题目分享

1.经验总结:


在学习C语言结构体时,关键在于理解和掌握结构体的定义、初始化、访问以及结构体数组与指针的操作。通过实际编写代码,将结构体应用于解决具体问题,可以更好地领悟结构体在封装数据方面的优势。此外,熟练运用结构体成员的访问方式,掌握结构体在函数间的传递,以及了解结构体与动态内存分配的关系,是提高结构体应用能力的重要经验。总之,多实践、多思考,方能熟练掌握结构体这一强大的数据类型。
本文重点在于结构体的学习,对于初学者而言可以先了解一下共用体。

2.题目分享:

题目1:定义一个学生结构体,包含学生的姓名、年龄和成绩。编写一个函数,该函数接受一个学生结构体数组和学生数量作为参数,并打印出所有成绩高于平均分的学生信息。
#include <stdio.h>
#include <string.h>

// 定义学生结构体
typedef struct {
    char name[50];
    int age;
    float score;
} Student;

// 函数声明
void printAboveAverageStudents(Student students[], int count);

int main() {
    // 初始化学生数组
    Student students[] = {
        {"Alice", 20, 85.5},
        {"Bob", 21, 92.0},
        {"Charlie", 22, 78.5},
        {"David", 20, 88.0},
        {"Eva", 21, 95.0}
    };
    
    // 计算学生数量
    int studentCount = sizeof(students) / sizeof(students[0]);
    
    // 打印高于平均分的学生信息
    printAboveAverageStudents(students, studentCount);
    
    return 0;
}

// 打印高于平均分的学生信息
void printAboveAverageStudents(Student students[], int count) {
    float sum = 0.0;
    for (int i = 0; i < count; i++) {
        sum += students[i].score;
    }
    float average = sum / count;
    
    printf("Students with scores above average (%.2f):\n", average);
    for (int i = 0; i < count; i++) {
        if (students[i].score > average) {
            printf("Name: %s, Age: %d, Score: %.2f\n", students[i].name, students[i].age, students[i].score);
        }
    }
}
题目2:定义一个表示日期的结构体,并编写一个函数来比较两个日期的大小。
#include <stdio.h>

// 定义日期结构体
typedef struct {
    int day;
    int month;
    int year;
} Date;

// 函数声明
int compareDates(Date d1, Date d2);

int main() {
    Date date1 = {12, 4, 2023};
    Date date2 = {10, 5, 2023};
    
    // 比较两个日期
    int result = compareDates(date1, date2);
    
    if (result < 0) {
        printf("Date1 is earlier than Date2.\n");
    } else if (result > 0) {
        printf("Date1 is later than Date2.\n");
    } else {
        printf("Date1 and Date2 are the same.\n");
    }
    
    return 0;
}

// 比较两个日期的大小
int compareDates(Date d1, Date d2) {
    if (d1.year != d2.year) {
        return (d1.year > d2.year) ? 1 : -1;
    } else if (d1.month != d2.month) {
        return (d1.month > d2.month) ? 1 : -1;
    } else if (d1.day != d2.day) {
        return (d1.day > d2.day) ? 1 : -1;
    }
    return 0; // 日期相同
}
题目3:定义一个表示点的结构体,包含二维坐标(x, y)。编写一个函数,该函数接受两个点的结构体,并计算两点之间的距离。
#include <stdio.h>
#include <math.h>

// 定义点结构体
typedef struct {
    float x;
    float y;
} Point;

// 函数声明
float calculateDistance(Point p1, Point p2);

int main() {
    Point point1 = {3.0, 4.0};
    Point point2 = {0.0, 0.0};
    
    // 计算两点之间的距离
    float distance = calculateDistance(point1, point2);
    
    printf("Distance between point1 and point2 is: %.2f\n", distance);
    
    return 0;
}

// 计算两点之间的距离
float calculateDistance(Point p1, Point p2) {
    float dx = p2.x - p1
题目4:定义一个表示矩形的结构体,包含长度和宽度。编写一个函数,该函数接受一个矩形结构体,并计算矩形的面积。
#include <stdio.h>

// 定义矩形结构体
typedef struct {
    float length;
    float width;
} Rectangle;

// 函数声明
float calculateArea(Rectangle rect);

int main() {
    Rectangle rect = {10.0, 5.0};
    
    // 计算矩形的面积
    float area = calculateArea(rect);
    
    printf("The area of the rectangle is: %.2f\n", area);
    
    return 0;
}

// 计算矩形的面积
float calculateArea(Rectangle rect) {
    return rect.length * rect.width;
}
题目5:定义一个表示复数的结构体,包含实部和虚部。编写一个函数,该函数接受两个复数结构体,并计算它们的和。
#include <stdio.h>

// 定义复数结构体
typedef struct {
    float real;
    float imag;
} Complex;

// 函数声明
Complex addComplex(Complex c1, Complex c2);

int main() {
    Complex c1 = {4.0, 3.0};
    Complex c2 = {2.0, -1.0};
    
    // 计算两个复数的和
    Complex sum = addComplex(c1, c2);
    
    printf("Sum of the complex numbers: %.2f + %.2fi\n", sum.real, sum.imag);
    
    return 0;
}

// 计算两个复数的和
Complex addComplex(Complex c1, Complex c2) {
    Complex result;
    result.real = c1.real + c2.real;
    result.imag = c1.imag + c2.imag;
    return result;
}
题目6:定义一个表示时间的结构体,包含小时、分钟和秒。编写一个函数,该函数接受一个时间结构体,并将时间转换为总秒数。
#include <stdio.h>

// 定义时间结构体
typedef struct {
    int hours;
    int minutes;
    int seconds;
} Time;

// 函数声明
int convertToSeconds(Time time);

int main() {
    Time time = {2, 45, 30};
    
    // 将时间转换为总秒数
    int totalSeconds = convertToSeconds(time);
    
    printf("Total seconds: %d\n", totalSeconds);
    
    return 0;
}

// 将时间转换为总秒数
int convertToSeconds(Time time) {
    return time.hours * 3600 + time.minutes * 60 + time.seconds;
}

————由于博主还是大三的在读生,时间有限,每天会不定时更新一些学习经验和一些32的项目,如果喜欢就点点关注吧,大佬们!!!!————

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
森林防火应急联动指挥系统是一个集成了北斗定位/GPS、GIS、RS遥感、无线网络通讯、4G网络等技术的现代化智能系统,旨在提高森林火灾的预防和扑救效率。该系统通过实时监控、地图服务、历史数据管理、调度语音等功能,实现了现场指挥调度、语音呼叫通讯、远程监控、现场直播、救火人员生命检测等工作的网络化、智能化、可视化。它能够在火灾发生后迅速组网,确保现场与指挥中心的通信畅通,同时,系统支持快速部署,适应各种极端环境,保障信息的实时传输和历史数据的安全存储。 系统的设计遵循先进性、实用性、标准性、开放性、安全性、可靠性和扩展性原则,确保了技术的领先地位和未来的发展空间。系统架构包括应急终端、无线专网、应用联动应用和服务组件,以及安全审计模块,以确保用户合法性和数据安全性。部署方案灵活,能够根据现场需求快速搭建应急指挥平台,支持高并发视频直播和大容量数据存储。 智能终端设备具备三防等级,能够在恶劣环境下稳定工作,支持北斗+GPS双模定位,提供精确的位置信息。设备搭载的操作系统和处理器能够处理复杂的任务,如高清视频拍摄和数据传输。此外,设备还配备了多种传感器和接口,以适应不同的使用场景。 自适应无线网络是系统的关键组成部分,它基于认知无线电技术,能够根据环境变化动态调整通讯参数,优化通讯效果。网络支持点对点和点对多点的组网模式,具有低功耗、长距离覆盖、强抗干扰能力等特点,易于部署和维护。 系统的售后服务保障包括安装实施服务、系统维护服务、系统完善服务、培训服务等,确保用户能够高效使用系统。提供7*24小时的实时故障响应,以及定期的系统优化和维护,确保系统的稳定运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

樱娆π

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值