C++结构体入门与实战案例详解
掌握C++结构体是理解面向对象编程的基础。本文将详细讲解结构体的创建、初始化和常用操作,包括指针传递、引用传递和嵌套结构体的使用,并结合实际业务场景(如师生信息匹配、薪资排序)提供可运行的代码示例,帮助开发者快速上手。
结构体的基础创建与初始化
结构体(struct)允许将不同类型的数据组合在一起。在C++中,我们可以通过 struct 关键字来定义。在使用字符数组存储字符串时,需要注意内存安全,推荐使用 strcpy_s;而使用 string 类则更加便捷。
以下是两种常见的结构体定义及其初始化方式:
#include <iostream>
#include <string>
using namespace std;
struct User {
char name[20];
char sex[5];
int age;
};
struct Student {
string name;
int age;
int score;
} stu; // 第二种:声明变量并定义
在主函数中,我们可以通过成员访问运算符 . 进行赋值和打印。对于静态数组成员,需使用库函数复制字符串;对于 std::string 类型,可以直接赋值。
int main() {
struct User u1;
strcpy_s(u1.name, "肥学"); // 建议使用 strcpy_s 替代 strcpy
u1.age = 12;
strcpy_s(u1.sex, "男");
cout << "name:" << u1.name << " age:" << u1.age << " sex:" << u1.sex << endl;
struct Student s;
s.name = "鸣人";
s.age = 20;
s.score = 80;
cout << "Student Info - name:" <<s.name << " age:" << s.age << " score:" << s.score << endl;
// 聚合初始化
struct Student s2={ "pte", 20, 56 };
struct User u2 = { "pter","男", 20 };
}
结构体的高级操作
第1步:嵌套结构与指针/引用传递
结构体内部可以包含其他结构体。在函数传参时,除了直接拷贝对象,使用指针或引用可以减少开销并修改原值。
- 地址传递(指针):使用
&取地址,函数内通过->或(*ptr).member访问。 - 引用传递:使用
&符号,函数内像普通对象一样直接访问成员。
struct Friend {
string name;
int age;
string sex;
};
struct User {
string name;
int age;
string sex;
Friend f; // 嵌套结构体
};
void addFriend(User* u) { // 指针传递
Friend f = { "fei", 20, "men" };
u->f = f;
}
void addF2(User& u) { // 引用传递
Friend f = { "xue", 20, "men" };
u.f = f;
}
调用时只需传入对象本身或取地址,函数执行后会改变原结构体内的嵌套数据。
第2步:结构体的 const 修饰
在结构体中,const 成员必须在初始化列表中赋值,且一旦赋值不可更改。这对于设计只读配置或标识符非常有用。同时,函数参数若不需要修改数据,应标记为 const 以增强安全性。
struct ConstUser {
const string name;
const int age;
const string sex;
};
// 注意:C++标准编译器通常要求自定义构造函数或使用聚合初始化列表
void printInfo(const ConstUser* u) {
cout << u->name << " | Age: " << u->age << " | Sex: " << u->sex << endl;
}
实战案例一:师生分组分配
假设需要给多位老师分配学生,每位老师名下有固定的几个学生。此案例涉及结构体数组、随机数生成以及循环输入输出。
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
typedef struct Student {
string name;
int age;
string sex;
} S; // 使用 typedef 简化写法
typedef struct Teacher {
string name;
int age;
string sex;
S sarray[2]; // 每位老师带2名学生
} T;
void assignment(T* tarray, int len) {
srand((unsigned int)time(NULL)); // 设置随机种子
for (int i = 0; i < len; i++) {
cin >> tarray[i].name;
cin >> tarray[i].age;
cin >> tarray[i].sex;
for (int s = 0; s < 2; s++) {
cin >> tarray[i].sarray[s].name;
tarray[i].sarray[s].age = rand() % 18 + 8; // 随机生成8-25岁
cin >> tarray[i].sarray[s].sex;
}
}
}
void printInfo(T* tarray, int tnum) {
for (int i = 0; i < tnum; i++) {
cout << "Teacher: " << tarray[i].name << endl;
for (int j = 0; j < 2; j++) {
cout << " Student: " << tarray[i].sarray[j].name
<< " Age: " << tarray[i].sarray[j].age
<< " Sex: " << tarray[i].sarray[j].sex << endl;
}
}
}
实战案例二:员工薪资冒泡排序
该案例演示如何对结构体数组进行遍历、赋值,并按指定字段(薪资)进行降序排序。这里使用了简单的冒泡排序逻辑。
struct Staff {
string name;
int salary;
};
void initStaff(Staff* sarray, int len) {
srand((unsigned int)time(NULL));
string seed = "ABCDE";
for (int i = 0; i < len; i++) {
int sal = rand() % 10000 + 3000;
sarray[i].name = "user_" + seed[i];
sarray[i].salary = sal;
}
}
void sortSalary(Staff* sarray, int len) {
// 冒泡排序:按工资从高到低
for (int i = len - 1; i > 0; i--) {
for (int j = len - 1; j >= len - i; j--) {
if (sarray[j].salary > sarray[j - 1].salary) {
// 交换整个结构体
Staff temp = sarray[j];
sarray[j] = sarray[j - 1];
sarray[j - 1] = temp;
}
}
}
}
int main() {
Staff staffArr[5];
initStaff(staffArr, 5);
sortSalary(staffArr, 5); // 排序后输出
return 0;
}
以上就是关于C++结构体基础概念、进阶操作以及相关实践案例的详细内容。结构体作为C++面向过程到面向对象过渡的重要桥梁,理解其内存布局和数据传递机制对于编写高效代码至关重要。更多关于C++语言特性与算法优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













