9 CPP结构体注意事项

news2024/9/25 11:15:41

注意:

1 结构名是标识符

2 结构体的成员可以是任意数据类型

3 定义结构体描述的代码可以放在程序的人和地方,一般放在main函数的上面或头文件中。

4 结构体成员可以用C++的类(如string),但是不提倡。

5 在C++中,结构体重可以有函数,但是不提倡。

6 在C++11中,定义结构体的时候一指定初始值。

struct perople{

string name;//不提倡

}

建议

struct perople{

char name[21];

}

C++11可以有初始值

struct perople{

char name[21]="测试";

}

 

初学阶段,第一种初始化方法用的比较多,但是实际开发中,第二种方法多。

3)使用结构体

在C++程序中,用成员运算符(.)来访问结构体的每个成员。结构体中的每个成员具备普通变量的全部特征。

语法:结构体变量名.结构体成员名;

4)内存占用的大小

用sizeof运算符可以得到结构体占用内存的大小。

注意:结构体占用内存的大小不一定等于全部成员占用内存之和。

内存对齐: #pragma pack(字节数) 默认是8 可以用1

 

#include <iostream>

//#pragma pack(1)//打开这行注释 结构体大小就是35个字节了
using namespace std;
struct people {
    char name[21];//21
    int age;//4
    double weight;//8
    char sex;//1
    bool isVIP;//1
};

void test() {
    struct people p = {0};
    cout << "结构体大小:" << sizeof(p) << endl;//默认的,不是全部成员占用的35个字节而是48个字节
//    struct people {
//        char name[21];//默认占3个8字节 24
//        int age;//默认占1个8字节  8
//        double weight;//默认占用1个8字节  8
//        char sex;//默认占用1个8字节 8
//        bool isVIP;//默认占用1个8字节,但是前面的sex没占满8字节,且字节和sex的和也不足8字节,所以和sex共同占用8字节即可
//    };

//但是如果结构体顺序如下
//    struct people {
//        char sex;
//        char name[21];
//        bool isVIP;
//        int age;
//        double weight;
//    };
    //默认情况下就是占用40个字节 sex name isVIP占用3个8字节也就是24字节
}

int main() {
    test();
    return 0;
}

5)清空结构体

创建的结构体变量如果没有初始化,成员中有垃圾值。

用memset函数可以把结构体中全部成员清零,(只适用于C++基本数据类型)bzero()函数也可以。

#include <iostream>

using namespace std;
struct people {
    char name[21];
    int age;
    double weight;
    char sex;
    bool isVIP;
};

void test() {
    struct people p;
    memset(&p, 0, sizeof(p));
    bzero(&p, sizeof(people));
    cout << p.age << endl;
}

int main() {
    test();
    return 0;
}

6)结构体的赋值

用memcpy()函数把结构体中全部元素赋值到另一个想同类型的结构体(只适用于C++基本数据类型)。

也可以直接用等号(只适用C++基本数据类型)

#include <iostream>

using namespace std;
struct people {
    char name[21];
    int age;
    double weight;
    char sex;
    bool isVIP;
};

void test() {
    struct people p;
    memset(&p, 0, sizeof(p));
    bzero(&p, sizeof(people));
    cout << p.age << endl;
    p.age = 11;
    struct people p2;
    memcpy(&p2, &p, sizeof(p));
    cout << p2.age << endl;
}

int main() {
    test();
    return 0;
}
0
11
#include <iostream>
#include <cstring>
//结构体数组
using namespace std;
struct people {
    char name[21];
    int age;
    double weight;
    char sex;
    bool isVIP;
};

