当前位置:首页 > 技术 > 正文内容

C++ 结构体与动态数组详解

访客 技术 2026年9月30日 7

本节将深入探讨 C++ 中的结构体以及如何基于结构体实现动态数组。

结构体增强

C++ 结构体语法特性

C++ 语言对 C 语言的结构体进行了增强,允许在结构体内部定义成员函数。这意味着函数可以与它们操作的数据紧密关联,提高了代码的组织性和可读性。


#include <iostream>

using namespace std;

// 定义一个 Student 结构体
struct Student
{
    int studentId;
    char studentName[16];
    int studentAge;

    // 在结构体内部声明一个成员函数
    void displayMessage()
    {
        cout << "这是一个学生信息测试函数。" << endl;
    }
};

/*
在 C++ 中,结构体类型名可以直接是 struct 关键字后的名称。
遵循大驼峰命名法是常见的实践。
*/
int main()
{
    // 直接使用结构体名作为数据类型声明变量
    Student studentRecord = {101, "Alice", 20};

    cout << "学号: " << studentRecord.studentId << endl;
    cout << "姓名: " << studentRecord.studentName << endl;
    cout << "年龄: " << studentRecord.studentAge << endl;

    // 通过结构体变量调用其成员函数
    studentRecord.displayMessage();

    return 0;
}
  

C++ 结构体实现案例

该示例展示了如何在 C++ 中为结构体成员提供访问器(getters)和修改器(setters)方法,并演示了如何使用结构体指针进行动态内存管理和成员访问。


#include <iostream>
#include <cstring> // 用于 strcpy
#include <cstdlib> // 用于 calloc, free

using namespace std;

struct StudentInfo
{
    int id;
    char name[32];
    int age;

    // 声明成员函数
    void updateId(int newId);
    int retrieveId() const; // const 表示此函数不会修改对象状态

    void updateName(const char *newName);
    const char *retrieveName() const;

    void updateAge(int newAge);
    int retrieveAge() const;
};

// 使用作用域解析运算符 :: 实现结构体成员函数
void StudentInfo::updateId(int newId)
{
    // this 指针指向调用该函数的对象实例
    this->id = newId;
}
int StudentInfo::retrieveId() const
{
    return id;
}

void StudentInfo::updateName(const char *newName)
{
    // 使用 strcpy 复制字符串
    strncpy(this->name, newName, sizeof(this->name) - 1);
    this->name[sizeof(this->name) - 1] = '\0'; // 确保 null 终止
}
const char *StudentInfo::retrieveName() const
{
    return name;
}

void StudentInfo::updateAge(int newAge)
{
    this->age = newAge;
}
int StudentInfo::retrieveAge() const
{
    return age;
}

int main()
{
    // 使用 calloc 分配动态内存并初始化为零
    StudentInfo *studentPtr = (StudentInfo *)calloc(1, sizeof(StudentInfo));

    if (!studentPtr) {
        cerr << "内存分配失败!" << endl;
        return 1;
    }

    // 通过指针调用成员函数设置值
    studentPtr->updateId(202);
    studentPtr->updateName("Bob");
    studentPtr->updateAge(22);

    // 通过指针调用成员函数获取值并打印
    cout << "学号: " << studentPtr->retrieveId() << endl;
    cout << "姓名: " << studentPtr->retrieveName() << endl;
    cout << "年龄: " << studentPtr->retrieveAge() << endl;

    // 释放动态分配的内存
    free(studentPtr);
    studentPtr = NULL; // 将指针设为 NULL 以避免悬空指针

    return 0;
}
  

动态数组实现

功能概述

动态数组是一种能够根据需要自动调整大小的数据结构。在本节中,我们将设计一个通用的动态数组结构体,该结构体可以存储指向特定类型(例如学生对象)的指针,并支持常见的"增、删、改、查"操作。

核心结构体设计

为了管理动态数组的容量和实际元素数量,我们在结构体中引入了 `capacity`(总容量)和 `count`(已用空间)成员。同时,它将存储指向 `Student` 对象的指针数组。


#include <vector> // 假设我们稍后会使用 STL vector 或自定义实现

// 定义默认初始容量
#define INITIAL_CAPACITY 10

// 假设 Student 结构体已定义,此处为占位符
struct Student { /* ... Student definition ... */ };

// 定义一个通用的动态数组结构体
struct DynamicArray
{
    // 指向 Student 对象的指针数组
    Student **elementPointers;
    // 数组的总容量
    int capacity;
    // 数组中当前存储的有效元素数量
    int count;

    // 构造函数(可选,用于初始化)
    DynamicArray(int initialCapacity = INITIAL_CAPACITY) : capacity(initialCapacity), count(0) {
        elementPointers = new Student*[capacity];
    }

    // 析构函数(重要,用于释放内存)
    ~DynamicArray() {
        delete[] elementPointers;
    }

    // 其他成员函数如 add, remove, get, set 等将在此处定义
};
  

学生数据定义(头文件和源文件)

以下是 `Student` 结构体的头文件 (`student.h`) 和实现文件 (`student.cpp`)。

student.h


#ifndef STUDENT_HEADER
#define STUDENT_HEADER

#include <string> // 使用 C++ 标准字符串
#include <iostream>

class Student {
private:
    int studentId;
    std::string studentName;
    int studentAge;

public:
    // 构造函数
    Student(int id = 0, std::string name = "", int age = 0);

    // Setter 方法
    void setId(int id);
    void setName(const std::string& name);
    void setAge(int age);

    // Getter 方法
    int getId() const;
    const std::string& getName() const;
    int getAge() const;

    // 示例:显示学生信息
    void displayInfo() const;
};

#endif // STUDENT_HEADER
  

student.cpp


#include "student.h"

// 实现构造函数
Student::Student(int id, std::string name, int age) : studentId(id), studentName(name), studentAge(age) {}

// 实现 Setter 方法
void Student::setId(int id) {
    this->studentId = id;
}
void Student::setName(const std::string& name) {
    this->studentName = name;
}
void Student::setAge(int age) {
    this->studentAge = age;
}

// 实现 Getter 方法
int Student::getId() const {
    return studentId;
}
const std::string& Student::getName() const {
    return studentName;
}
int Student::getAge() const {
    return studentAge;
}

// 实现显示信息方法
void Student::displayInfo() const {
    std::cout << "ID: " << studentId << ", Name: " << studentName << ", Age: " << studentAge << std::endl;
}
  
标签: C++结构体

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。