C 语言-结构体
1. 定义与声明
结构体是一个或多个变量的集合,这些变量可能具有不同的类型,并分组在一个名称下。它是用户定义的数据类型。它们有助于组织大型程序中的复杂数据,因为它们允许将一组逻辑相关的变量视为一个变量。
例如,学生可以拥有姓名、年龄、性别和分数等属性。我们可以char
为 创建一个acter 数组name
,int
为 创建一个eger 变量roll
,char
为gender 创建一个acter 变量,int
为 创建一个eger 数组marks
。但如果有 20 或 100 名学生,就很难处理这些变量。
我们可以使用关键字声明一个结构体,struct
语法如下:
struct structureName
{
dataType memberVariable1;
datatype memberVariable2;
...
};
/* Example */
struct student
{
char name[20];
int roll;
char gender;
int marks[5];
};
上面的语句定义了一个新的数据类型struct student
。此数据类型的每个变量将由name[20]
、roll
和组成。这些被称为结构体的成员。gender
marks[5]
一旦结构体被声明为新的数据类型,就可以创建该数据类型的变量。
/* Variable declaration */
struct structureName structureVariable;
/* Example /*
struct student stu1;
struct student stu2,stu3,stu4;
struct Student 的每个变量都有其成员的副本。
重要的——
-
在创建结构体变量之前,结构体的成员不会占用内存。
-
您可能已经注意到我们使用了
struct。
typedef
在结构声明中使用关键字我们可以防止struct
再次写入。
typedef struct students
{
char name[20];
int roll;
char gender;
int marks[5];
} STUDENT;
/* or */
typedef struct
{
char name[20];
int roll;
char gender;
int marks[5];
} STUDENT;
STUDENT stu1,stu2,stu3,stu4;
按照惯例,类型定义使用大写字母(例如)。STUDENT
3.结构体定义和变量声明可以组合如下。
struct student
{
char name[20];
int roll;
chat gender;
int marks[5];
}stu1, stu2, stu3, stu4;
4. 结构体名称的使用structureName
是可选的。下面的代码是完全有效的。
struct
{
char name[20];
int roll;
char gender;
int marks[5];
}stu1, stu2, stu3, stu4;
5.结构体通常在源代码文件的顶部声明,甚至在定义函数之前也是如此。
6.C 不允许在结构声明内进行变量初始化。
1. 结构体成员的初始化和访问
与任何其他变量一样,结构变量也可以在声明它们的地方进行初始化。成员与其初始值之间存在一对一的关系。
/* Variable Initialization */
struct structureName = { value1, value2,...};
/* Example */
typedef struct
{
char name[20];
int roll;
char gender;
int marks[5];
}STUDENT;
void main(){
STUDENT stu1 = { "Alex", 43, 'M', {76, 78, 56, 98, 92}};
STUDENT stu2 = { "Max", 33, 'M', {87, 84, 82, 96, 78}};
}
要访问成员,我们必须使用.
(点运算符)。
/* Accessing Memebers of a Structure */
structureVariable.memberVariable
/* Example */
printf("Name: %s\n", stu1.name);
printf("Roll: %d\n", stu1.roll);
printf("Gender: %c\n", stu1.gender);
for( int i = 0; i < 5; i++)
printf("Marks in %dth subject: %d\n", i, stu1.marks[i]);
/* Output */
Name: Alex
Roll: 43
Gender: M
Marks in 0th subject: 76
Marks in 1th subject: 78
Marks in 2th subject: 56
Marks in 3th subject: 98
Marks in 4th subject: 92
可以使用 来以任意顺序在变量声明中初始化成员.
。
STUDENT stu3 = { .gender = 'M',
.roll = 23,
.name = "Gasly",
.marks = { 99, 45, 67, 78, 94}
};
我们还可以初始化前几个成员并将其余的留空。但是,未初始化的成员应该仅位于列表的末尾。未初始化的整数和浮点数有一个默认值 0。对于字符和字符串来说它是 \0(NULL)。
STUDENT stu4 = { "Kviyat", 65};
/* same as { "Kviyat", 65, '\0', { 0, 0, 0, 0, 0} } */
2. 结构体变量的操作
与原始数据类型的变量一样,我们不能执行 +、-、*、/ 等算术运算。同样,关系运算符和相等运算符不能与结构变量一起使用。但是,我们可以将一个结构变量复制到另一个结构变量,前提是它们属于同一结构。
/* Invalid Operations */
stu1 + stu2
stu1 - stu2
stu1 == stu2
stu1 != stu2 etc.
/* Valid Operation */
stu1 = stu2
我们必须单独比较结构成员才能比较结构体变量。
#include <stdio.h>
#include <string.h>
struct student
{
char name[20];
double roll;
char gender;
int marks[5];
}stu1,stu2;
void main()
{
struct student stu1= { "Alex", 43, 'M', {76, 78, 56, 98, 92}};
struct student stu2 = { "Max", 33, 'M', {87, 84, 82, 96, 78}};
if( strcmp(stu1.name,stu2.name) == 0 && stu1.roll == stu2.roll)
printf("Both are the records of the same student.\n");
else printf("Different records, different students.\n");
/* Copiying the structure variable */
st2 = st1;
if( strcmp(stu1.name,stu2.name) == 0 && stu1.roll == stu2.roll)
printf("\nBoth are the records of the same student.\n");
else printf("\nDifferent records, different students.\n");
}
/* Output */
Different records, different students.
Both are the records of the same student.
3. 结构体数组
您已经看到我们如何创建 4 个不同struct student
类型的变量来存储 4 个学生的记录。更好的方法是创建一个数组struct student
(就像 array of int
s 一样)。
struct student
{
char name[20];
double roll;
char gender;
int marks[5];
};
struct student stu[4];
要访问数组的元素stu
和每个元素的成员,可以使用循环。
/* Taking values for the user */
for(int i = 0; i < 4; i++)
{
printf("Enter name:\n");
scanf("%s",&stu[i].name);
printf("Enter roll:\n");
scanf("%d",&stu[i].roll);
printf("Enter gender:\n");
scanf(" %c",&stu[i].gender);
for( int j = 0; j < 5; j++)
{
printf("Enter marks of %dth subject:\n",j);
scanf("%d",&stu[i].marks[j]);
}
printf("\n-------------------\n\n");
}
/* Finding the average marks and printing it */
for(int i = 0; i < 4; i++)
{
float sum = 0;
for( int j = 0; j < 5; j++)
{
sum += stu[i].marks[j];
}
printf("Name: %s\nAverage Marks = %.2f\n\n", stu[i].name,sum/5);
}
4. 嵌套结构体
结构体的嵌套意味着在另一个结构体内有一个或多个结构变量。就像我们声明int
成员或char
成员一样,我们也可以将结构体变量声明为成员。
struct date
{
int date;
int month;
int year;
};
struct student
{
char name[20];
int roll;
char gender;
int marks[5];
struct birth birthday;
};
void main(){
struct student stu1;
birthday
类型的结构体变量struct birth
嵌套在 内部struct student
。很明显,您不能struct student
在 内部嵌套类型的结构变量struct student
。
请注意,必须首先声明要嵌套的结构。使用 .,我们可以访问内部结构体中包含的成员以及其他成员。
/* Example */
stu1.birthday.date
stu1.birthday.month
stu1.birthday.year
stu1.name
不同类型的结构变量也可以嵌套。
struct birth
{
int date;
int month;
int year;
};
struct relation
{
char fathersName[20];
char mothersName[20];
};
struct student
{
char name[20];
int roll;
char gender;
int marks[5];
struct birth birthday;
struct relation parents;
};