【C++】结构体(struct)

本文深入探讨C/C++中的结构体概念,包括基本形式、变量定义与初始化、读写成员、赋值、指针使用及对齐问题,同时解析结构体作为成员的使用场景,帮助读者全面理解结构体的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

结构体struct的基本形式

变量定义和初始化

读写结构体内部成员

结构体赋值

结构体指针

特殊形式(匿名结构体,但一般不这么用)

另一种特殊形式(一般也不这么用)

对齐问题

结构体作为成员


我对结构体的理解:结构体是将多种数据类型组合成一个集合,这个集合就是结构体。结构体是弱化版的类,功能没有类强大。

结构体注意点:struct一般都放在最外层定义,不放在函数内定义。

不使用结构体(先不谈”类“),会带来以下几个问题:

1)信息比较松散,不直观;

2)容易重名;

3)数据存取不方便。

结构体struct的基本形式

struct TypeName
{
    //Members;
}

其中,struct是关键字,TypeName为新类型的名称,Members则是一系列成员。

1)TypeName的命名规则,和变量名的规则一样;

2)成员变量可以是 普通变量/数组 定义。

变量定义和初始化

结构体的使用方法和普通的int等类型基本相同。

程序功能:展示结构体初始化

C语言中结构体使用:struct Contact a = {100,"nick","123456789",};关键字struct不能漏。

而C++中就不存在这么麻烦的事情。

#include "stdio.h"

struct Contact
{
    int id;
    char name[16];
    char phone[16];
};

int main()
{
    //初始化单个结构体
    Contact a = {100,"nick","123456789",};
    //初始化结构体数组
    Contact b[4] =
    {
        {100,"nick","123456789",},
        {99,"nancy","123456789",},
        {98,"jack","123456789",},
        {97,"rose","123456789",},
    };
    return 0;
}

读写结构体内部成员

程序功能:访问,修改结构体内部数据。(strcpy函数来自于string.h)

#include "stdio.h"
#include "string.h"

struct Contact
{
    int id;
    char name[16];
    char phone[16];
};

int main()
{
    //初始化单个结构体
    Contact a = {100,"nick","123456789",};

    a.id = 201;
    strcpy(a.name, "John");
    strcpy(a.phone, "987654321");

    printf("%d %s %s", a.id, a.name, a.phone);

    return 0;
}
/*
//run out:
201 nick 987654321
*/

结构体赋值

程序功能:赋值操作。

#include "stdio.h"
#include "string.h"

struct Contact
{
    int id;
    char name[16];
    char phone[16];
};

int main()
{
    //初始化单个结构体
    Contact a = {100,"nick","123456789",};

    Contact b = a;

    return 0;
}

结构体指针

程序功能:结构体指针。

指针需要用符号->来访问成员变量,或者使用(*p).id这种方式。

还有如果申明了结构体数组,在访问时p[0].id这样使用,因为p[0]他不是指针了,已经是一个对象了,所以可以直接使用.(点号操作)。

#include "stdio.h"
#include "string.h"

struct Contact
{
    int id;
    char name[16];
    char phone[16];
};

int main()
{
    //初始化单个结构体
    Contact a = {100,"nick","123456789",};

    Contact *p = &a;
    p->id = 3;
    printf("%d %s %s", a.id, a.name, a.phone);

    return 0;
}

/*
//run out:
3 nick 123456789
*/

特殊形式(匿名结构体,但一般不这么用)

struct
{
    int id;
    char name[16];
    char phone[16];
}Info1;

该结构体没有类型名,只有变量名,可以这样定义,但一般不这么用。

另一种特殊形式(一般也不这么用)

struct Contact
{
    int id;
    char name[16];
    char phone[16];
}Info1, Info2;

为什么不这样用?其实很显然,结构体属于类型定义,而类型定义一般会放在头文件中。你在头文件中定义2个变量岂不是很扯。

对齐问题

为什么要对齐?

因为cpu的指令要求,只能在对齐的地址上存取,属于指令集的语法要求。不对齐就没法存取。(并不是所有的CPU都有此限制。)

