C语言结构体指针详解:语法、成员访问与函数传参
结构体指针是C语言中操作复杂数据结构的核心工具。通过指针直接访问内存地址,不仅能实现高效的成员访问(使用->运算符),还能避免函数传参时的数据拷贝开销。
结构体指针的定义与赋值规则
指针可以指向一个结构体,定义形式通常为:struct 结构体名 *变量名;。在定义结构体变量的同时,也可以直接定义指向该结构体的指针。
以下示例展示了如何定义学生信息结构体并初始化指针:
#include <stdio.h>
// 定义结构体类型,同时定义实例stu1和指针pstu
struct stu {
char *name; // 姓名
int num; // 学号
int age; // 年龄
char group; // 所在小组
float score;// 成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
需要特别注意区分结构体类型与结构体变量的概念。结构体本身仅是一种数据类型模板(类似 int),编译器不会为其分配内存空间;只有结构体变量才包含实际数据并占用内存。
- 正确做法:取结构体变量的地址。
struct stu *pstu = &stu1; - 错误做法:直接对类型名或变量名不加
&赋值给指针。struct stu *pstu = stu1;会导致编译错误。 - 无效做法:试图获取不存在的“结构体名”的地址。
struct stu *pstu = &stu;是非法的。
获取结构体成员的方法
通过结构体指针访问成员时,主要有两种等效的写法:
- 解引用加点运算:
(*pointer).memberName。由于成员访问运算符.的优先级高于解引用运算符*,因此必须使用括号将*pointer括起来。如果去掉括号写成*pointer.memberName,则会被解释为*(pointer.memberName),导致逻辑完全错误。 - 箭头运算符:
pointer->memberName。这里的->称为“箭头”,是专门用于结构体指针访问成员的新增运算符。这种写法更加直观且常用。
【示例】读取结构体成员的值:
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n",
(*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n",
pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);
结构体指针处理数组
当处理结构体数组时,结构体数组名即为首元素的地址。利用指针遍历可以避免索引运算的繁琐,提升代码的可读性。
【示例】遍历全班学生信息:
#include <stdio.h>
struct stu {
char *name;
int num;
int age;
char group;
float score;
};
struct stu stus[] = {
{"Zhou ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
{"Liu fang", 1, 18, 'A', 148.5},
{"Cheng ling", 2, 17, 'F', 139.0},
{"Wang ming", 3, 17, 'B', 144.5}
}, *ps;
int main() {
// 计算数组元素个数
int len = sizeof(stus) / sizeof(struct stu);
printf("Name\tNum\tAge\tGroup\tScore\n");
// 指针逐位移动遍历
for (ps = stus; ps < stus + len; ps++) {
printf("%s\t%d\t%d\t%c\t%.1f\n", ps->name, ps->num, ps->age, ps->group, ps->score);
}
return 0;
}
作为函数参数传递的优势
如果不使用指针,而是直接将结构体变量作为参数传递给函数,C语言会将整个结构体所有成员复制到栈空间中。如果结构体包含大量数据或嵌套数组,这会带来显著的时间和空间开销。
使用结构体指针作为参数传递时,实参只向形参传输一个内存地址,效率极高。
【示例】计算学生总成绩、平均分及低于特定分数的人数:
#include <stdio.h>
struct stu {
char *name;
int num;
int age;
char group;
float score;
}stus[] = {
{"Li ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
{"He fang", 1, 18, 'A', 148.5},
{"Cheng ling", 2, 17, 'F', 139.0},
{"Wang ming", 3, 17, 'B', 144.5}
};
// 函数声明:接收结构体指针和长度
void average(struct stu *ps, int len);
int main() {
int len = sizeof(stus) / sizeof(struct stu);
average(stus, len);
return 0;
}
void average(struct stu *ps, int len) {
int i, num_140 = 0;
float sum = 0;
for(i=0; i<len; i++) {
// 利用算术运算移动指针 (ps + i)
sum += (ps + i)-> score;
if((ps + i)->score < 140) num_140++;
}
printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum/5, num_140);
}
以上就是结构体和指针的详细内容,更多关于C语言基础的知识资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













