C++指针结构体数组与指向结构体变量的指针详解
C++中的结构体数组用于存储一组同类型的结构体数据,而指向结构体变量的指针则提供了更灵活的内存访问方式。本文将详细介绍这两者的定义、初始化方法及实际应用场景,包括通过指针构建单向链表。
一、结果或目标
掌握C++结构体数组的创建与使用技巧,理解如何通过指针高效访问结构体成员,并能够利用这一机制构建基础的静态链表数据结构。
二、准备条件
- 开发环境:支持C++11及以上标准的编译器(如GCC, Clang, MSVC)。
- 基础知识:了解C++基本数据类型、数组概念以及指针的基本用法。
- 头文件依赖:涉及字符串比较需包含
<string>或<cstring>。
三、真实操作顺序
第1步:定义与初始化结构体数组
目的:创建一个包含多个学生信息的结构体数组,并为其赋予初始值。
动作:使用 struct 关键字定义类型,随后声明数组并进行整体初始化。
struct Student {
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
};
// 初始化时直接提供所有成员的初值列表
Student stu[3] = {
{10101, "Li Lin", 'M', 18, 87.5, "103 Beijing Road"},
{10102, "Zhang Fun", 'M', 19, 99, "130 Shanghai Road"},
{10104, "Wang Min", 'F', 20, 78.5, "1010 Zhongshan Road"}
};
完成状态:编译系统会根据提供的初值个数自动确定数组元素个数(若省略数组大小)。每个元素都完整包含了所有结构体成员的值。
第2步:应用结构体数组解决实际问题
目的:演示如何使用结构体数组进行数据统计,例如候选人投票统计。
入口:定义包含“姓名”和“票数”的结构体 Person。
动作:循环读取输入,并通过字符串比较更新对应候选人的票数。推荐使用 std::string 简化字符串处理。
#include <iostream>
#include <string>
using namespace std;
struct Person {
string name;
int count;
};
int main() {
Person leader[3] = {"Li", 0, "Zhang", 0, "Fun", 0};
string leader_name;
// 模拟10次投票
for(int i = 0; i < 10; i++) {
cin >> leader_name;
for(int j = 0; j < 3; j++) {
if(leader_name == leader[j].name) {
leader[j].count++; // 使用==直接比较string对象
}
}
}
// 输出结果
for(int i = 0; i < 3; i++) {
cout << leader[i].name << ":" << leader[i].count << endl;
}
return 0;
}
重要参数:string 类允许直接使用 == 运算符进行比较,比传统的 strcmp() 更安全且易读。但需注意,部分老旧C++标准可能不支持对含 string 成员的数组直接初始化,此时可先定义数组再逐个赋值。
第3步:使用指向结构体变量的指针
目的:学习通过指针间接访问和修改结构体成员。
动作:声明一个指向结构体类型的指针变量,并将其指向具体的结构体实例。
struct Student {
int num;
string name;
char sex;
float score;
};
Student stu; // 定义变量
Student *p = &stu; // 指针p指向stu的地址
stu.name = "Wang Fun"; // 通过变量名访问
cout << p->name << endl; // 通过指针访问
可观察的完成状态:输出结果应与直接通过 stu.name 访问一致。C++提供了 -> 运算符作为 (*p).member 的简写形式,极大提高了代码的可读性。
p->n:获取成员值。p->n++:使用后自增(取原值,再加1)。++p->n:先自增,再获取新值。
第4步:构建单向链表
目的:结合结构体与指针实现动态数据的链接存储。
结构定义:结构体中除数据成员外,还需包含一个指向同类型结构体的指针成员 next。
struct Student {
long num;
float score;
struct Student *next; // 指向下一个结点的指针
};
图示说明:链表结构
下图展示了链表的逻辑结构,每个节点通过 next 指针串联起来:
动作:在程序中手动分配地址并连接结点,形成“头指针 -> A -> B -> C -> NULL”的链条。
Student a, b, c, *head, *p;
a.num = 31001; a.score = 89.5;
b.num = 31003; b.score = 90;
c.num = 31007; c.score = 85;
head = &a; // 头指针指向第一个结点
a.next = &b; // a指向b
b.next = &c; // b指向c
c.next = NULL; // c是最后一个结点,指向空
// 遍历输出
for(p = head; p != NULL; p = p->next) {
cout << p->num << " " << p->score << endl;
}
图示说明:内存连接
由于各结点在内存中不一定连续,必须依赖前一个结点的 next 字段来定位下一个结点的位置:
完成判断:程序应能成功输出三个结点的数据,且在处理完最后一个结点后指针变为 NULL,循环终止。
四、原文有依据的排错
- string初始化兼容性:如果使用较旧的编译器且遇到结构体数组初始化报错,尝试不使用
string,改用字符数组char name[20]并结合strcpy_s或memcpy进行赋值。 - 空指针解引用:在链表遍历时,务必检查
p != NULL,否则当链表为空或越界时会引发崩溃。
五、简要总结
结构体数组适用于批量管理同类数据,而结构体指针则是操作动态数据结构(如链表)的基础。熟练运用 -> 运算符可以简化对嵌套数据的访问。以上就是C++指针结构体数组与指向结构体变量的指针的详细内容,更多关于C++数据结构与指针的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