void test() {
    people ps[3];
    memset(ps, 0, sizeof(ps));//清空整个数组
    cout << "数组表示法" << endl;
    //数组表示法
    strcpy(ps[0].name, "hello");
    ps[0].age = 22;
    ps[0].weight = 11.2;
    ps[0].sex = 'X';
    ps[0].isVIP = true;

    ps[1] = {"hulu", 3, 44.3, 'Y', true};//C++11标准的语法
    ps[2] = {"haha", 4, 21.3, 'X', false};//C++11标准的语法
    for (int i = 0; i < 3; i++) {
        cout << "姓名:" << ps[i].name << endl;
    }
    cout << "指针表示法:不常用" << endl;
    //指针表示法:不常用
    strcpy((ps + 0)->name, "ptr_huhu");
    *(ps + 1) = {"ptr_gaga", 13, 424.3, 'Y', true};//C++11标准的语法
    *(ps + 2) = {"ptr_haha", 41, 31.3, 'X', false};//C++11标准的语法
    for (int i = 0; i < 3; i++) {
        cout << "姓名:" << (*(ps + i)).name << endl;
    }
}

int main() {
    test();
    return 0;
}
数组表示法
姓名:hello
姓名:hulu
姓名:haha
指针表示法:不常用
姓名:ptr_huhu
姓名:ptr_gaga
姓名:ptr_haha

结构体中的指针

如果结构体重的指针指向的是动态分配的内存地址:

1 对结构体用sizeof运算可能没有意义。

2 对结构体用memset()函数可能会造成内存泄漏

3 C++的字符串string中有一个指向的是动态分配的内存地址指针。

#include <iostream>
#include <cstring>

using namespace std;
//结构体中的指针
struct People {
    int a;
    int *p;
};

void test() {
    People people;
    people.p = new int[100];
    cout << "sizeof(people)=" << sizeof(people) << endl;//16个字节 ,肯定是有问题

    //结构体清零
    cout << "调用前:people.a:" << people.a << ",people.p:" << people.p << endl;
    memset(&people, 0, sizeof(people));
    cout << "调用后:people.a:" << people.a << ",people.p:" << people.p << endl;

    //上面的清零是有问题的  输出结果如下,这个指针都给清零了,导致p之前所指向的内存就不能被操作了,内存泄漏
//    sizeof(people) = 16
//    调用前:people.a:0, people.p:0x7fb1e6405910
//    调用后:people.a:0, people.p:0x0

//应该这么做
    People people2;
    people2.a = 3;
    people2.p = new int[100];
    cout << endl;
    cout << "调用前:people2.a:" << people2.a << ",people2.p:" << people2.p << endl;
    people2.a = 0;//清零成员a
    memset(people2.p, 0, 100 * sizeof(people2.p));//清空p指向的内存中的内容
    cout << "调用后:people2.a:" << people2.a << ",people2.p:" << people2.p << endl;


    delete[] people.p;//释放动态分配的内存
}

struct stringTest {
    string name;
};

void test2() {

    stringTest st;
    st.name = "葫芦娃";
    cout << "name=" << st.name << endl;
    //我这里演示是没有问题的,但是视频里面是有问题的 视频里面是VS
    memset(&st, 0, sizeof(st));

    st.name = "舅爷爷";
    cout << "name=" << st.name << endl;
}

int main() {
    cout << "执行test()" << endl;
    test();
    cout << "执行test2()" << endl;
    test2();
    return 0;
}

执行test()
sizeof(people)=16
调用前:people.a:197835680,people.p:0x7fd12d405910
调用后:people.a:0,people.p:0x0

调用前:people2.a:3,people2.p:0x7fd12d405aa0
调用后:people2.a:0,people2.p:0x7fd12d405aa0
执行test2()
name=葫芦娃
name=舅爷爷

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97784.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java:AES加密和解密

java&#xff1a;AES加密和解密 1 前言 对称加密&#xff0c;即单秘钥加密&#xff0c;指加密和解密的过程中&#xff0c;使用相同的秘钥&#xff0c;相比于非对称加密&#xff0c;因仅有一把钥匙&#xff0c;故而速度更快&#xff0c;更适合解密大文件&#xff08;常见于如视…

ESP32的arduino IDE代码使用flash download tool进行烧录

