C语言结构体指针访问结构体成员的2种方式(附带示例)
在C语言中,我们既可以通过结构体变量来访问和操作成员,也可以通过结构体指针来访问和操作成员。通过结构体指针访问结构体成员有两种主要方式:
-
使用箭头运算符
->
-
使用解引用运算符
*
配合点运算符.
这两种方式各有特点,我们将详细探讨它们的用法和区别。
让我们先定义一个简单的结构体,用于后续的示例:
struct Person { char name[50]; int age; float height; };
现在,我们来看看如何使用结构体指针访问这个结构体的成员。
1. 箭头运算符(->)
箭头运算符是访问结构体指针成员最常用和最直观的方式,它的语法简洁明了,使用起来非常方便。
语法格式如下:
结构体指针->成员名
让我们通过一个具体的例子来说明箭头运算符的使用:
#include <stdio.h> #include <string.h> struct Person { char name[50]; int age; float height; }; int main() { struct Person person = {"张三", 25, 175.5}; struct Person *ptr = &person; // 使用箭头运算符访问结构体成员 printf("姓名:%s\n", ptr->name); printf("年龄:%d\n", ptr->age); printf("身高:%.1f cm\n", ptr->height); // 修改结构体成员 strcpy(ptr->name, "李四"); ptr->age = 30; ptr->height = 180.0; printf("\n修改后的信息:\n"); printf("姓名:%s\n", ptr->name); printf("年龄:%d\n", ptr->age); printf("身高:%.1f cm\n", ptr->height); return 0; }
输出结果:
姓名:张三 年龄:25 身高:175.5 cm 修改后的信息: 姓名:李四 年龄:30 身高:180.0 cm
在这个例子中,我们创建了一个 Person 结构体的实例 person,并定义了一个指向它的指针 ptr。通过箭头运算符,我们可以轻松地访问和修改结构体的成员。箭头运算符的使用方式非常直观,就像是指针“指向”了结构体的成员一样。
2. 解引用运算符(*)配合点运算符(.)
另一种访问结构体指针成员的方式是使用解引用运算符*
和点运算符.
的组合。这种方式虽然不如箭头运算符那么简洁,但它清晰地展示了指针解引用的过程。
语法格式如下:
(*结构体指针).成员名
注意,括号在这里是必需的,因为点运算符的优先级高于解引用运算符。
让我们用同样的例子来演示这种方式:
#include <stdio.h> #include <string.h> struct Person { char name[50]; int age; float height; }; int main() { struct Person person = {"王五", 28, 170.0}; struct Person *ptr = &person; // 使用间接引用运算符和点运算符访问结构体成员 printf("姓名:%s\n", (*ptr).name); printf("年龄:%d\n", (*ptr).age); printf("身高:%.1f cm\n", (*ptr).height); // 修改结构体成员 strcpy((*ptr).name, "赵六"); (*ptr).age = 35; (*ptr).height = 178.5; printf("\n修改后的信息:\n"); printf("姓名:%s\n", (*ptr).name); printf("年龄:%d\n", (*ptr).age); printf("身高:%.1f cm\n", (*ptr).height); return 0; }
输出结果:
姓名:王五 年龄:28 身高:170.0 cm 修改后的信息: 姓名:赵六 年龄:35 身高:178.5 cm
在这个例子中,我们使用(*ptr).成员名
的形式来访问和修改结构体的成员。这种方式实际上是先解引用指针*ptr
,然后使用点运算符访问结构体成员。虽然这种方式看起来有点繁琐,但它清楚地展示了指针操作的过程,有助于理解指针和结构体的关系。
两种方式的比较
两种方式在功能上是完全等价的,但使用箭头运算符更加直观。实际上,箭头运算符是一种语法糖,编译器会将 ptr->member 转换为 (*ptr).member。
选择使用哪种方式主要取决于个人偏好和代码风格。大多数 C 程序员倾向于使用箭头运算符,因为它更简洁,尤其是在处理多层嵌套的结构体指针时。例如,对于 struct A *a; struct B *b; struct C *c;,使用 a->b->c->member 比 (*(*(*a).b).c).member 更易读和书写。
然而,了解和掌握两种方式都是很有必要的。在某些情况下,使用解引用和点运算符的组合可能更清晰地表达代码的意图,特别是当你想强调正在进行指针解引用操作时。