目录
题目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的项目,如果喜欢就点点关注吧,大佬们!!!!————