目录
定义结构体及结构体变量
概念:结构体是一种自定义的数据类型。它允许将不同的数据类型组合到一个单一的实体中。
定义结构体类型
定义一个结构体基本类型的一般形式如下。
struct 结构体名
{
成员列表
};
//花括号内是该结构体中的各个成员(或称分量),由它们组成一个结构体。
//对成员列表中各成员都应进行类型说明,例如。
类型标识符 成员名;
声明结构体变量
定义结构体变量的方式有如下三种。
先声明结构体类型,再定义该类型变量
一般形式为:struct 结构体名 变量名1,变量名2……
struct Person // 声明结构体类型
{
char name[20];
int age;
};
int main()
{
struct Person p1 = {"John", 30}; // 定义Person类型变量
struct Person p2 = {"Alice", 25};
printf("%s is %d years old.", p1.name, p1.age);// 访问成员变量
printf("%s is %d years old.", p2.name, p2.age);
return 0;
}
在定义结构体类型的同时定义变量
一般形式为:struct 结构体名
{
成员列表
};变量名1,变量名2……
struct person
{
char name[20];
int age;
} p1 = {"John", 30}, p2 = {"Jane", 25};//定义结构体类型的同时定义变量
不指定类型名而直接定义结构体类型变量
一般形式为:struct
{
成员列表
}变量名1,变量名2……
struct //未指定类型名
{
char name[20];
int age;
} person = {"John Smith", 30};
注:
1.结构体类型名(或结构体标识符)与结构体变量两个概念不同,如结构体类型名student和变量名stud1,前者并没有分配内存空间,而后者才会由编译系统为其分配相应长度的空间。
2.成员也可以是结构体变量。即一个结构体的结构中可以嵌套另一种结构体的结构。
引用结构体类型变量
具体形式有如下几种:
1.引用结构体变量中的一个成员,一般形式为:结构体变量名.成员名
2.可以将一个结构体变量作为一个整体赋给另一个具有相同类型的结构体变量,举例如下。
struct Student
{
char name[20];
int age;
float gpa;
};
struct Student alice = {"Alice", 20, 3.8};
struct Student bob;
bob = alice;
//把 alice 中的每个成员的值都复制到 bob 中对应的成员中
3.对成员变量可以像普通变量一样进行各种运算,例如
stud1.grade++;
4.可以引用成员的地址,也可以引用结构体变量的地址,例如
scanf("%d",&S1.num);
printf("%o",&S1);
5.不能将一个结构体变量作为一个整体进行输入和输出。
6.同一个程序单元中,普通变量可以和结构体成员变量同名。例如
#include <stdio.h>
struct Person
{
char name[20];
int age;
};
int main()
{
struct Person person1;
// 定义一个名为age的普通变量
int age = 30;
// 将person1的age成员变量赋值为20
person1.age = 20;
// 输出普通变量age和结构体成员变量age的值
printf("普通变量age的值为:%d", age);
printf("结构体成员变量age的值为:%d", person1.age);
return 0;
}
7.结构体成员类型为字符串时不能直接用赋值号赋值,需要用字符串处理函数strcpy()进行字符串复制。例如
stu_1.name="li lin";//错误
strcpy(stu_1.name,"li lin");//正确
结构体数组
和定义结构体变量类似,定义结构体数组有如下三种形式。
先定义结构体类型再定义数组
// 定义结构体类型
struct MyStruct
{
int x;
char y;
};
// 定义数组
struct MyStruct myArray[10];
定义结构体类型的同时定义数组
struct Student
{
char name[20];
int age;
float score;
} stu[10];
不指定类型名而直接定义结构体数组(匿名结构体)
#include <stdio.h>
int main()
{
struct
{ // 定义了一个匿名结构体
int id;
char name[20];
} students[] = {{ 1, "Alice" },{ 2, "Bob" },{ 3, "Charlie" }};
for (int i = 0; i < sizeof(students) / sizeof(students[0]); i++)
{
printf("id: %d, name: %s", students[i].id, students[i].name);
}
return 0;
}
结构体指针的应用——单链表
指向结构体的指针
一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。
故引用结构体成员的方式有如下三种:
1.结构体变量.成员名(上文已作讲解)如s.name
2.点域法表示为(*p).成员名,如(*p).name
3.指向法表示为p->成员名,如p->name,等价于(*p).name
用点域法和指向法引用结构体成员
//点域法
#include <stdio.h>
struct Person
{
char name[20];
int age;
};
int main()
{
// 定义一个 person 结构体变量,并初始化成员变量
struct Person person = { "Tom", 18 },*p = &person;
// 使用点域法修改结构体成员变量的值
person.age = 19;
printf("Name: %s, Age: %d", person.name, (*p).age);
return 0;
}
//指向法
#include <stdio.h>
struct Person
{
char name[20];
int age;
};
int main() {
// 定义一个 person 结构体变量,并初始化成员变量
struct Person person = { "Tom", 18 };
// 创建一个指向 person 结构体变量的指针
struct Person* p_person = &person;
// 使用指向法修改结构体成员变量的值
p_person->age = 19;
printf("Name: %s, Age: %d", p_person->name, p_person->age);
return 0;
}
指向结构体数组的指针
#include <stdio.h>
// 定义结构体
struct Person
{
char name[50];
int age;
};
int main()
{
// 定义结构体数组
struct Person people[2] = {{"Alice", 25},{"Bob", 30}};
// 定义指向结构体数组的指针
struct Person* ptr = people;
// 使用指针访问结构体数组中的元素
printf("First person's name: %s", ptr->name);
printf("First person's age: %d\n", ptr->age);
// 将指针移动到下一个元素
ptr++;
// 再次使用指针访问另一个结构体
printf("Second person's name: %s", ptr->name);
printf("Second person's age: %d\n", ptr->age);
return 0;
}
注:程序中每执行一次p++,指针变量p指向下一个数组元素。
用typedef定义类型
C语言允许在程序中用typedef来定义新的类型名来代替已有的类型名。
·用一个新的类型名代替原有的类型名
typedef int INTEGER
INTEGER a,b;
//相当于
int a,b;
·用一个简单的类型名代替复杂的类型
1.定义一个类型名代替一个结构体类型
typedef struct
{
int id;
char name[20];
float grade;
} Student;//可以用其定义变量,如:Student s1;
2.命名一个新的类型名代表数组类型
typedef int COUNT[20];
typedef int NAME[20];
COUNT a,b;
NAME c,d;
//相当于
int a[20],b[20];
char c[20],d[20];
3.命名一个新的类型名代表一个指针类型
typedef char *STRING;
STRING p1,p2,p[10];
//相当于
char *p1,*p2,p[10];
4.命名一个新的类型名代表指向函数的指针类型
typedef int (*Pointer)();
Pointer p1,p2;
说明:
1.typedef实际上是为特定的类型指定了一个同义字。
2.用typedef只是对已经存在的类型指定了一个新的类型名,并没有创造新的类型。
3.typedef声明各种类型,使得编程更加方便。
4.当不同源文件中用到同一个类型数据时,常用typedef声明一些数据类型。
ps:本专题原为笔者复习整理笔记,故缺少单链表、共用体、枚举等问题。