ESP32的arduino IDE代码使用flash download tool进行烧录前言arduino代码烧录arduino下载了一些什么文件flash download tool工具烧录总结前言 最近遇到用户在使用 arduino IDE开发环境编写了ESP32的代码&#xff0c;希望提供编写好的程序给用户烧录&#xff0c;但是又不希望让…

Kotlin + SpringBoot + JPA 服务端开发

Kotlin SpringBoot JPA 服务端开发 本篇主要介绍一下 kotlin springboot的服务端开发环境搭建 1.概述 Kotlin 是一个基于JVM的编程语言, 是IDEA开发工具 jetbrains 公司开发的语言,也被google选为android开发的首选语言, 因为它是完全兼容Java的 所以也可以做后端开发 比如…

[Java] 如何理解和设置ThreadPoolExecutor三大核心属性?什么情况下工作线程数会突破核心线程数?任务拒绝策略都有哪些?

文章目录前言ThreadPoolExecutor类是什么&#xff1f;ThreadPoolExecutor的三大核心属性1. 核心线程数&#xff08;corePoolSize&#xff09;属性2. 任务队列&#xff08;workQueue&#xff09;属性3. 最大线程数&#xff08;maximumPoolSize&#xff09;属性总结&#xff1a;T…

【开发百宝箱之猿如意使用指南】「工欲成其事,必先利其器」一文教你如何通过“猿如意”便捷的使用数据库管理工具DBeaver

开发百宝箱之猿如意使用指南欢迎您使用“猿如意”百宝箱大家科普一下什么是猿如意&#xff1f;赶快趁热下载个【猿如意】吧每个程序猿值得拥有的学习开发工作必备“良药”没有猿如意的“我们”&#xff08;猿如意帮我们解决了哪些问题&#xff1f;&#xff09;【如何快速下载自…

非零基础自学Golang 第12章 接口与类型 12.2 接口的创建与实现 12.2.1 接口创建

非零基础自学Golang 文章目录非零基础自学Golang第12章 接口与类型12.2 接口的创建与实现12.2.1 接口创建第12章 接口与类型 12.2 接口的创建与实现 Go语言接口是方法的集合&#xff0c;使用接口是实现模块化的重要方式。 下面将重点介绍如何创建和实现一个Go语言接口。 12…

Pytest用例执行的先后顺序

[内部资源] 想拿年薪30W的软件测试人员&#xff0c;这份资料必须领取~ 温馨提示 「本篇约1600字&#xff0c;看完需3-5分钟&#xff0c;学习学半小时&#xff0c;加油&#xff01;」 先看普通函数运行顺序 import pytestdef test_one():print("我是清安")def tes…

React学习27(react-redux多组件共享数据)

项目结构 准备工作 1&#xff09;定义一个person组件&#xff0c;和count组件通过redux共享数据 2&#xff09;为person组件编写&#xff1a;reducer &#xff0c;action和contant常量 3&#xff09;重点&#xff1a;Person的reducer和Count的reducer要用combineReducers进行…

深度学习-优化器

优化器 文章目录优化器1. 引言1. SGD1.1 vanilla SGD1.2 SGD with Momentum1.3 SGD with Nesterov Acceleration2. AdaGrad3. RMSProp4. AdaDelta5. Adam优化器选择出处1. 引言 优化算法可以分成一阶优化和二阶优化算法&#xff0c;其中一阶优化就是指的梯度算法及其变种&#…

Linux——vi,vim的使用

三种模式 正常模式 以vi或vim打开一个档案就直接进入一般模式了(这是默认的模式)。在这个模式中&#xff0c;你可以使用 【上下左右】 按键来移动光标&#xff0c;你可以使用 【删除字符】或 【删除整行】来处理档案内容&#xff0c;也可以使用 【复制&#xff0c;粘贴】来处…

3D激光里程计其三:点云畸变补偿

3D激光里程计其三&#xff1a;点云畸变补偿1. 产生原因2. 补偿方法Reference: 深蓝学院-多传感器融合 1. 产生原因 一帧点云&#xff1a;通常指雷达内部旋转一周扫描得到的点的集合。 优点&#xff1a;有足够数量的点云才能进行匹配&#xff0c;且一周正好是周围环境的完整采…

