利用结构类型实现简单通讯录

复合数据类型之结构类型

在C语言中,结构类型是一种复合数据类型,它允许用户将不同类型的数据组合成一个单一的数据结构。结构类型为用户提供了自定义数据类型的机制,使得可以将多个相关的数据项组合成一个整体,常用来处理像记录、链表这样的静态和动态数据结构,从而便于管理和操作。

 

一、结构类型的定义

 

结构类型的定义使用"struct"关键字,后面跟随结构体的名称和一对大括号。在大括号中,可以定义结构体的成员变量,每个成员变量可以具有不同的数据类型。例如:

struct Student {

char name[50];

int age;

float score;

};

 

在上面的示例中,定义了一个名为"Student"的结构体,它包含三个成员变量:"name"(一个字符数组,用于存储学生的姓名)、"age"(一个整型变量,用于存储学生的年龄)和"score"(一个浮点型变量,用于存储学生的成绩)。

 

要创建结构体的实例(即变量),可以使用以下语法:

struct Student stu1;

 

这将创建一个名为"stu1"的"Student"结构体实例。然后,可以通过点运算符(".")或者

("->")来访问结构体中的成员变量(注意:①"."适合于用结构变量或结构数组元素访问其成员②"->"适合于用结构数组或结构指针访问其成员),例如:

strcpy(stu1.name, "张三");

stu1.age = 18;

stu1.score = 90.5;

 

上述代码将"stu1"的"name"成员设置为"张三","age"成员设置为18,"score"成员设置为90.5。

 

二、结构指针的定义

 

除了定义结构类型外,还可以定义结构体类型的指针,并通过指针来访问结构体的成员。例如:

struct Student *stu_ptr;

stu_ptr = &stu1;

printf("%s的年龄是%d岁,成绩是%.1f分\n", stu_ptr->name, stu_ptr->age, stu_ptr->score);

 

上述代码首先定义了一个指向"Student"结构体的指针"stu_ptr",然后将"stu1"的地址赋给"stu_ptr"。接下来,使用"->"运算符来通过指针访问结构体的成员,并打印出学生的姓名、年龄和成绩。

 

三、嵌套结构

 

在C语言中,结构类型可以嵌套使用,也就是说,一个结构体的成员可以是另一个结构体类型。这种嵌套结构允许我们创建更复杂的数据结构,以表示现实世界中的复杂对象或系统。例如:

#include <stdio.h>

// 定义一个表示地址的结构体

struct Address {

char street[50];

char city[50];

char country[50];

};

 

// 定义一个表示学生的结构体,其中包含一个地址结构体成员

struct Student {

char name[50];

int age;

float score;

struct Address addr; // 嵌套的地址结构体

};

 

在这个例子中,"struct Address" 是一个表示地址的结构体,它包含了街道、城市和国家等字段。然后,"struct Student" 是一个表示学生的结构体,它包含了姓名、年龄、成绩以及一个 "struct Address"类型的成员 "addr"。

 

嵌套结构允许我们构建更加复杂的数据结构,这在处理现实世界中的复杂对象时非常有用。例如,一个公司可能有一个员工结构体,而每个员工都有一个地址结构体作为其成员。这样,我们可以方便地管理和访问员工的所有相关信息。

 

四、结构类型的赋值

 

当要为结构体的实例赋值时,可以直接给每个成员赋值,或者使用结构体初始化列表来一次性初始化所有成员。例如:

c35dfeb37fac43d8acf7b091014a68fb.png

 五、结构数据在函数间的传递

在C语言中,结构数据可以通过多种方式在函数间传递。下面是一些常见的方法:

 

(1)值传递

 

当将结构体作为参数传递给函数时,默认情况下是通过值传递的,这意味着函数会接收结构体的一个副本,对副本所做的修改不会影响原始结构体。例如:

#include <stdio.h>

struct Point {

int x;

int y;

};

 

void printPoint(struct Point p) {

printf("(%d, %d)\n", p.x, p.y);

}

 

int main() {

struct Point p = {10, 20};

printPoint(p); // 输出: (10, 20)

return 0;

}

 

 

(2) 指针传递

 

如果想要修改原始结构体或避免结构体的复制开销,可以使用指针传递。这样,函数将接收结构体的地址,可以直接操作原始数据。例如:

#include <stdio.h>

struct Point {

int x;

int y;

};

 

void movePoint(struct Point *p, int dx, int dy) {

p->x += dx;

p->y += dy;

}

 

int main() {

struct Point p = {10, 20};

movePoint(&p, 5, 10); // 移动点

printf("(%d, %d)\n", p.x, p.y); // 输出: (15, 30)

return 0;

}

 

(3)返回结构体

 

函数也可以返回结构体。当函数返回结构体时,实际上返回的是结构体的一个副本。

#include <stdio.h>

struct Point {

int x;

int y;

};

struct Point addPoints(struct Point p1, struct Point p2) {

struct Point result;

result.x = p1.x + p2.x;

result.y = p1.y + p2.y;

return result;

}

 

int main() {

struct Point p1 = {10, 20};

struct Point p2 = {30, 40};

struct Point p3 = addPoints(p1, p2);

printf("(%d, %d)\n", p3.x, p3.y); // 输出: (40, 60)

return 0;

}

 

(4) 使用全局变量

 

结构体也可以作为全局变量,这样它们可以在多个函数之间共享。但这种方法通常不推荐,因为它会破坏封装性并可能导致难以追踪的副作用。

 

(5)动态内存分配

 

对于大型结构体或需要多次修改的结构体,可以考虑使用动态内存分配(如"malloc"和"free"函数)。这样,你可以在堆上分配内存,并通过指针在函数间传递这些内存块。

 

选择哪种方法取决于你的具体需求。在大多数情况下,指针传递是最高效和最灵活的方式,因为它避免了不必要的数据复制,并允许函数直接操作原始数据。然而,这也增加了编程的复杂性,因为需要正确地管理指针和内存。

 

下面我们利用上述知识实现简单通讯录:

9f57925264114e2086a5a569e467eb70.png

 

我们利用Input()用来输入通讯录的数据,

display()用来输出通讯录的数据,main()函数向input()和 Display()函数传递结构数,用于函数的数据传递。

程序中main()函数调用Input()函数时,形参和实参都是结构数组名,此时,形参将 自动转换成结构指针;main()函数调用Display()函数时,实参是结构数组名,形参是结构指针,两次调用的传递机制是相同的。

同样的,我们还可以实现简单的成绩统计:

用score数组存3门课成绩,并将score作为结构的一个成员被传递,此时用作计算总分的函数add()只要用指针接收score的首地址即可。

717612d664a143c7854b246491a6104a.png

 

 

结构类型在C语言中非常有用,它可以用于表示复杂的数据结构,例如记录、链表等。通过定义结构类型,可以方便地组织和操作多个相关的数据项,提高代码的可读性和可维护性。

好啦,今天的分享就到这里了。再次声明:作者水平有限,如有失偏颇,还请各位不吝赐教!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值