通常对齐规则:

short:其内存地址必须是2字节对其(地址能被2整除)

int:4字节对齐

对结构体进行padding,使得结构体保持对齐。

程序功能:打印结构体obj的地址。

#include "stdio.h"

struct Object
{
    char a;
    char i;
    int b;
};

int main()
{
    //初始化单个结构体
    Object obj;
    printf("a:%p b:%p \n", &obj.a, &obj.b);

    return 0;
}

结构体作为成员

struct Score
{
    float chinese;
    float english;
    float math;
};
struct Student
{
    int id;
    char name[16];
    Score score;
};

使用指针,不直接包含:

struct Score
{
    float chinese;
    float english;
    float math;
};
struct Student
{
    int id;
    char name[16];
    Score *score;
};
Score _score = {80,79,25};
Student _stu;
_stu.ps = &_score;

为什么需要传地址?

如果你的变量是一个信息量特别多的结构体,如果你传值,会占用cpu和内存资源,而且这是没有必要的。干嘛不直接传地址给它,只要地址给它,只要解析地址就好,那占用资源就非常少,极其高效。

如果只读,那么就加const,变为const Contact*;想读写就不加const,就传递Contact*就行了。

<think>好的,用户想了解C++中的struct。首先,我需要确认用户的基础,可能他们已经有C语言的基础,所以得比较C和C++中的struct区别。 C++struct不仅包含数据成员,还能有函数成员,这点和C不同,要强调出来。访问控制默认是public的,而class默认是private,这点容易混淆,需要解释清楚。 然后,继承方面,struct默认是public继承,class是private,这也是关键点。用户可能想知道什么时候用struct,什么时候用class,应该举例说明常见的使用场景,比如简单的数据聚合。 还要提到C++11/17的新特性,比如成员初始化和非静态成员初始化,以及结构化绑定,这些对用户来说可能有帮助。需要注意语法正确性,比如示例代码中的struct定义、构造函数和成员函数。 最后,确保回答结构清晰,分点说明,并且用中文,避免使用Markdown格式。可能需要检查是否有遗漏的部分,比如与union的区别,但用户没有问,暂时不用涉及。保持回答简洁但全面,帮助用户逐步理解structC++中的用法和特点。</think>在C++中,struct结构体)是一种用户自定义的复合数据类型,是面向对象编程的基础构件之一。以下分步骤详细说明: 1. **基本定义** ```cpp struct Point { // 声明名为Point的结构体 int x; // 数据成员 int y; // 默认访问权限为public }; ``` 2. **与C语言的区别** - **成员函数支持**:C++结构体可以包含成员函数 - **访问控制**:支持public/protected/private访问修饰符 - **继承特性**:可以实现继承和多态 ```cpp struct Circle : Shape { // 继承自基类 void draw() override { /* 实现 */ } private: double radius; }; ``` 3. **与class的关键区别** $$ \begin{array}{|l|l|l|} \hline 特征 & struct & class \\ \hline 默认访问权限 & public & private \\ 默认继承方式 & public & private \\ 典型用途 & 数据聚合 & 封装行为 \\ \hline \end{array} $$ 4. **现代C++特性支持** - **成员初始化**(C++11): ```cpp struct Widget { int id = 0; // 非静态成员初始化 static const int version = 1; }; ``` - **结构化绑定**(C++17): ```cpp std::pair<int, string> getData(); auto [code, msg] = getData(); // 解构绑定 ``` 5. **使用建议** - 优先用struct处理纯数据集合(如DTO) - 当需要封装复杂行为时使用class - 保持结构体简单,避免过度设计 示例:包含构造函数的struct ```cpp struct Student { string name; int age; Student(string n, int a) : name(std::move(n)), age(a) {} void print() const { cout << name << " (" << age << ")\n"; } }; ``` 注意:在内存布局上,struct与class完全一致,区别仅在于默认的访问控制和继承方式。实际开发中应根据语义需求选择使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值