认识Java中的异常处理

文章目录Java异常处理异常体系的介绍常见运行时异常常见编译时异常Java异常处理 异常体系的介绍 什么事异常处理? 异常是程序在“编译”或者“执行”的过程中可能出现的问题&#xff0c;比如: 数组索引越界、空指针异常、 日期格式化异常&#xff0c;等… 注意&#xff1a;语…

常用损失函数

常见损失函数 文章目录常见损失函数引言回归1. 均方差2.平均绝对误差(MAE)3. 均方根误差(RMSE)4. 交叉熵分类二分类多分类引言 无论在机器学习还是深度领域中,损失函数都是一个非常重要的知识点。损失函数&#xff08;Loss Function&#xff09;是用来估量模型的预测值 f(x) 与…

Eslint 8.23 Flat Config 新配置迁移升级指南

前言 直入正题&#xff0c;eslint 目前为止的配置文件格式&#xff08; 如 .eslintrc.js &#xff09; 存在很多无法避免的历史问题&#xff1a; 配置格式混乱&#xff0c;层层不明确的继承&#xff0c;不易理解。 插件配置时不支持实体运用&#xff08;不能传 function / ob…

学完框架后的反思—为什么要使用框架?

学习前端也有一定的时间了,最近在网上看到了一个问题让我反思了很久——为什么要使用前端框架? 我发现自己当初学习框架时并没有想那么多,只是看中了其在业界企业的应用,大部分公司开发页面基本上都是使用框架进行开发的,而最为被大厂广泛接受的就是 React 框架,所以我当…

二棕榈酰磷酯酰乙醇胺-聚乙二醇-叠氮 DPPE-PEG-N3简介,可用于药物传递、基因转染和生物分子修饰。

二棕榈酰磷酯酰乙醇胺-聚乙二醇-叠氮 DPPE-PEG-N3 中文名称&#xff1a;二棕榈酰磷酯酰乙醇胺-聚乙二醇-叠氮基 英文名称&#xff1a;DPPE-PEG-N3 英文别名&#xff1a; 1,2-dipalmitoyl-sn-glycero-3-phosphoethanolamine-PEG-Azide 分子量&#xff08;PEG&#xff09;&a…

Linux——任务调度

at定时任务 基本介绍 at命令是一次性定时计划任务&#xff0c;at地守护线程atd会以后台模式运行&#xff0c;检查作业队列来运行默认情况下&#xff0c;atd守护进程没60秒检查作业队列&#xff0c;有作业时&#xff0c;会检查作业运行时间&#xff0c;如果时间于当前时间匹配…

Dubbo 1 分布式系统中的相关概念 1.2 集群和 分布式

Dubbo 【黑马程序员Dubbo快速入门&#xff0c;Java分布式框架dubbo教程】 1 分布式系统中的相关概念 文章目录Dubbo1 分布式系统中的相关概念1.2 集群和 分布式1.2.1 集群和分布式1.2.2 集群和分布式 【互联网 中】1.2 集群和 分布式 1.2.1 集群和分布式 集群&#xff1a;很…

使用synchornized和ReentrantLock来解决并发错误

文章目录什么是并发错误&#xff1f;并发错误是如何产生的&#xff1f;演示并发错误如何解决并发错误使用synchornized解决并发错误使用ReentrantLock解决并发错误什么是并发错误&#xff1f; 多个线程共享操作同一个对象的时候&#xff0c;线程体当中连续的多行操作未必能够连…

下个文档还要马内?还好我会Python,教大家来一手强制复制粘贴

前因后果 公司有人阳了&#xff0c;今天在家上班&#xff0c;突然小姨子就问我有没有baidu文库会员&#xff0c;想下载点东西&#xff0c;我心想这还要会员&#xff1f;用Python不是分分钟的事情&#xff01; 然后我非常自信的告诉她不用会员随便下载&#xff0c;结果她顺势想…